Uh oh!
There was an error while loading. Please reload this page.
docs: Add anchor macros - #22
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 dependenciesecho"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.
Uh oh!
There was an error while loading. Please reload this page.
Summary by CodeRabbit