Skip to content

docs: Add anchor macros#22

Merged
tilo-14 merged 4 commits intomainfrom
add-anchor
Feb 2, 2026
Merged

docs: Add anchor macros#22
tilo-14 merged 4 commits intomainfrom
add-anchor

Conversation

@tilo-14
Copy link
Member

@tilo-14 tilo-14 commented Feb 2, 2026

Summary by CodeRabbit

  • Documentation
    • Expanded Light Token cookbook with comprehensive program examples for all operations (mint, transfer, burn, freeze, close, approve/revoke, wrap/unwrap).
    • Added Program tabs showing Anchor and native program flows alongside client examples; updated links to full source examples.
    • Added a new Program examples page and program prerequisites guide; improved navigation across client/program paths.
  • Chores
    • Added a script to aggregate program example snippets for documentation.

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

Walkthrough

Adds comprehensive program-level examples and program prerequisites to the Light Token docs, migrates example import paths from light_token_sdk::token to light_token::instruction, introduces many Anchor and native CPI example snippets, and adds a script to aggregate Rust snippets into MDX pages.

Changes

Cohort / File(s) Summary
Navigation & Landing
docs.json, light-token/examples/program.mdx
Added a new "Program" examples page entry and created the examples landing MDX page.
Cookbook pages (Program tabs added)
light-token/cookbook/*.mdx (approve-revoke.mdx, burn.mdx, close-token-account.mdx, create-ata.mdx, create-mint.mdx, create-token-account.mdx, freeze-thaw.mdx, mint-to.mdx, overview.mdx, transfer-checked.mdx, transfer-interface.mdx, wrap-unwrap.mdx)
Inserted Program tabs containing CPI/Anchor/native code examples, updated prerequisite imports, and replaced previous examples-light-token links with direct source/full-example links.
Anchor program examples
snippets/code-snippets/light-token/*/anchor-program/full-example.mdx (approve, burn, close-token-account, create-ata, create-mint, create-token-account, freeze, mint-to, mint-to-checked, thaw, transfer-checked, transfer-interface, revoke, etc.)
Added many Anchor-based program examples: public program modules, instruction entrypoints, Accounts structs, and tests demonstrating CPI usage.
Native program examples
snippets/code-snippets/light-token/*/native-program/full-example.mdx (approve, burn, close-token-account, create-ata, create-mint, create-token-account, freeze, mint-to, mint-to-checked, thaw, transfer-checked, transfer-interface, revoke, etc.)
Added native Rust program helpers with invoke / invoke_signed flows, signer seed derivation, validation, and tests for CPI interactions.
Anchor macro examples & renames
snippets/code-snippets/light-token/*/anchor-macro/full-example.mdx (create-ata, create-mint, create-token-account)
Added Anchor macro examples and renamed/refactored macro-generated types (e.g., CreateAta → CreateAssociatedTokenAccount, CreateTokenAccount → CreateTokenVault), updating params and account fields.
Import path & sample updates
snippets/code-samples/code-compare-snippets.jsx, snippets/code-snippets/*/rust-client/*, snippets/light-token-*.mdx, snippets/light-token-guides/*
Migrated imports from light_token_sdk::token::* to light_token::instruction::*, adjusted instruction construction patterns (struct-literal/CPI fields) and added fee_payer/cpi_context fields in many snippets.
Snippet aggregation script & tables
scripts/copy-program-snippets.sh, snippets/overview-tables/*, snippets/light-token-guides/light-token-program-prerequisites.mdx
Added a bash script to generate MDX from Rust snippet sources, corrected cookbook table typos, expanded examples table, and added a program prerequisites guide.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰
Hopping through docs with a jittery grin,
Program tabs sprout where examples begin.
CPI carrots, Anchor leaves in a row,
Native burrows help the knowledge grow.
A nibble of snippets — now off I go!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'docs: Add anchor macros' directly relates to the primary changes in the changeset, which extensively document Anchor macros integration throughout the Light Token cookbook and examples.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-anchor

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 |
+
 ### Macros
snippets/code-snippets/light-token/burn/native-program/full-example.mdx (1)

34-61: Consider using expect() instead of unwrap() for clearer documentation.

On line 47, unwrap() is used after validating that data.len() >= 9. While safe, using expect() 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 available
light-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 invoke tab—the invoke_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 in invoke examples.

Both Freeze and Thaw invoke examples (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 in invoke_signed examples.

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.ata vs env.associated_token_account naming.

This test uses env.ata (Line 70) while other test files (e.g., transfer-checked) use env.associated_token_account. This suggests either different test environment setups or an inconsistency in the setup_test_env utility. Both should work if the underlying TestEnv struct 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");

Comment on lines +96 to +109
```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])
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +162 to +201
```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])
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd "create-ata.mdx" --type f

Repository: Lightprotocol/docs-v2

Length of output: 100


🏁 Script executed:

wc -l light-token/cookbook/create-ata.mdx

Repository: Lightprotocol/docs-v2

Length of output: 104


🏁 Script executed:

sed -n '162,201p' light-token/cookbook/create-ata.mdx

Repository: Lightprotocol/docs-v2

Length of output: 884


🏁 Script executed:

fd "CreateAssociatedAccountCpi" --type f

Repository: Lightprotocol/docs-v2

Length of output: 47


🏁 Script executed:

rg "CreateAssociatedAccountCpi" --type rust

Repository: Lightprotocol/docs-v2

Length of output: 213


🏁 Script executed:

rg "CreateAssociatedAccountCpi" --type md

Repository: Lightprotocol/docs-v2

Length of output: 47


🏁 Script executed:

rg "invoke\(\)" light-token/cookbook/create-ata.mdx -A 2 -B 2

Repository: Lightprotocol/docs-v2

Length of output: 111


🏁 Script executed:

sed -n '140,220p' light-token/cookbook/create-ata.mdx

Repository: Lightprotocol/docs-v2

Length of output: 1991


🏁 Script executed:

sed -n '200,250p' light-token/cookbook/create-ata.mdx

Repository: Lightprotocol/docs-v2

Length of output: 1073


🏁 Script executed:

find . -name "*.rs" -type f | head -20

Repository: Lightprotocol/docs-v2

Length of output: 47


🏁 Script executed:

grep -r "invoke\(\)" light-token/cookbook/ -A 5 -B 5

Repository: 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).

Comment on lines +180 to +186
```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"
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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.

Comment on lines +125 to +136
```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])
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Undefined authority_seeds! macro and missing error propagation.

  1. authority_seeds!(bump) on line 128 is not a standard macro—it will cause compilation errors without a macro definition.
  2. 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.

Comment on lines +170 to +181
```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])
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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 ?).

Comment on lines +25 to +34
#[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>,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "full-example.mdx" -type f 2>/dev/null | head -20

Repository: Lightprotocol/docs-v2

Length of output: 1690


🏁 Script executed:

fd "full-example.mdx" --type f

Repository: 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 -50

Repository: Lightprotocol/docs-v2

Length of output: 1897


🏁 Script executed:

rg "LIGHT_TOKEN_PROGRAM_ID" --type rust | head -20

Repository: 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 -10

Repository: 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 -50

Repository: Lightprotocol/docs-v2

Length of output: 1537


🏁 Script executed:

cat snippets/code-snippets/light-token/mint-to/anchor-program/full-example.mdx | head -50

Repository: 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 -20

Repository: 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 -30

Repository: 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 2

Repository: 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.

Comment on lines +14 to +27
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(())
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for MintToCpi struct definition
rg -n "struct MintToCpi" --type rust -A 20

Repository: Lightprotocol/docs-v2

Length of output: 213


🏁 Script executed:

# Also search for any MintToCpi usage patterns
rg -n "MintToCpi" --type rust -B 3 -A 3

Repository: 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 f

Repository: 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().

Comment on lines +14 to +22
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(())
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and locate it
find . -name "full-example.mdx" -path "*revoke*" 2>/dev/null

Repository: 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 10

Repository: Lightprotocol/docs-v2

Length of output: 213


🏁 Script executed:

cat ./snippets/code-snippets/light-token/revoke/anchor-program/full-example.mdx

Repository: Lightprotocol/docs-v2

Length of output: 2751


🏁 Script executed:

# Search for RevokeCpi definition across all files
rg "RevokeCpi" -B 2 -A 10

Repository: Lightprotocol/docs-v2

Length of output: 7860


🏁 Script executed:

# Also search for RevokeAccounts to understand the full struct
rg "RevokeAccounts" -B 2 -A 10

Repository: 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.

Comment on lines +6 to +14
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"] }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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:


🌐 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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

@tilo-14 tilo-14 merged commit 1256e56 into main Feb 2, 2026
4 of 8 checks passed
@tilo-14 tilo-14 deleted the add-anchor branch February 2, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant