Conversation
WalkthroughAdds comprehensive program-level examples and program prerequisites to the Light Token docs, migrates example import paths from Changes
Sequence Diagram(s)sequenceDiagram
participant Test/Client as Client/Test
participant AnchorOrNative as Anchor/Native Program
participant LightToken as Light Token Program (CPI)
participant System as System Program / Runtime
Note over Client,AnchorOrNative: 1) Client/Test sends tx to Anchor/Native program
Client/Test->>AnchorOrNative: invoke instruction (data, accounts)
Note over AnchorOrNative: 2) Program builds CPI struct (e.g., MintToCpi / ApproveCpi)
AnchorOrNative->>LightToken: invoke or invoke_signed (CPI)
LightToken->>System: program runtime actions (accounts, lamports, compressible writes)
System-->>LightToken: execution result
LightToken-->>AnchorOrNative: CPI result
AnchorOrNative-->>Client/Test: transaction result / signature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 Fix all issues with AI agents
In `@light-token/cookbook/burn.mdx`:
- Around line 96-109: Define the missing signer_seeds and propagate the CPI
error: add a signer_seeds variable (e.g., let signer_seeds: &[&[&[u8]]] = /*
your PDA seed slices and bump */) and pass that to BurnCpi.invoke_signed, then
propagate the Result (use the ? operator or return the Result) instead of
ignoring it; reference the BurnCpi invocation (BurnCpi { ...
}.invoke_signed(...)) and ensure the signer_seeds shape matches the expected
invoke_signed parameter.
In `@light-token/cookbook/create-ata.mdx`:
- Around line 162-201: The CreateAssociatedAccountCpi examples call .invoke()
and .invoke_signed(...) without propagating errors; update both CPI invocation
lines (the .invoke() in the non-signer example and the
.invoke_signed(&[signer_seeds]) in the PDA signer example) to return their
Result by appending ? so errors are propagated (keep the preceding
.rent_free(...) chain intact and only add ? to the final invocation).
In `@light-token/cookbook/create-token-account.mdx`:
- Around line 180-186: Update the TOML dependency block to use the latest stable
versions: change light-sdk version from "0.18.0" to "0.19.0" (keep features
["anchor","v2","cpi-context"]), change light-sdk-macros from "0.18.0" to
"0.19.0", change light-compressible from "0.1.0" to "0.4.0", and change
anchor-lang from "0.31" to "0.32.1" so the snippet under the
create-token-account documentation reflects current releases.
In `@light-token/cookbook/freeze-thaw.mdx`:
- Around line 125-136: The snippet uses an undefined macro
authority_seeds!(bump) and fails to propagate errors from invoke_signed; replace
or define the signer seeds correctly (e.g., construct the PDA seeds array
expected by invoke_signed instead of authority_seeds! or add a local
macro/helper that returns the &[&[u8]] signer seeds) and update the FreezeCpi
invocation to call invoke_signed(...)? so the Result is propagated; make the
changes around the FreezeCpi construction and the invoke_signed call to use the
concrete signer_seeds value and append the `?` to the invoke_signed invocation
on FreezeCpi.
- Around line 170-181: The ThawCpi example uses an undefined authority_seeds!
macro and doesn't propagate errors from invoke_signed; replace the macro usage
by constructing signer_seeds explicitly from your authority seed bytes and the
bump (e.g., a &[&[u8]] slice built from the authority seed and bump) instead of
calling authority_seeds!, then call ThawCpi { token_account, mint,
freeze_authority }.invoke_signed(&[signer_seeds])? so the error is propagated
(ensure the surrounding function returns a Result to accept the ?).
In `@light-token/examples/program.mdx`:
- Line 9: Update the copy "Find all examples on Github:
[examples-light-token](https://github.com/Lightprotocol/examples-light-token)"
to use the correct brand capitalization by changing "Github" to "GitHub" (i.e.,
edit the text that begins "Find all examples on Github:" / the link label
"[examples-light-token]") so the line reads "Find all examples on GitHub:
[examples-light-token](https://github.com/Lightprotocol/examples-light-token)".
In `@scripts/copy-program-snippets.sh`:
- Around line 6-13: Replace the hard-coded absolute paths by making SNIPPETS_DIR
and ANCHOR_EXAMPLES_DIR configurable via environment variables with
repo-relative fallbacks: read SNIPPETS_DIR and ANCHOR_EXAMPLES_DIR from the
environment (e.g., ${SNIPPETS_DIR:-...} pattern) and default them to paths built
from the script’s repository root (use the script directory / project root as
computed in the script) so the values work on other machines and CI; update the
occurrences of SNIPPETS_DIR and ANCHOR_EXAMPLES_DIR (including the repeated
block later) to use these variables instead of the literal
/home/tilo/Workspace/... paths.
In `@snippets/code-snippets/light-token/burn/anchor-program/full-example.mdx`:
- Around line 29-33: The BurnAccounts struct currently exposes
light_token_program: AccountInfo without validating its address, allowing CPI
spoofing; update the BurnAccounts definition to add an address constraint on
light_token_program to ensure it equals the expected light-token program ID (use
the canonical constant/identifier for that program, e.g., LIGHT_TOKEN_PROGRAM_ID
or the light_token::ID constant) so Anchor will verify the AccountInfo's key
matches the trusted program before performing the CPI.
In `@snippets/code-snippets/light-token/freeze/anchor-program/full-example.mdx`:
- Around line 25-34: The light_token_program AccountInfo in FreezeAccounts is
unchecked and can be spoofed for CPI; update the account constraint to require
the actual program (e.g., change light_token_program: AccountInfo<'info> to
light_token_program: Program<'info, LightToken> or add a checked constraint that
its key equals crate::light_token::id()) so Anchor enforces the program ID
before performing CPI; ensure the FreezeAccounts struct and any uses of
light_token_program (e.g., in the freeze instruction handler) are updated to use
the typed Program<'info, LightToken> or the explicit key check.
In `@snippets/code-snippets/light-token/mint-to/anchor-program/full-example.mdx`:
- Around line 14-27: The MintTo CPI invocation is missing the declared program
account: update the MintToCpi construction in the mint_to function to pass
ctx.accounts.light_token_program.to_account_info() as the token_program field so
the declared light_token_program in MintToAccounts is actually used; apply the
same fix for MintToCheckedAccounts in the mint-to-checked example (mirror how
CloseAccountCpi supplies token_program) so the CPI includes token_program:
ctx.accounts.light_token_program.to_account_info().
In `@snippets/code-snippets/light-token/revoke/anchor-program/full-example.mdx`:
- Around line 14-22: The Revoke CPI invocation in function revoke is missing the
program account; update the call so RevokeCpi { token_account:
ctx.accounts.token_account.to_account_info(), owner:
ctx.accounts.owner.to_account_info(), system_program:
ctx.accounts.system_program.to_account_info(),
}.invoke(ctx.accounts.light_token_program.as_ref())?; reference RevokeCpi,
RevokeAccounts, light_token_program, and revoke to locate the change.
In `@snippets/light-token-guides/light-token-program-prerequisites.mdx`:
- Around line 6-14: Update the pinned dependency versions in the document:
change the anchor-lang entry from "0.31.1" to "0.32.1", update solana-sdk from
"2" to "3.0.0", and set tokio to "1.49.0" (while keeping the "1" constraint form
if preferred); leave light-client at "0.19.0" and verify whether light-token,
light-token-types, and light-program-test should remain as pre-release/dev
versions or be aligned to their latest crates.io releases before committing.
In `@snippets/overview-tables/Untitled`:
- Line 1: The file cookbook-guides-table.mdx currently contains only a stray
local absolute path; remove that line and either delete the file if unused or
replace its contents with the intended MDX snippet (ensuring valid MDX
frontmatter and component/markdown content). Locate the file by its name
cookbook-guides-table.mdx, remove the absolute path string, and commit the
corrected MDX content (or remove the file) so the docs build won't surface local
paths.
🧹 Nitpick comments (14)
snippets/overview-tables/light-token-program-examples-table.mdx (1)
1-15: Missing blank line between Examples table and Macros section.The Macros header on line 7 follows immediately after the table row on line 6 without a blank line separator. This may cause rendering issues in some Markdown parsers.
📝 Suggested fix
| [create-and-transfer](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/create-and-transfer) | Create account via macro and transfer via CPI | + ### Macrossnippets/code-snippets/light-token/burn/native-program/full-example.mdx (1)
34-61: Consider usingexpect()instead ofunwrap()for clearer documentation.On line 47,
unwrap()is used after validating thatdata.len() >= 9. While safe, usingexpect()would document the invariant more clearly for readers.📝 Suggested improvement
- let amount = u64::from_le_bytes(data[0..8].try_into().unwrap()); + let amount = u64::from_le_bytes(data[0..8].try_into().expect("length validated above"));snippets/code-snippets/light-token/create-mint/anchor-macro/full-example.mdx (1)
3-3: Consider documenting which APIs trigger the deprecation warning.The
#![allow(deprecated)]attribute suppresses deprecation warnings, but it's unclear which APIs are deprecated. Consider adding a comment explaining this, or if possible, migrating to non-deprecated alternatives.📝 Suggested improvement
-#![allow(deprecated)] +#![allow(deprecated)] // TODO: light_sdk macros use deprecated Anchor patterns - update when v2 macros are availablelight-token/cookbook/mint-to.mdx (2)
131-144: Missing error propagation with?operator.The
invoke()call on line 143 doesn't propagate errors. Other code examples in this PR (e.g., the full Anchor examples) use.invoke()?. This should be consistent:Proposed fix
MintToCpi { mint: mint.clone(), destination: destination.clone(), amount, authority: authority.clone(), system_program: system_program.clone(), fee_payer: None, max_top_up: None, } -.invoke() +.invoke()?; +Ok(())
149-164: Missing error propagation with?operator.Same issue as the
invoketab—theinvoke_signed()call on line 163 should propagate errors:Proposed fix
MintToCpi { mint: mint.clone(), destination: destination.clone(), amount, authority: authority.clone(), system_program: system_program.clone(), fee_payer: None, max_top_up: None, } -.invoke_signed(&[signer_seeds]) +.invoke_signed(&[signer_seeds])?; +Ok(())light-token/cookbook/freeze-thaw.mdx (1)
111-120: Missing error propagation ininvokeexamples.Both Freeze and Thaw
invokeexamples (lines 119, 164) are missing the?operator for consistency with the full code examples.Also applies to: 156-165
light-token/cookbook/burn.mdx (1)
78-91: Missing error propagation with?operator.The
invoke()call on line 90 should propagate errors for consistency with the full code examples:Proposed fix
BurnCpi { source: source.clone(), mint: mint.clone(), amount, authority: authority.clone(), system_program: system_program.clone(), fee_payer: None, max_top_up: None, } -.invoke() +.invoke()?; +Ok(())light-token/cookbook/create-mint.mdx (3)
270-286: Missing error propagation with?operator.The
invoke()call on line 285 should propagate errors:Proposed fix
CreateMintCpi::new( mint_seed.clone(), authority.clone(), payer.clone(), address_tree.clone(), // stores address output_queue.clone(), // stores account when inactive compressible_config.clone(), // rent settings mint.clone(), rent_sponsor.clone(), system_accounts, params, ) -.invoke() +.invoke()?; +Ok(())
292-310: Missing error propagation ininvoke_signedexamples.Both PDA signer examples (lines 309, 334) should include the
?operator for error propagation, consistent with other examples.Also applies to: 316-335
356-359: Empty space after Anchor tab.There's an empty line between
</Tab>closing tags (lines 356-359). While not breaking, it creates unnecessary whitespace in the source:Proposed fix
<AnchorProgramCode /> </Tab> - </Tabs>light-token/cookbook/transfer-checked.mdx (1)
81-81: Minor inconsistency in tab title naming.This tab is titled "invoke_signed (PDA signer)" while other cookbook pages use "invoke_signed (PDA owner)" (e.g., close-token-account.mdx, approve-revoke.mdx). Consider aligning the terminology for consistency.
📝 Suggested fix
- <Tab title="invoke_signed (PDA signer)"> + <Tab title="invoke_signed (PDA owner)">snippets/code-snippets/light-token/mint-to-checked/anchor-program/full-example.mdx (1)
57-86: Minor inconsistency:env.atavsenv.associated_token_accountnaming.This test uses
env.ata(Line 70) while other test files (e.g., transfer-checked) useenv.associated_token_account. This suggests either different test environment setups or an inconsistency in thesetup_test_envutility. Both should work if the underlyingTestEnvstruct exposes both field names or aliases.docs.json (1)
90-92: Minor: Extra blank line in JSON array.There's a trailing blank line (line 91) before the closing bracket which creates inconsistent formatting with the rest of the file.
🧹 Suggested fix
"light-token/cookbook/load-ata", "light-token/cookbook/close-token-account", "light-token/cookbook/burn" - ]snippets/code-samples/code-compare-snippets.jsx (1)
176-187: Minor: Trailing whitespace on lines 183-184.The lines have trailing spaces after the commas which could cause linter warnings.
🧹 Suggested fix
export const lightCreateMintRustCode = [ "use light_token::instruction::CreateMint;", "", "let ix = CreateMint::new(", " params,", " mint_seed.pubkey(),", " payer.pubkey(),", - " address_tree.tree,", - " output_queue,", + " address_tree.tree,", + " output_queue,", ")", ".instruction()?;", ].join("\n");
| ```rust | ||
| use light_token::instruction::BurnCpi; | ||
|
|
||
| BurnCpi { | ||
| source: source.clone(), | ||
| mint: mint.clone(), | ||
| amount, | ||
| authority: authority.clone(), | ||
| system_program: system_program.clone(), | ||
| fee_payer: None, | ||
| max_top_up: None, | ||
| } | ||
| .invoke_signed(&[signer_seeds]) | ||
| ``` |
There was a problem hiding this comment.
Undefined signer_seeds variable and missing error propagation.
The invoke_signed example references signer_seeds on line 108 but doesn't define it. Add the seed definition for completeness:
Proposed fix
use light_token::instruction::BurnCpi;
+let signer_seeds: &[&[u8]] = &[OWNER_SEED, &[bump]];
+
BurnCpi {
source: source.clone(),
mint: mint.clone(),
amount,
authority: authority.clone(),
system_program: system_program.clone(),
fee_payer: None,
max_top_up: None,
}
-.invoke_signed(&[signer_seeds])
+.invoke_signed(&[signer_seeds])?;
+Ok(())🤖 Prompt for AI Agents
In `@light-token/cookbook/burn.mdx` around lines 96 - 109, Define the missing
signer_seeds and propagate the CPI error: add a signer_seeds variable (e.g., let
signer_seeds: &[&[&[u8]]] = /* your PDA seed slices and bump */) and pass that
to BurnCpi.invoke_signed, then propagate the Result (use the ? operator or
return the Result) instead of ignoring it; reference the BurnCpi invocation
(BurnCpi { ... }.invoke_signed(...)) and ensure the signer_seeds shape matches
the expected invoke_signed parameter.
| ```rust | ||
| use light_token::instruction::CreateAssociatedAccountCpi; | ||
|
|
||
| CreateAssociatedAccountCpi { | ||
| payer: payer.clone(), | ||
| owner: owner.clone(), | ||
| mint: mint.clone(), | ||
| ata: associated_token_account.clone(), | ||
| bump, | ||
| } | ||
| .rent_free( | ||
| compressible_config.clone(), | ||
| rent_sponsor.clone(), | ||
| system_program.clone(), | ||
| ) | ||
| .invoke() | ||
| ``` | ||
|
|
||
| </Tab> | ||
| <Tab title="invoke_signed (PDA signer)"> | ||
|
|
||
| ```rust | ||
| use light_token::instruction::CreateAssociatedAccountCpi; | ||
|
|
||
| let signer_seeds: &[&[u8]] = &[ATA_SEED, &[authority_bump]]; | ||
|
|
||
| CreateAssociatedAccountCpi { | ||
| payer: payer.clone(), | ||
| owner: owner.clone(), | ||
| mint: mint.clone(), | ||
| ata: associated_token_account.clone(), | ||
| bump, | ||
| } | ||
| .rent_free( | ||
| compressible_config.clone(), | ||
| rent_sponsor.clone(), | ||
| system_program.clone(), | ||
| ) | ||
| .invoke_signed(&[signer_seeds]) | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "create-ata.mdx" --type fRepository: Lightprotocol/docs-v2
Length of output: 100
🏁 Script executed:
wc -l light-token/cookbook/create-ata.mdxRepository: Lightprotocol/docs-v2
Length of output: 104
🏁 Script executed:
sed -n '162,201p' light-token/cookbook/create-ata.mdxRepository: Lightprotocol/docs-v2
Length of output: 884
🏁 Script executed:
fd "CreateAssociatedAccountCpi" --type fRepository: Lightprotocol/docs-v2
Length of output: 47
🏁 Script executed:
rg "CreateAssociatedAccountCpi" --type rustRepository: Lightprotocol/docs-v2
Length of output: 213
🏁 Script executed:
rg "CreateAssociatedAccountCpi" --type mdRepository: Lightprotocol/docs-v2
Length of output: 47
🏁 Script executed:
rg "invoke\(\)" light-token/cookbook/create-ata.mdx -A 2 -B 2Repository: Lightprotocol/docs-v2
Length of output: 111
🏁 Script executed:
sed -n '140,220p' light-token/cookbook/create-ata.mdxRepository: Lightprotocol/docs-v2
Length of output: 1991
🏁 Script executed:
sed -n '200,250p' light-token/cookbook/create-ata.mdxRepository: Lightprotocol/docs-v2
Length of output: 1073
🏁 Script executed:
find . -name "*.rs" -type f | head -20Repository: Lightprotocol/docs-v2
Length of output: 47
🏁 Script executed:
grep -r "invoke\(\)" light-token/cookbook/ -A 5 -B 5Repository: Lightprotocol/docs-v2
Length of output: 29873
Add error handling to the .invoke*() calls in the CPI snippets.
These snippets are missing ? to properly propagate errors. Other similar CPI examples in the cookbook (approve-revoke, close-token-account, transfer-checked) include error handling—these should match that pattern.
Suggested fix
- .invoke()
+ .invoke()?;- .invoke_signed(&[signer_seeds])
+ .invoke_signed(&[signer_seeds])?;🤖 Prompt for AI Agents
In `@light-token/cookbook/create-ata.mdx` around lines 162 - 201, The
CreateAssociatedAccountCpi examples call .invoke() and .invoke_signed(...)
without propagating errors; update both CPI invocation lines (the .invoke() in
the non-signer example and the .invoke_signed(&[signer_seeds]) in the PDA signer
example) to return their Result by appending ? so errors are propagated (keep
the preceding .rent_free(...) chain intact and only add ? to the final
invocation).
| ```toml | ||
| [dependencies] | ||
| light-sdk = { version = "0.18.0", features = ["anchor", "v2", "cpi-context"] } | ||
| light-sdk-macros = "0.18.0" | ||
| light-compressible = "0.1.0" | ||
| anchor-lang = "0.31" | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check crates.io for latest versions of the specified dependencies
echo "Checking light-sdk..."
curl -s "https://crates.io/api/v1/crates/light-sdk" | jq -r '.crate.max_stable_version // .crate.max_version'
echo "Checking light-sdk-macros..."
curl -s "https://crates.io/api/v1/crates/light-sdk-macros" | jq -r '.crate.max_stable_version // .crate.max_version'
echo "Checking light-compressible..."
curl -s "https://crates.io/api/v1/crates/light-compressible" | jq -r '.crate.max_stable_version // .crate.max_version'
echo "Checking anchor-lang..."
curl -s "https://crates.io/api/v1/crates/anchor-lang" | jq -r '.crate.max_stable_version // .crate.max_version'Repository: Lightprotocol/docs-v2
Length of output: 197
Update dependency versions to latest stable releases.
The documentation contains outdated versions. Current latest stable versions are:
- light-sdk: 0.19.0 (documented: 0.18.0)
- light-sdk-macros: 0.19.0 (documented: 0.18.0)
- light-compressible: 0.4.0 (documented: 0.1.0)
- anchor-lang: 0.32.1 (documented: 0.31)
Update the TOML snippet to reflect these versions to ensure users follow current, supported releases.
🤖 Prompt for AI Agents
In `@light-token/cookbook/create-token-account.mdx` around lines 180 - 186, Update
the TOML dependency block to use the latest stable versions: change light-sdk
version from "0.18.0" to "0.19.0" (keep features ["anchor","v2","cpi-context"]),
change light-sdk-macros from "0.18.0" to "0.19.0", change light-compressible
from "0.1.0" to "0.4.0", and change anchor-lang from "0.31" to "0.32.1" so the
snippet under the create-token-account documentation reflects current releases.
| ```rust | ||
| use light_token::instruction::FreezeCpi; | ||
|
|
||
| let signer_seeds = authority_seeds!(bump); | ||
|
|
||
| FreezeCpi { | ||
| token_account: token_account.clone(), | ||
| mint: mint.clone(), | ||
| freeze_authority: freeze_authority.clone(), | ||
| } | ||
| .invoke_signed(&[signer_seeds]) | ||
| ``` |
There was a problem hiding this comment.
Undefined authority_seeds! macro and missing error propagation.
authority_seeds!(bump)on line 128 is not a standard macro—it will cause compilation errors without a macro definition.- The
invoke_signed()call on line 135 is missing the?operator for error propagation.
Proposed fix
use light_token::instruction::FreezeCpi;
-let signer_seeds = authority_seeds!(bump);
+let signer_seeds: &[&[u8]] = &[FREEZE_AUTHORITY_SEED, &[bump]];
FreezeCpi {
token_account: token_account.clone(),
mint: mint.clone(),
freeze_authority: freeze_authority.clone(),
}
-.invoke_signed(&[signer_seeds])
+.invoke_signed(&[signer_seeds])?;
+Ok(())🤖 Prompt for AI Agents
In `@light-token/cookbook/freeze-thaw.mdx` around lines 125 - 136, The snippet
uses an undefined macro authority_seeds!(bump) and fails to propagate errors
from invoke_signed; replace or define the signer seeds correctly (e.g.,
construct the PDA seeds array expected by invoke_signed instead of
authority_seeds! or add a local macro/helper that returns the &[&[u8]] signer
seeds) and update the FreezeCpi invocation to call invoke_signed(...)? so the
Result is propagated; make the changes around the FreezeCpi construction and the
invoke_signed call to use the concrete signer_seeds value and append the `?` to
the invoke_signed invocation on FreezeCpi.
| ```rust | ||
| use light_token::instruction::ThawCpi; | ||
|
|
||
| let signer_seeds = authority_seeds!(bump); | ||
|
|
||
| ThawCpi { | ||
| token_account: token_account.clone(), | ||
| mint: mint.clone(), | ||
| freeze_authority: freeze_authority.clone(), | ||
| } | ||
| .invoke_signed(&[signer_seeds]) | ||
| ``` |
There was a problem hiding this comment.
Same issues: undefined macro and missing error propagation.
The Thaw invoke_signed example has the same issues as the Freeze example—undefined authority_seeds! macro and missing ? operator.
Proposed fix
use light_token::instruction::ThawCpi;
-let signer_seeds = authority_seeds!(bump);
+let signer_seeds: &[&[u8]] = &[FREEZE_AUTHORITY_SEED, &[bump]];
ThawCpi {
token_account: token_account.clone(),
mint: mint.clone(),
freeze_authority: freeze_authority.clone(),
}
-.invoke_signed(&[signer_seeds])
+.invoke_signed(&[signer_seeds])?;
+Ok(())🤖 Prompt for AI Agents
In `@light-token/cookbook/freeze-thaw.mdx` around lines 170 - 181, The ThawCpi
example uses an undefined authority_seeds! macro and doesn't propagate errors
from invoke_signed; replace the macro usage by constructing signer_seeds
explicitly from your authority seed bytes and the bump (e.g., a &[&[u8]] slice
built from the authority seed and bump) instead of calling authority_seeds!,
then call ThawCpi { token_account, mint, freeze_authority
}.invoke_signed(&[signer_seeds])? so the error is propagated (ensure the
surrounding function returns a Result to accept the ?).
| #[derive(Accounts)] | ||
| pub struct FreezeAccounts<'info> { | ||
| /// CHECK: Light token program for CPI | ||
| pub light_token_program: AccountInfo<'info>, | ||
| /// CHECK: Validated by light-token CPI | ||
| #[account(mut)] | ||
| pub token_account: AccountInfo<'info>, | ||
| /// CHECK: Validated by light-token CPI | ||
| pub mint: AccountInfo<'info>, | ||
| pub freeze_authority: Signer<'info>, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "full-example.mdx" -type f 2>/dev/null | head -20Repository: Lightprotocol/docs-v2
Length of output: 1690
🏁 Script executed:
fd "full-example.mdx" --type fRepository: Lightprotocol/docs-v2
Length of output: 2357
🏁 Script executed:
cat -n snippets/code-snippets/light-token/freeze/anchor-program/full-example.mdx 2>/dev/null | head -50Repository: Lightprotocol/docs-v2
Length of output: 1897
🏁 Script executed:
rg "LIGHT_TOKEN_PROGRAM_ID" --type rust | head -20Repository: Lightprotocol/docs-v2
Length of output: 213
🏁 Script executed:
# Check other freeze examples and similar programs to see if they use address constraints
fd "full-example.mdx" --type f -x grep -l "light_token_program" {} \; | head -10Repository: Lightprotocol/docs-v2
Length of output: 858
🏁 Script executed:
# Check a few other examples to see the pattern used
cat snippets/code-snippets/light-token/thaw/anchor-program/full-example.mdx | head -50Repository: Lightprotocol/docs-v2
Length of output: 1537
🏁 Script executed:
cat snippets/code-snippets/light-token/mint-to/anchor-program/full-example.mdx | head -50Repository: Lightprotocol/docs-v2
Length of output: 1580
🏁 Script executed:
# Search for LIGHT_TOKEN_PROGRAM_ID in all mdx files
grep -r "LIGHT_TOKEN_PROGRAM_ID" snippets/code-snippets/light-token/ | head -20Repository: Lightprotocol/docs-v2
Length of output: 2890
🏁 Script executed:
# Look for address constraint patterns in other examples
grep -r "address =" snippets/code-snippets/light-token/ -A 1 -B 1 | head -30Repository: Lightprotocol/docs-v2
Length of output: 2889
🏁 Script executed:
# Check the test files to see how they handle the light_token_program
grep -r "light_token_program" snippets/code-snippets/light-token/freeze/ -A 2 -B 2Repository: Lightprotocol/docs-v2
Length of output: 1213
Constrain light_token_program to prevent CPI spoofing.
Unchecked program accounts can be swapped with a malicious program; the example should model the safe constraint pattern already used elsewhere in the documentation.
🔒 Suggested fix (address constraint)
use anchor_lang::prelude::*;
-use light_token::instruction::FreezeCpi;
+use light_token::instruction::{FreezeCpi, LIGHT_TOKEN_PROGRAM_ID};
#[derive(Accounts)]
pub struct FreezeAccounts<'info> {
/// CHECK: Light token program for CPI
- pub light_token_program: AccountInfo<'info>,
+ #[account(address = LIGHT_TOKEN_PROGRAM_ID)]
+ pub light_token_program: AccountInfo<'info>,🤖 Prompt for AI Agents
In `@snippets/code-snippets/light-token/freeze/anchor-program/full-example.mdx`
around lines 25 - 34, The light_token_program AccountInfo in FreezeAccounts is
unchecked and can be spoofed for CPI; update the account constraint to require
the actual program (e.g., change light_token_program: AccountInfo<'info> to
light_token_program: Program<'info, LightToken> or add a checked constraint that
its key equals crate::light_token::id()) so Anchor enforces the program ID
before performing CPI; ensure the FreezeAccounts struct and any uses of
light_token_program (e.g., in the freeze instruction handler) are updated to use
the typed Program<'info, LightToken> or the explicit key check.
| pub fn mint_to(ctx: Context<MintToAccounts>, amount: u64) -> Result<()> { | ||
| MintToCpi { | ||
| mint: ctx.accounts.mint.to_account_info(), | ||
| destination: ctx.accounts.destination.to_account_info(), | ||
| amount, | ||
| authority: ctx.accounts.authority.to_account_info(), | ||
| system_program: ctx.accounts.system_program.to_account_info(), | ||
| max_top_up: None, | ||
| fee_payer: None, | ||
| } | ||
| .invoke()?; | ||
| Ok(()) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for MintToCpi struct definition
rg -n "struct MintToCpi" --type rust -A 20Repository: Lightprotocol/docs-v2
Length of output: 213
🏁 Script executed:
# Also search for any MintToCpi usage patterns
rg -n "MintToCpi" --type rust -B 3 -A 3Repository: Lightprotocol/docs-v2
Length of output: 213
🏁 Script executed:
# Search for the full-example.mdx file to see the complete context
fd "full-example.mdx" --type fRepository: Lightprotocol/docs-v2
Length of output: 2357
🏁 Script executed:
cat -n "snippets/code-snippets/light-token/mint-to/anchor-program/full-example.mdx"Repository: Lightprotocol/docs-v2
Length of output: 3265
🏁 Script executed:
cat -n "snippets/code-snippets/light-token/close-token-account/anchor-program/full-example.mdx"Repository: Lightprotocol/docs-v2
Length of output: 3143
🏁 Script executed:
# Search for MintToCpi usage in all example files
grep -r "MintToCpi" snippets/code-snippets/ --include="*.mdx"Repository: Lightprotocol/docs-v2
Length of output: 573
🏁 Script executed:
# Check native program version of mint-to for comparison
cat -n "snippets/code-snippets/light-token/mint-to/native-program/full-example.mdx"Repository: Lightprotocol/docs-v2
Length of output: 6059
🏁 Script executed:
cat -n "snippets/code-snippets/light-token/mint-to-checked/anchor-program/full-example.mdx"Repository: Lightprotocol/docs-v2
Length of output: 3450
light_token_program account declared but not used in CPI construction.
The MintToAccounts struct declares light_token_program (line 32), but MintToCpi (lines 15-23) doesn't reference it. Compare with close-token-account, which correctly passes light_token_program as the token_program field to CloseAccountCpi (line 16 in that example). Update MintToCpi to include the program account:
MintToCpi {
token_program: ctx.accounts.light_token_program.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
destination: ctx.accounts.destination.to_account_info(),
amount,
authority: ctx.accounts.authority.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
max_top_up: None,
fee_payer: None,
}Also applies to: MintToCheckedAccounts in mint-to-checked/anchor-program/full-example.mdx (same pattern).
🤖 Prompt for AI Agents
In `@snippets/code-snippets/light-token/mint-to/anchor-program/full-example.mdx`
around lines 14 - 27, The MintTo CPI invocation is missing the declared program
account: update the MintToCpi construction in the mint_to function to pass
ctx.accounts.light_token_program.to_account_info() as the token_program field so
the declared light_token_program in MintToAccounts is actually used; apply the
same fix for MintToCheckedAccounts in the mint-to-checked example (mirror how
CloseAccountCpi supplies token_program) so the CPI includes token_program:
ctx.accounts.light_token_program.to_account_info().
| pub fn revoke(ctx: Context<RevokeAccounts>) -> Result<()> { | ||
| RevokeCpi { | ||
| token_account: ctx.accounts.token_account.to_account_info(), | ||
| owner: ctx.accounts.owner.to_account_info(), | ||
| system_program: ctx.accounts.system_program.to_account_info(), | ||
| } | ||
| .invoke()?; | ||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and locate it
find . -name "full-example.mdx" -path "*revoke*" 2>/dev/nullRepository: Lightprotocol/docs-v2
Length of output: 216
🏁 Script executed:
# Search for RevokeCpi struct definition
ast-grep --pattern 'pub struct RevokeCpi {
$$$
}'Repository: Lightprotocol/docs-v2
Length of output: 47
🏁 Script executed:
# Also search for RevokeCpi in general to find its definition
rg "RevokeCpi" --type rust -B 2 -A 10Repository: Lightprotocol/docs-v2
Length of output: 213
🏁 Script executed:
cat ./snippets/code-snippets/light-token/revoke/anchor-program/full-example.mdxRepository: Lightprotocol/docs-v2
Length of output: 2751
🏁 Script executed:
# Search for RevokeCpi definition across all files
rg "RevokeCpi" -B 2 -A 10Repository: Lightprotocol/docs-v2
Length of output: 7860
🏁 Script executed:
# Also search for RevokeAccounts to understand the full struct
rg "RevokeAccounts" -B 2 -A 10Repository: Lightprotocol/docs-v2
Length of output: 3986
Pass light_token_program to the RevokeCpi invocation.
The light_token_program account is declared in RevokeAccounts (line 28) but not included in the RevokeCpi struct construction (lines 15-20). For the CPI to execute properly, the program account must be passed to the invoke call. Update the code to:
RevokeCpi {
token_account: ctx.accounts.token_account.to_account_info(),
owner: ctx.accounts.owner.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
}
.invoke(ctx.accounts.light_token_program.as_ref())?;The test correctly provides LIGHT_TOKEN_PROGRAM_ID when calling the instruction, confirming this account is required.
🤖 Prompt for AI Agents
In `@snippets/code-snippets/light-token/revoke/anchor-program/full-example.mdx`
around lines 14 - 22, The Revoke CPI invocation in function revoke is missing
the program account; update the call so RevokeCpi { token_account:
ctx.accounts.token_account.to_account_info(), owner:
ctx.accounts.owner.to_account_info(), system_program:
ctx.accounts.system_program.to_account_info(),
}.invoke(ctx.accounts.light_token_program.as_ref())?; reference RevokeCpi,
RevokeAccounts, light_token_program, and revoke to locate the change.
| light-token = "0.4.0" | ||
| light-token-types = "0.4.0" | ||
| anchor-lang = "0.31.1" | ||
|
|
||
| [dev-dependencies] | ||
| light-program-test = { version = "0.19.0", features = ["v2"] } | ||
| light-client = { version = "0.19.0", features = ["v2"] } | ||
| solana-sdk = "2" | ||
| tokio = { version = "1", features = ["full"] } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
latest version anchor-lang crate crates.io
💡 Result:
The latest published version of the anchor-lang crate on crates.io is 0.32.1. [1], [2]
🌐 Web query:
latest version light-token crate Solana
💡 Result:
The latest published version of the light-token Rust crate (Light Protocol / Solana compressed tokens SDK) is 0.3.0. [1]
Cargo.toml:
light-token = "0.3.0"Sources: [1]
🌐 Web query:
latest version light-program-test light-client Solana
💡 Result:
light-program-test(Rust crate): v0.18.0 (docs.rs)light-client(Rust crate, Light Protocol / Solana ZK Compression): v0.19.0 (docs.rs)
Citations:
- 1: https://docs.rs/crate/light-program-test/0.18.0/source/?utm_source=openai
- 2: https://docs.rs/crate/light-client/latest?utm_source=openai
🌐 Web query:
latest version solana-sdk crate
💡 Result:
The latest published version of the Rust solana-sdk crate is 3.0.0. [1]
Cargo: solana-sdk = "3.0.0" [1]
🌐 Web query:
latest version tokio crate
💡 Result:
The latest published version of the Rust tokio crate is 1.49.0. [1]
Changelog date for 1.49.0: January 3, 2026. [2]
Sources: [1] [2]
Update pinned dependency versions.
The documentation pins versions for several packages that have newer releases available: anchor-lang should be updated from 0.31.1 to 0.32.1, and solana-sdk from version 2 to 3.0.0. Additionally, tokio can be updated to 1.49.0 (within the "1" constraint). light-client is already current at 0.19.0, though light-token and light-program-test appear to be pre-release or development versions ahead of the latest crates.io releases.
🤖 Prompt for AI Agents
In `@snippets/light-token-guides/light-token-program-prerequisites.mdx` around
lines 6 - 14, Update the pinned dependency versions in the document: change the
anchor-lang entry from "0.31.1" to "0.32.1", update solana-sdk from "2" to
"3.0.0", and set tokio to "1.49.0" (while keeping the "1" constraint form if
preferred); leave light-client at "0.19.0" and verify whether light-token,
light-token-types, and light-program-test should remain as pre-release/dev
versions or be aligned to their latest crates.io releases before committing.
| @@ -0,0 +1 @@ | |||
| /home/tilo/Workspace/docs/snippets/overview-tables/cookbook-guides-table.mdx No newline at end of file | |||
There was a problem hiding this comment.
Remove the stray local path content.
This file only contains a local absolute path, which will surface in the docs if rendered. Please delete this file or replace it with the intended MDX snippet content.
🤖 Prompt for AI Agents
In `@snippets/overview-tables/Untitled` at line 1, The file
cookbook-guides-table.mdx currently contains only a stray local absolute path;
remove that line and either delete the file if unused or replace its contents
with the intended MDX snippet (ensuring valid MDX frontmatter and
component/markdown content). Locate the file by its name
cookbook-guides-table.mdx, remove the absolute path string, and commit the
corrected MDX content (or remove the file) so the docs build won't surface local
paths.
Summary by CodeRabbit