Skip to content

chore: light-ctoken-sdk small refactors and inline docs #2102

Merged
SwenSchaeferjohann merged 17 commits intomainfrom
jorrit/chore-prepare-ctoken-sdk-release
Dec 7, 2025
Merged

chore: light-ctoken-sdk small refactors and inline docs #2102
SwenSchaeferjohann merged 17 commits intomainfrom
jorrit/chore-prepare-ctoken-sdk-release

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Dec 6, 2025

Summary by CodeRabbit

  • Refactor

    • Public APIs renamed to a CPI-centric surface; many identifiers changed for consistency (including token-pool → spl_interface) and the main error enum renamed to CTokenSdkError. Program ID constant consolidated to a new cToken symbol.
  • New Features

    • Added CPI convenience helpers, CPI-focused constructors, new public constants, and helpers to compute config/rent-sponsor PDAs.
  • Documentation

    • Expanded crate docs, examples, and fixed a typographical error.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2025

Walkthrough

This PR renames many CPI-facing types from *Infos*Cpi, converts numerous Pubkey fields to AccountInfo<'info>, adds CPI helper methods (instruction/invoke/invoke_signed), introduces CompressibleParamsCpi with CPI builders, renames compressed-mint helpers to derive_cmint_compressed_address / find_cmint_address, adds a constants module (incl. CTOKEN_PROGRAM_ID), and renames the primary error enum TokenSdkErrorCTokenSdkError, updating public APIs, exports, and tests accordingly.

Changes

Cohort / File(s) Change Summary
Compressible params & decompress runtime
sdk-libs/ctoken-sdk/src/ctoken/compressible.rs, sdk-libs/ctoken-sdk/src/compressible/decompress_runtime.rs, sdk-libs/ctoken-sdk/src/compressible/mod.rs
Introduced CompressibleParamsCpi<'info> (replaces CompressibleParamsInfos), CPI constructor and builder, adjusted CPI usages; made decompress_runtime private and broadened re-export pub use decompress_runtime::*.
Create / Close cToken account CPI wrappers
sdk-libs/ctoken-sdk/src/ctoken/create.rs, sdk-libs/ctoken-sdk/src/ctoken/close.rs
Replaced *Infos CPI wrappers with *Cpi variants (CreateCTokenAccountCpi, CloseCTokenAccountCpi), switched compressible to CompressibleParamsCpi, updated From impls and CPI instruction/invoke flow.
Create ATA / cMint CPI and helpers
sdk-libs/ctoken-sdk/src/ctoken/create_ata.rs, sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs, sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/*
Renamed CPI structs (CreateAssociatedTokenAccountCpi, CreateCMintCpi, write CPI variants), renamed mint_signermint_seed/mint_seed_pubkey, updated constructors/TryFrom impls and CPI account ordering; renamed helpers derive_compressed_mint_addressderive_cmint_compressed_address, find_spl_mint_addressfind_cmint_address and propagated to exports, tests, docs.
Mint-to CPI wrappers
sdk-libs/ctoken-sdk/src/ctoken/mint_to.rs
Renamed MintToCTokenInfosMintToCTokenCpi (and write wrapper), added CPI instruction/invoke/invoke_signed helpers, updated TryFrom/From mappings and error prefixes; switched program_id references to CTOKEN_PROGRAM_ID.
Transfer CPI refactor (CToken ↔ SPL)
sdk-libs/ctoken-sdk/src/ctoken/transfer_ctoken.rs, .../transfer_ctoken_spl.rs, .../transfer_spl_ctoken.rs, .../transfer_interface.rs
Replaced many *Infos with *Cpi types, converted many Pubkey fields to AccountInfo<'info>, added CPI helpers (instruction, invoke, invoke_signed), updated From/TryFrom conversions and account ordering; transfer_interface now uses CPI variants and CTokenSdkError.
Error renaming & propagation
sdk-libs/ctoken-sdk/src/error.rs, many compressed_token/* & utils.rs
Renamed TokenSdkErrorCTokenSdkError, updated Result<T> alias and replaced error returns/usages across many modules; added variants (MissingSplInterfacePda*, InvalidCpiContext, NoInputAccounts).
Compressed-mint helper renames & re-exports
sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/*, .../mod.rs, sdk-libs/macros/src/*, tests/*, token-client/src/*
Renamed functions and re-exports (derive_compressed_mint_addressderive_cmint_compressed_address, find_spl_mint_addressfind_cmint_address); updated call sites in token-client, tests, macros, docs.
Constants & crate exports
sdk-libs/ctoken-sdk/src/constants.rs, sdk-libs/ctoken-sdk/src/lib.rs, sdk-libs/ctoken-sdk/src/ctoken/mod.rs
Added constants module with new Pubkey constants (incl. CTOKEN_PROGRAM_ID), adjusted crate re-exports (added compressed proof types, removed runtime/utils exports), updated ctoken module exports to CPI-oriented names and added helper PDA functions.
Meta/config renames (token_pool → spl_interface)
sdk-libs/ctoken-sdk/src/compressed_token/v1/*, v2/*
Replaced token_pool_pda with spl_interface_pda across meta/config structs and account_metas builders; updated constructors and account meta assembly.
CPI account constructors & parsing
many sdk-libs/ctoken-sdk/src/compressed_token/v2/* and transfer2/*
Updated various CPI parsing/try_from functions to return Result<..., CTokenSdkError>, switched program id usage to CTOKEN_PROGRAM_ID, and adjusted CPI-write helper signatures.
Tests, macros, token-client, misc
forester/tests/*, sdk-libs/token-client/src/*, sdk-libs/macros/src/*, sdk-libs/sdk/src/lib.rs, sdk-libs/ctoken-sdk/tests/*
Updated tests and call sites to use new names/constants, fixed doc typo, adjusted macro import paths, and updated pack import references.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Focus review on:

  • CPI invoke/invoke_signed account ordering and readonly/writable flags for all new *Cpi types.
  • From/TryFrom conversions extracting Pubkey from AccountInfo (correct keys/bump/order).
  • Program ID substitutions (CTOKEN_PROGRAM_ID) and new constants to ensure correct imports.
  • Error enum rename consequences: ProgramError/u32 conversion mappings and all call sites updated.
  • Tests and examples updated to reflect renamed helpers and CPI constructors.

Possibly related PRs

Suggested labels

ai-review

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

From Infos to Cpi the wrappers flew,
AccountInfo fields replaced Pubkeys true,
Compressible params gained a CPI face,
Errors renamed and helpers found their place,
Invokes aligned — a tidier SDK view. 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective: refactoring the ctoken SDK and adding inline documentation. It's concise, clear, and directly reflects the changeset's primary focus.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.
✨ 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 jorrit/chore-prepare-ctoken-sdk-release

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a72be0 and 417b325.

📒 Files selected for processing (1)
  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs (16 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
sdk-libs/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in sdk-libs must not depend on light-test-utils; integration tests must be located in sdk-tests/

Files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
🧠 Learnings (65)
📓 Common learnings
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use AccountInfos structs (CreateCMintAccountInfos, MintToCTokenInfos, CreateCTokenAccountInfos, CreateAssociatedTokenAccountInfos, TransferCtokenAccountInfos) from light-ctoken-sdk for typed account management
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-token-test/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:57.458Z
Learning: Applies to sdk-tests/sdk-token-test/**/*test.rs : Tests should use light-ctoken-sdk functions from sdk-libs/compressed-token-sdk for testing ctoken instructions
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use the builder pattern from `light-ctoken-sdk::ctoken` module for CPI operations in native Solana programs
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/PACKED_ACCOUNTS.md:0-0
Timestamp: 2025-11-24T17:59:54.233Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/**/*.rs : Provide descriptive names in ProgramPackedAccounts error messages (e.g., 'token_mint' instead of 'account')
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export new wrapper modules in `account_compression_cpi/mod.rs` using `pub mod new_operation;` and `pub use new_operation::*;`, then import in `lib.rs`
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Create wrapper instruction module at `src/account_compression_cpi/new_operation.rs` with `NewOperationContext` struct defining required accounts
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use the `invoke_signed()` method for PDA-signed CPI calls with properly derived PDA and bump seeds
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Implement `process_new_operation()` function in wrapper module to handle PDA signer setup, account mapping, and CPI execution
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/create_*token_account*.rs : CToken account layout is the same as SPL tokens but implements a custom Compressible extension
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use the `invoke()` method for regular CPI calls where the program acts as authority
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: DOCS.md:0-0
Timestamp: 2025-12-06T00:50:17.433Z
Learning: Applies to **/docs/* : For CPI documentation include: Target program (program being called), PDA signer (seeds and bump for CPI authority), Account mapping (how accounts passed through), Data passthrough (instruction data handling), Example code (complete CPI invocation).
📚 Learning: 2025-12-06T00:49:00.181Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use AccountInfos structs (CreateCMintAccountInfos, MintToCTokenInfos, CreateCTokenAccountInfos, CreateAssociatedTokenAccountInfos, TransferCtokenAccountInfos) from light-ctoken-sdk for typed account management

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:54.233Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/PACKED_ACCOUNTS.md:0-0
Timestamp: 2025-11-24T17:59:54.233Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/**/*.rs : Provide descriptive names in ProgramPackedAccounts error messages (e.g., 'token_mint' instead of 'account')

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:01:54.689Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:54.689Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/MINT_ACTION.md : MintAction documentation must cover batch instruction for compressed mint management supporting 9 actions: CreateCompressedMint, MintTo, UpdateMintAuthority, UpdateFreezeAuthority, CreateSplMint, MintToCToken, UpdateMetadataField, UpdateMetadataAuthority, RemoveMetadataKey

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:00.181Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use the `invoke_signed()` method for PDA-signed CPI calls with properly derived PDA and bump seeds

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/mint_action/*.rs : MintAction instruction is a batch instruction supporting 9 action types: CreateCompressedMint, MintTo, UpdateMintAuthority, UpdateFreezeAuthority, CreateSplMint, MintToCToken, UpdateMetadataField, UpdateMetadataAuthority, RemoveMetadataKey, with support for both compressed and decompressed token minting

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/mint_action/*.rs : Compressed mint accounts support one extension: TokenMetadata

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/seed_providers.rs : PDA and CToken seed provider implementations with client-side seed functions should be in `seed_providers.rs`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:00.181Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Use the builder pattern from `light-ctoken-sdk::ctoken` module for CPI operations in native Solana programs

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:13.714Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_ITERATOR.md:0-0
Timestamp: 2025-11-24T17:59:13.714Z
Learning: Applies to program-libs/account-checks/docs/**/*.rs : Use descriptive account names when calling AccountIterator methods (e.g., `iter.next_account("token_mint")` instead of `iter.next_account("account_3")`)

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Create wrapper instruction module at `src/account_compression_cpi/new_operation.rs` with `NewOperationContext` struct defining required accounts

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:00.181Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Applies to sdk-tests/sdk-ctoken-test/**/*.rs : Derive PDAs using Pubkey::find_program_address() with consistent seed values before using invoke_signed()

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/**/*.rs : PDA derivation functions should accept `&[&[u8]]` for seeds and `&[u8; 32]` for program_id when using AccountInfoTrait methods `find_program_address()` or `create_program_address()`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/pack_unpack.rs : Pubkey compression logic and `PackedXxx` struct generation with Pack/Unpack trait implementations should be in `pack_unpack.rs`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Implement `check_pda_seeds` function to derive PDA using `find_program_address` and verify it matches account key, returning `InvalidSeeds` (20010) error on mismatch

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Compute hashed_pubkey in `src/initialize_address_tree.rs` by hashing and truncating the owner pubkey to 31 bytes for bn254 field compatibility.

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:00:13.178Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-11-24T18:00:13.178Z
Learning: Applies to program-libs/compressible/docs/**/config.rs : Set CompressibleConfig default values for CToken V1: base_rent = 1220, compression_cost = 11000, lamports_per_byte_per_epoch = 10, and address_space[0] = `amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/create_*token_account*.rs : CToken account layout is the same as SPL tokens but implements a custom Compressible extension

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:21.983Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:21.983Z
Learning: Applies to program-libs/compressible/src/config.rs : CompressibleConfig account structure must support serialization via Anchor, Pinocchio, and Borsh formats for Light Registry program integration

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:21.983Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:21.983Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement default initialization for CToken V1 config in CompressibleConfig structure

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:00:13.178Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/docs/CONFIG_ACCOUNT.md:0-0
Timestamp: 2025-11-24T18:00:13.178Z
Learning: Applies to program-libs/compressible/docs/program-libs/compressible/src/config.rs : CompressibleConfig struct must use `#[repr(C)]` for proper memory layout with fixed field ordering: version (u16, 2 bytes), state (u8, 1 byte), bump (u8, 1 byte), update_authority (Pubkey, 32 bytes), withdrawal_authority (Pubkey, 32 bytes), rent_sponsor (Pubkey, 32 bytes), compression_authority (Pubkey, 32 bytes), rent_sponsor_bump (u8, 1 byte), compression_authority_bump (u8, 1 byte), rent_config (RentConfig, 8 bytes), address_space ([Pubkey; 4], 128 bytes), and _place_holder ([u8; 32], 32 bytes) for total of 256 bytes

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/variant_enum.rs : Account variant enum (`CompressedAccountVariant`) generation and `CompressedAccountData` wrapper struct should be implemented in `variant_enum.rs`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/decompress_context.rs : Decompression trait implementation (`DecompressContext`) with account accessors, PDA/token separation logic, and token processing delegation should be in `decompress_context.rs`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:00.181Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-tests/sdk-ctoken-test/README.md:0-0
Timestamp: 2025-12-06T00:49:00.181Z
Learning: Implement all 8 core compressed token operations: create_cmint, mint_to_ctoken, create_token_account_invoke, create_token_account_invoke_signed, create_ata_invoke, create_ata_invoke_signed, transfer_interface_invoke, and transfer_interface_invoke_signed

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : `InitAddressTreeAccountsInstructionData` struct in `src/initialize_address_tree.rs` must include: height (u32, default 40), index (u64), root_history_capacity (u32, default 200), input_queue_batch_size (u64, default 15,000), input_queue_zkp_batch_size (u64, default 250), bloom_filter_capacity (u64, default batch_size * 8), bloom_filter_num_iters (u64, default 3 for test/10 for production), program_owner (Option<Pubkey>), forester (Option<Pubkey>), rollover_threshold (Option<u64>, default 95%), network_fee (Option<u64>, default 10,000 lamports), and close_threshold (Option<u64>).

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:54:38.537Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/README.md:0-0
Timestamp: 2025-11-24T17:54:38.537Z
Learning: Implement compressed token program interfaces for third-party token creation and usage on Solana using ZK Compression

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:55:17.323Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: sdk-libs/macros/src/compressible/README.md:0-0
Timestamp: 2025-11-24T17:55:17.323Z
Learning: Applies to sdk-libs/macros/src/compressible/**/instructions.rs : Compress/decompress instruction handlers and context struct generation should be implemented in `instructions.rs`, with compress using PDA-only and decompress supporting full PDA + ctoken

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:54:33.614Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/anchor/README.md:0-0
Timestamp: 2025-11-24T17:54:33.614Z
Learning: Implement the Compressed Token Program interface for creating and using compressed tokens on Solana with ZK Compression

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/extensions/*compressible*.rs : When working with ctoken accounts that have the compressible extension, you MUST read program-libs/compressible/docs/ including RENT.md, CONFIG_ACCOUNT.md, and SOLANA_RENT.md for complete rent system documentation

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Error codes must be defined in programs/compressed-token/anchor/src/lib.rs as anchor_compressed_token::ErrorCode enum and returned as ProgramError::Custom(error_code as u32) on-chain

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:37.752Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:37.752Z
Learning: Applies to programs/compressed-token/program/**/ctoken_transfer.rs : CTokenTransfer instruction is SPL-compatible and transfers between decompressed accounts only

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Implement `check_program` function to verify account key matches program_id AND is marked executable, returning `InvalidProgramId` (20011) or `ProgramNotExecutable` (20012) errors

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Return error `AccountError::InvalidAccountSize` (error code 12006) when account data length doesn't match calculated size requirements

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:46.693Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ERRORS.md:0-0
Timestamp: 2025-11-24T17:59:46.693Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/error.rs : Map Pinocchio standard ProgramError variants (InvalidArgument, InvalidInstructionData, InvalidAccountData, AccountDataTooSmall, InsufficientFunds, IncorrectProgramId, MissingRequiredSignature, AccountAlreadyInitialized, UninitializedAccount, NotEnoughAccountKeys, AccountBorrowFailed) to AccountError::PinocchioProgramError with codes 1-11

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Validate account ownership by Light account compression program using `check_owner` from `light-account-checks` when deserializing `BatchedQueueAccount` with `output_from_account_info`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:01:54.689Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:01:54.689Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/**/*.md : Instruction documentation must include the following sections: path, description (including accounts and state layout), instruction_data, Accounts (in order with checks), instruction logic and checks, and Errors (with descriptions of causes)

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/account_info/test_account_info.rs : Create a test-only AccountInfo mock implementation without external dependencies for unit testing AccountInfoTrait implementations

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/account_info/{solana,pinocchio}.rs : Implement AccountInfoTrait with SDK-specific Pubkey types: `solana_pubkey::Pubkey` for solana-program feature and `[u8; 32]` raw bytes for pinocchio feature

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:13.007Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:13.007Z
Learning: Applies to program-libs/account-checks/src/account_info/test_account_info.rs : Provide test mock AccountInfo implementation for unit testing purposes

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:13.007Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:13.007Z
Learning: Applies to program-libs/account-checks/src/account_info/*.rs : Use AccountInfoTrait abstraction for unified account validation across solana-program and pinocchio SDKs

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Use generic `AccountInfoTrait` parameter for all account validation functions to enable compatibility with both Solana and Pinocchio runtimes

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Initialize address tree with integrated address queue in `src/initialize_address_tree.rs`. Creates one `BatchedMerkleTreeAccount` with account layout defined in `src/merkle_tree.rs`, metadata in `src/merkle_tree_metadata.rs`, tree type `TreeType::AddressV2` (5), initial root `ADDRESS_TREE_INIT_ROOT_40`, starts at next_index 1, and discriminator `BatchMta` (8 bytes).

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: CPI processing must setup PDA signer seeds using the CPI_AUTHORITY_PDA_SEED constant and bump, then create CpiContext with `new_with_signer` using the signer_seeds

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/initialize_address_tree.rs : Address tree initialization must create a single Solana account: BatchedMerkleTreeAccount with integrated input queue, initialized with a single leaf: H(0, HIGHEST_ADDRESS_PLUS_ONE)

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:23.357Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:59:23.357Z
Learning: Applies to program-libs/account-checks/docs/src/**/packed_accounts.rs : Implement index-based dynamic account access with bounds checking for handling variable account sets (mint, owner, delegate accounts)

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:13.007Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:13.007Z
Learning: Applies to program-libs/account-checks/src/packed_accounts.rs : Use index-based account access with bounds-checked retrieval for dynamic account sets

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:13.714Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_ITERATOR.md:0-0
Timestamp: 2025-11-24T17:59:13.714Z
Learning: Applies to program-libs/account-checks/docs/**/*.rs : Validate account permissions (signers and mutability) early in instruction processing using AccountIterator methods

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:23.357Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:59:23.357Z
Learning: Applies to program-libs/account-checks/docs/src/**/*.rs : Define constant discriminator arrays for compile-time verification of account types

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:54.233Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/PACKED_ACCOUNTS.md:0-0
Timestamp: 2025-11-24T17:59:54.233Z
Learning: Use ProgramPackedAccounts when account indices come from instruction data and accounts can be accessed in any order

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:13.007Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:13.007Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use convenience methods next_signer, next_mut, and next_non_mut for simplified account iterator access

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:46.693Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ERRORS.md:0-0
Timestamp: 2025-11-24T17:59:46.693Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/error.rs : Implement From<std::cell::BorrowError> and From<std::cell::BorrowMutError> to convert to AccountError::BorrowAccountDataFailed when using solana-program SDK

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:46.693Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ERRORS.md:0-0
Timestamp: 2025-11-24T17:59:46.693Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/error.rs : All AccountError variants must convert automatically to `ProgramError::Custom(u32)` for both solana-program and pinocchio SDKs using From trait implementations

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:58:50.237Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_CHECKS.md:0-0
Timestamp: 2025-11-24T17:58:50.237Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/checks.rs : Implement `account_info_init` function to initialize account with discriminator, handling `BorrowAccountDataFailed` (20003) and `AlreadyInitialized` (20006) errors

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:59:03.485Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/docs/ACCOUNT_INFO_TRAIT.md:0-0
Timestamp: 2025-11-24T17:59:03.485Z
Learning: Applies to program-libs/account-checks/docs/program-libs/account-checks/src/account_info/*.rs : AccountInfoTrait implementations must return `AccountError` from all fallible operations: `BorrowAccountDataFailed` (12009) for borrow failures, `InvalidSeeds` (12016) for PDA creation, and `FailedBorrowRentSysvar` (12014) for rent access

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : When deserializing BatchedMerkleTreeAccount in Solana programs, use `BatchedMerkleTreeAccount::state_from_account_info()` for state trees and `BatchedMerkleTreeAccount::address_from_account_info()` for address trees

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:13.007Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:13.007Z
Learning: Applies to program-libs/account-checks/src/account_info/account_info_trait.rs : Implement unified data access interface with `try_borrow_data` and `try_borrow_mut_data` methods in AccountInfoTrait

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export new wrapper modules in `account_compression_cpi/mod.rs` using `pub mod new_operation;` and `pub use new_operation::*;`, then import in `lib.rs`

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T18:02:15.670Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:02:15.670Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Implement `process_new_operation()` function in wrapper module to handle PDA signer setup, account mapping, and CPI execution

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-12-06T00:49:21.983Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-12-06T00:49:21.983Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement PDA derivation methods (`derive_pda`, `derive_v1_config_pda`) on CompressibleConfig for account discovery

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:50.011Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_STATE_TREE.md:0-0
Timestamp: 2025-11-24T17:56:50.011Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_state_tree.rs : Compute and store hashed pubkeys by hashing and truncating to 31 bytes for bn254 field compatibility in both queue and tree accounts

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:20.711Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/INITIALIZE_ADDRESS_TREE.md:0-0
Timestamp: 2025-11-24T17:56:20.711Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/initialize_address_tree.rs : Set discriminator to `BatchMta` `[66, 97, 116, 99, 104, 77, 116, 97]` (8 bytes) for BatchedMerkleTreeAccount in `src/initialize_address_tree.rs`.

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/Cargo.toml : Depend on light-compressed-account crate for compressed account types and utilities

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:57:53.312Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/TREE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:53.312Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Account validation for address trees must check: (1) account ownership by Light account compression program, (2) account discriminator is `BatchMta`, and (3) tree type is `ADDRESS_MERKLE_TREE_TYPE_V2` (5)

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:57:39.230Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/QUEUE_ACCOUNT.md:0-0
Timestamp: 2025-11-24T17:57:39.230Z
Learning: Applies to program-libs/batched-merkle-tree/docs/src/queue.rs : Pre-hash merkle tree pubkeys to 31 bytes (248 bits) with 1 byte padding for bn254 field size compatibility in Poseidon hashing within ZK circuits

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
📚 Learning: 2025-11-24T17:56:00.229Z
Learnt from: CR
Repo: Lightprotocol/light-protocol PR: 0
File: program-libs/batched-merkle-tree/docs/CLAUDE.md:0-0
Timestamp: 2025-11-24T17:56:00.229Z
Learning: Applies to program-libs/batched-merkle-tree/docs/**/*.rs : Use constants from constants.rs including ADDRESS_TREE_INIT_ROOT_40 generated from IndexedMerkleTree reference implementation

Applied to files:

  • sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs
🧬 Code graph analysis (1)
sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs (2)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/instruction.rs (2)
  • derive_cmint_compressed_address (187-196)
  • find_cmint_address (206-211)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Test program-libs-slow
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (compressed-token-and-e2e, ["cargo test -p light-compressed-token", "cargo-test-sbf -p c...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
  • GitHub Check: Forester e2e test
🔇 Additional comments (1)
sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs (1)

25-75: CreateCMint docs + builder wiring look coherent with the new cmint helpers

The updated docs and example nicely show the intended flow (derive cmint address, build CreateCMintParams, then call CreateCMint::new(...).instruction()), and the struct/constructor changes (mint_seed_pubkey usage and MintActionMetaConfig::new_create_mint call) are consistent and straightforward. I don’t see functional issues here.

Also applies to: 77-167


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
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
sdk-libs/sdk/src/lib.rs (2)

3-6: Minor grammar issue in documentation.

Line 4 begins with "and unique addresses..." which creates an awkward sentence fragment. Consider combining into a single coherent statement or restructuring for clarity.

//! Compressed Accounts store state as account hashes in State Merkle trees.
//! and unique addresses in Address Merkle trees.
+//! Compressed Accounts store state as account hashes in State Merkle trees
+//! and unique addresses in Address Merkle trees.

147-147: Add documentation comments to the new public modules.

The error and utils modules at lines 147 and 154 are properly defined and exported, but they lack documentation comments. Other modules in the same file have documentation (e.g., cpi, instruction, transfer). Add doc comments to both modules for consistency:

/// Error types for the light SDK.
pub mod error;

/// Utility functions for the light SDK.
pub mod utils;
sdk-libs/ctoken-sdk/src/ctoken/compressible.rs (1)

48-75: Align CPI default token_account_version with CompressibleParams::default()

CompressibleParamsCpi::new uses CompressibleParams::default() for most fields but hardcodes token_account_version: TokenDataVersion::ShaFlat instead of defaults.token_account_version. That couples the CPI helper to a specific version and can silently diverge from the core default if it changes.

Prefer sourcing from defaults.token_account_version to keep both in sync:

-        Self {
+        Self {
             compressible_config,
             rent_sponsor,
             system_program,
             pre_pay_num_epochs: defaults.pre_pay_num_epochs,
             lamports_per_write: defaults.lamports_per_write,
             compress_to_account_pubkey: None,
-            token_account_version: TokenDataVersion::ShaFlat,
+            token_account_version: defaults.token_account_version,
         }
sdk-libs/ctoken-sdk/src/ctoken/transfer_ctoken.rs (1)

18-55: CPI helper is fine; consider clarifying max_top_up semantics

The new TransferCtokenCpi wrapper and its invoke/invoke_signed helpers are wired correctly: they build a TransferCtoken via From and pass [source, destination, authority] to invoke(_signed).

One small nit: the field comment on max_top_up says "0 = no limit", but the field type is Option<u16>, where None already encodes "no limit". If Some(0) is intended to be equivalent to None, it may be worth tightening the comment or enforcing that invariant at construction.

sdk-libs/ctoken-sdk/src/ctoken/mod.rs (1)

147-191: New ID/config helper fns look good; minor naming consistency nit

CTOKEN_PROGRAM_ID, CTOKEN_CPI_AUTHORITY, COMPRESSIBLE_CONFIG_V1, RENT_SPONSOR, and the helper functions id(), cpi_authority(), config_pda(), and rent_sponsor_pda() are simple, correct wrappers and match the documented addresses.

If you want maximal API consistency, consider naming the helpers either all with _pda suffix or none (e.g. program_id(), cpi_authority_pda(), compressible_config_pda(), rent_sponsor_pda()), but that’s purely stylistic.

sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs (1)

306-354: Consider extracting duplicated account_infos construction.

The invoke and invoke_signed methods share nearly identical account ordering logic (lines 310-326 vs 335-351). This duplication increases maintenance burden and risk of divergence.

Consider extracting a helper method:

+    fn build_account_infos(self) -> (Instruction, Vec<AccountInfo<'info>>) {
+        let instruction = self.instruction()?;
+        let mut account_infos = vec![
+            self.system_accounts.light_system_program,
+            self.mint_signer,
+            self.authority,
+            self.payer,
+            self.system_accounts.cpi_authority_pda,
+            self.system_accounts.registered_program_pda,
+            self.system_accounts.account_compression_authority,
+            self.system_accounts.account_compression_program,
+            self.system_accounts.system_program,
+            self.output_queue,
+            self.address_tree,
+        ];
+        if let Some(cpi_context_account) = self.cpi_context_account {
+            account_infos.push(cpi_context_account);
+        }
+        (instruction, account_infos)
+    }
sdk-libs/ctoken-sdk/src/ctoken/mint_to.rs (2)

275-327: Significant code duplication between invoke and invoke_signed.

The account_infos construction (lines 279-297 vs 306-324) is nearly identical between the two methods. This 20-line duplication is more substantial than in other CPI types.

Extract the account ordering into a helper:

+    fn collect_account_infos(self) -> (Instruction, Vec<AccountInfo<'info>>) {
+        let instruction = self.instruction()?;
+        let mut account_infos = vec![
+            self.system_accounts.light_system_program,
+            self.authority,
+            self.payer,
+            self.system_accounts.cpi_authority_pda,
+            self.system_accounts.registered_program_pda,
+            self.system_accounts.account_compression_authority,
+            self.system_accounts.account_compression_program,
+            self.system_accounts.system_program,
+        ];
+        if let Some(cpi_context_account) = self.cpi_context_account {
+            account_infos.push(cpi_context_account);
+        }
+        account_infos.push(self.output_queue);
+        account_infos.push(self.state_tree);
+        account_infos.push(self.input_queue);
+        account_infos.extend(self.ctoken_accounts);
+        (instruction, account_infos)
+    }

35-37: TODO: Make account_index dynamic.

This hardcoded account_index: 0 at line 36 (and line 163) limits flexibility. The add_mint_to_action method allows adding more actions with custom indices, but the initial action is always index 0.

Would you like me to open an issue to track making the initial account_index configurable in MintToCTokenParams::new and MintToCTokenCpiWriteParams::new?

- derive_compressed_mint_address -> derive_cmint_compressed_address
- find_spl_mint_address -> find_cmint_address
- CreateCMint::mint_signer -> mint_seed_pubkey
- CreateCMintCpi::mint_signer -> mint_seed
- CreateCMintCpi::new_with_address -> new
Copy link
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
sdk-libs/macros/src/compressible/instructions.rs (1)

582-590: Error information is lost for non-custom errors.

When LocalProvider::get_seeds returns a non-custom error, the mapping defaults to Custom(0), discarding the original error variant (e.g., InvalidAccountData, BorshIoError). This complicates debugging.

Consider either preserving error type information via distinct custom codes or documenting why code 0 is acceptable here.

sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/instruction.rs (1)

186-211: Consolidate duplicated mint address derivation functions to prevent maintenance drift.

These three functions—derive_cmint_compressed_address, derive_cmint_from_spl_mint, and find_cmint_address—are duplicated identically in both sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs and sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/instruction.rs. The functions share the same signatures and implementations, using identical seeds and program IDs. This duplication risks unintended divergence if one copy is updated without the other. Move these functions to a shared utility module (e.g., sdk-libs/ctoken-sdk/src/utils/mint_address.rs or similar) and re-export from both current locations to maintain a single source of truth.

sdk-libs/ctoken-sdk/src/ctoken/transfer_spl_ctoken.rs (1)

94-130: Account ordering duplicated between invoke and invoke_signed — consider extracting.

Both methods construct identical account_infos arrays. While this works correctly, you could reduce duplication by extracting the array construction into a helper method. The comments documenting the account order are helpful for maintenance.

+    fn build_account_infos(self) -> ([AccountInfo<'info>; 8], Instruction) {
+        let instruction = TransferSplToCtoken::from(&self).instruction().unwrap();
+        let account_infos = [
+            self.compressed_token_program_authority,
+            self.payer,
+            self.mint,
+            self.destination_ctoken_account,
+            self.authority,
+            self.source_spl_token_account,
+            self.spl_interface_pda,
+            self.spl_token_program,
+        ];
+        (account_infos, instruction)
+    }
sdk-libs/ctoken-sdk/src/ctoken/transfer_ctoken_spl.rs (2)

93-129: Same duplication pattern as transfer_spl_ctoken.rs.

The invoke and invoke_signed methods have identical account array construction. Consider extracting to a helper if you want consistency across the codebase. The account ordering comments are valuable documentation.


147-209: Instruction construction with profiling looks good.

The #[profile] macro enables performance tracking. The two-phase operation (compress ctoken → decompress to SPL) correctly uses indices 1 and 2 for source/destination respectively, matching the packed_accounts order.

Note the TODO comment on line 188 (pool_index (TODO: make dynamic)) — this may need addressing in a follow-up.

Would you like me to open an issue to track making the pool_index parameter dynamic?

sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs (1)

220-301: Naming inconsistency: CreateCompressedMintCpiWrite still uses mint_signer while CreateCMint uses mint_seed_pubkey.

The CreateCMint struct renamed its field to mint_seed_pubkey to clarify its purpose, but CreateCompressedMintCpiWrite (lines 224-230) and CreateCompressedMintCpiWriteCpi (lines 455-462) still use mint_signer. This inconsistency could confuse SDK users.

If the semantics are the same, consider aligning the naming:

 pub struct CreateCompressedMintCpiWrite {
-    pub mint_signer: Pubkey,
+    pub mint_seed: Pubkey,
     pub payer: Pubkey,
     ...
 }

Please verify whether mint_signer in the CPI write path serves the same purpose as mint_seed_pubkey in CreateCMint. If so, the naming should be consistent.

♻️ Duplicate comments (1)
sdk-libs/macros/src/compressible/instructions.rs (1)

606-614: Error information is lost for non-custom errors.

Same issue as get_seeds: non-custom errors are mapped to Custom(0), losing the original error type. Consider preserving error information or documenting this behavior.

@ananas-block ananas-block force-pushed the jorrit/chore-prepare-ctoken-sdk-release branch from 3c78cd3 to eb576ab Compare December 6, 2025 20:32
@ananas-block ananas-block force-pushed the jorrit/chore-prepare-ctoken-sdk-release branch from eb576ab to 5a398a6 Compare December 6, 2025 20:38
@ananas-block ananas-block force-pushed the jorrit/chore-prepare-ctoken-sdk-release branch from 445bcdf to ba715c2 Compare December 6, 2025 20:51
Copy link
Contributor

@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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (20)
sdk-libs/ctoken-sdk/src/compressed_token/v2/compress_and_close.rs (1)

306-368: Consider simplifying the rent_sponsor_pubkey logic.

The rent_sponsor_pubkey variable is initialized as None on line 306, then potentially set inside a nested loop (lines 351-353), then checked again on line 360. This control flow is a bit convoluted.

The variable actual_rent_sponsor is determined on lines 343-368, but the logic duplicates the extension-searching pattern that already happened for authority (lines 322-340).

Consider extracting the extension lookup into a small helper to reduce duplication:

+fn find_compressible_extension(ctoken: &CToken) -> Option<&Compressible> {
+    ctoken.extensions.as_ref()?.iter().find_map(|ext| {
+        if let ZExtensionStruct::Compressible(e) = ext { Some(e) } else { None }
+    })
+}

Then use this helper for both authority and rent_sponsor lookups.

sdk-libs/token-client/src/actions/transfer2/compress.rs (1)

26-35: Fix return type in compress doc comment to match the signature

The doc says Result<Instruction, CTokenSdkError>, but the function returns Result<Signature, RpcError>. This will mislead users and any generated docs; the comment should describe the actual API.

-/// `Result<Instruction, CTokenSdkError>` - The compression instruction
+/// `Result<Signature, RpcError>` - The transaction signature for the compression operation
sdk-libs/ctoken-sdk/src/compressed_token/v2/transfer2/instruction.rs (1)

149-184: Consider removing or uncommenting the dead code block.

This commented-out transfer2 function contains useful validation logic (checking method_used flag) that could be valuable. If this is work-in-progress, consider adding a TODO comment explaining when it will be enabled. If it's obsolete, removing it would improve maintainability.

sdk-libs/ctoken-sdk/src/compressed_token/v2/mint_action/cpi_accounts.rs (1)

115-125: Use check_mut() function and return AccountError::AccountNotMutable instead of AccountError::AccountMutable.

The code checks !account_info.is_writable() and returns AccountError::AccountMutable ("Account is mutable"), which is semantically inverted. When an account is NOT writable, the correct error is AccountError::AccountNotMutable (error code 20002). Better yet, use the check_mut() function from the account_checks module which returns the correct error automatically:

check_mut(&out_output_queue)?;

instead of manual writable checks. This aligns with the established validation pattern used throughout the codebase.

sdk-libs/token-client/src/instructions/transfer2.rs (3)

188-192: Unwrapped RPC call can panic; consider propagating the error.

The .unwrap() on get_validity_proof result will panic if the RPC call fails. Since this is client-side code that interacts with external services, propagate the error instead.

     let rpc_proof_result = rpc
         .get_validity_proof(hashes, vec![], None)
         .await
-        .unwrap()
+        .map_err(|_| CTokenSdkError::InvalidAccountData)?
         .value;

199-212: Unwrapped RPC call can panic; propagate error for resilience.

The .unwrap() on get_random_state_tree_info() (line 201) will panic if no tree info is available. Consider using ok_or to convert to an appropriate error.

     let shared_output_queue = if packed_tree_infos.address_trees.is_empty() {
         let shared_output_queue = rpc
             .get_random_state_tree_info()
-            .unwrap()
+            .ok_or(CTokenSdkError::InvalidAccountData)?
             .get_output_pubkey()
-            .unwrap();
+            .ok_or(CTokenSdkError::InvalidAccountData)?;
         packed_tree_accounts.insert_or_get(shared_output_queue)

264-269: Chain of unwraps on RPC account fetch can panic.

The double .unwrap() on get_account (lines 267-268) will panic if the account doesn't exist or the RPC fails. This pattern repeats at lines 331-336. Propagate errors for production resilience.

                 let source_account_owner = rpc
                     .get_account(input.solana_token_account)
                     .await
-                    .unwrap()
-                    .unwrap()
+                    .map_err(|_| CTokenSdkError::InvalidAccountData)?
+                    .ok_or(CTokenSdkError::InvalidAccountData)?
                     .owner;
sdk-libs/ctoken-sdk/src/compressed_token/v1/batch_compress/account_metas.rs (1)

29-33: unimplemented!() will panic at runtime; complete or guard this code path.

If with_lamports is true, this will panic. Either implement the SOL pool PDA derivation or add a compile-time feature gate / explicit error return to prevent runtime panics.

         let sol_pool_pda = if with_lamports {
-            unimplemented!("TODO hardcode sol pool pda")
+            // Use the SOL_POOL_PDA constant from light_sdk
+            Some(Pubkey::from(light_sdk::constants::SOL_POOL_PDA))
         } else {
             None
         };
sdk-libs/ctoken-sdk/src/compressed_token/v1/transfer/account_metas.rs (1)

193-193: Remove debug println! statement before release.

This appears to be leftover debug code that should not be in production. It will pollute logs and may leak configuration details.

-    println!("config.with_anchor_none {}", config.with_anchor_none);
sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/instruction.rs (2)

154-154: Minor formatting: missing space after comma.

-        compressed_mint_instruction_data,input.cpi_context
+        compressed_mint_instruction_data, input.cpi_context

186-211: Extract mint address derivation functions to a shared utility module.

Three functions are duplicated identically across sdk-libs/ctoken-sdk/src/compressed_token/v2/create_compressed_mint/instruction.rs and sdk-libs/ctoken-sdk/src/ctoken/create_cmint.rs:

  • find_cmint_address
  • derive_cmint_compressed_address
  • derive_cmint_from_spl_mint

Both modules export these functions in their public APIs, creating a maintenance burden where any changes must be synchronized in two places. Extract these to a shared utility module (e.g., sdk-libs/ctoken-sdk/src/utils/mint_address.rs) and re-export from both locations.

sdk-libs/ctoken-sdk/src/ctoken/compressible.rs (2)

86-94: Consider adding Debug derive to CompressibleParamsCpi.

CompressibleParams derives Debug (line 26), but CompressibleParamsCpi does not. Adding #[derive(Debug)] would be helpful for debugging CPI operations, though AccountInfo may require manual implementation.

+#[derive(Debug)]
 pub struct CompressibleParamsCpi<'info> {

96-112: Minor inconsistency in new() constructor.

Line 110 hardcodes TokenDataVersion::ShaFlat instead of using defaults.token_account_version. While functionally equivalent (since the default is also ShaFlat), using the default value would be more consistent and maintainable if the default ever changes.

             compress_to_account_pubkey: None,
-            token_account_version: TokenDataVersion::ShaFlat,
+            token_account_version: defaults.token_account_version,
sdk-libs/ctoken-sdk/src/utils.rs (1)

31-32: Consider using the spl_token::ID constant instead of hardcoding the address, but add spl-token as a dependency first.

Line 32 hardcodes the SPL Token program ID as a string, while line 31 uses spl_token_2022::ID directly. For consistency and to avoid potential typos, use the constant from the spl_token crate. However, spl-token is not currently listed as a dependency in this package's Cargo.toml, so you'll need to add it to the workspace dependencies alongside spl-token-2022.

+spl-token = { workspace = true }

Then update the code:

-    let spl_token = Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
+    let spl_token = spl_token::ID;
sdk-libs/ctoken-sdk/src/compressed_token/v1/transfer/instruction.rs (2)

121-128: Replace panic with proper error return.

This panic! will abort the entire program if cpi_context_pubkey is Some but cpi_context is None. Consider returning an error instead for graceful handling.

         if let Some(cpi_context_pubkey) = transfer_config.cpi_context_pubkey {
             if transfer_config.cpi_context.is_some() {
                 account_metas.push(AccountMeta::new(cpi_context_pubkey, false));
             } else {
-                // TODO: throw error
-                panic!("cpi_context.is_none() but transfer_config.cpi_context_pubkey is some");
+                return Err(CTokenSdkError::CpiContextRequired);
             }
         }

173-174: Consider propagating error from token_account.compress().

The .unwrap() here will panic on failure. Since this function returns Result, propagating the error would be safer.

     let mut token_account = CTokenAccount::new_empty(mint, recipient, output_tree_index);
-    token_account.compress(amount).unwrap();
+    token_account.compress(amount).map_err(|_| CTokenSdkError::InvalidCompressDecompressAmount)?;
sdk-libs/ctoken-sdk/src/ctoken/mint_to.rs (1)

238-245: Validation check for CPI context is appropriate.

Returning ProgramError::InvalidAccountData when neither first_set_context nor set_context is true prevents invalid CPI writes. Consider using a more specific error variant for clearer debugging.

sdk-libs/ctoken-sdk/src/ctoken/transfer_interface.rs (2)

93-157: Consider reducing duplication between invoke and invoke_signed.

Both methods share nearly identical dispatch logic—the only difference is calling .invoke() vs .invoke_signed(signer_seeds). Consider extracting the common pattern:

fn dispatch_transfer(
    &self,
    invoke_fn: impl FnOnce(/* variant */) -> Result<(), ProgramError>,
) -> Result<(), ProgramError> {
    // common logic
}

Or simpler: have invoke() delegate to invoke_signed(&[]) if the underlying CPI methods support empty signer seeds.

Also applies to: 163-227


100-107: max_top_up: None hardcoded—consider exposing as configurable.

Both branches hardcode max_top_up: None with the comment "No limit by default". If users need to set a top-up limit for ctoken→ctoken transfers, they'd need to bypass TransferInterfaceCpi entirely. Consider adding a builder method:

pub fn with_max_top_up(mut self, max_top_up: Option<u64>) -> Self {
    self.max_top_up = max_top_up;
    self
}

Also applies to: 170-177

sdk-libs/ctoken-sdk/src/compressed_token/v2/account2.rs (1)

363-365: Use self.output.mint for consistency with the rest of the file.

The line uses self.mint via Deref coercion, which works but is inconsistent—every other occurrence in this file (lines 125, 158, 183, 210, 241, 270, 303, 337) explicitly uses self.output.mint. Change line 364 to *account_infos[self.output.mint as usize].key for clarity and consistency.

Copy link
Contributor

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
sdk-libs/ctoken-sdk/src/compressed_token/v2/account2.rs (1)

363-377: Use self.output.mint and self.output.owner in accessor methods

The mint() and owner() methods reference non-existent fields. CTokenAccount2 only defines inputs, output, compression, delegate_is_set, and method_used (lines 12-19). The mint and owner fields exist only on the output field of type MultiTokenTransferOutputData. Update the methods to:

pub fn mint(&self, account_infos: &[AccountInfo]) -> Pubkey {
    *account_infos[self.output.mint as usize].key
}

pub fn owner(&self, account_infos: &[AccountInfo]) -> Pubkey {
    *account_infos[self.output.owner as usize].key
}

Note: The commented-out delegate_account method at line 388 demonstrates the correct pattern with self.output.delegate.

sdk-libs/ctoken-sdk/src/compressed_token/v2/transfer2/instruction.rs (1)

149-184: Consider removing commented-out code.

A large block of commented code (149-184) remains in the file. If this code is no longer needed, consider removing it to improve maintainability. If it's intended as documentation or future reference, consider moving it to inline documentation or an issue tracker.

sdk-libs/token-client/src/actions/ctoken_transfer.rs (1)

40-40: Address the TODO comment when ready.

This TODO indicates the instruction construction should eventually be sourced from the compressed-token-sdk. When that's done, you'll get better type safety and reduce code duplication.

Would you like me to open an issue to track this technical debt?

sdk-libs/ctoken-sdk/tests/mint_action_cpi_accounts_tests.rs (1)

473-475: Duplicate assertion detected.

Line 474 duplicates the assertion on line 473. While harmless, consider removing the duplicate for clarity.

     let result = MintActionCpiAccounts::<AccountInfo>::try_from_account_infos(&accounts);
     assert!(result.is_err());
-    assert!(result.is_err());
 }
sdk-libs/token-client/src/instructions/transfer2.rs (3)

300-363: Decompress SPL vs ctoken split is sound; fix misleading comment.

The updated owner check using recipient_account_owner.to_bytes() != CTOKEN_PROGRAM_ID correctly routes:

  • non-CTOKEN owners through decompress_spl with SPL interface PDA + pool index, and
  • CTOKEN owners through decompress_ctoken.

However, the comment in the else branch (“Use the new SPL-specific decompress method”) is now misleading since that branch calls decompress_ctoken. Consider updating the comment to something like “Use the ctoken-specific decompress method” to avoid confusion.


498-590: Compress-and-close error mapping is reasonable but a bit coarse.

The new handling:

  • Maps RPC fetch failures, zero-copy parsing failures, and missing compressible extension fields to CTokenSdkError::InvalidAccountData.
  • Requires a Compressible extension when is_compressible is true and uses the owner bytes as rent sponsor when is_compressible is false.

This is functionally consistent and keeps client-side validation simple. If you want better observability, you might consider introducing more specific CTokenSdkError variants for “missing compressible extension” vs “invalid layout” in the future, but that’s not a blocker.


5-20: Error type migration to CTokenSdkError is complete and consistent.

Both create_decompress_instruction and create_generic_transfer2_instruction correctly return Result<Instruction, CTokenSdkError>, and all internal error handling uses the new error type. Call sites in the action layer (compress.rs, decompress.rs, transfer.rs, etc.) are properly updated to handle the CTokenSdkError return type. No legacy TokenSdkError patterns remain in the codebase.

♻️ Duplicate comments (2)
sdk-libs/ctoken-sdk/src/ctoken/create.rs (1)

14-26: Doc examples still won’t compile due to ? usage in non-Result context.

Both examples use ? but are not wrapped in a Result-returning function, so rustdoc will attempt to generate fn main() { ... } and fail compilation. This is the same class of issue that was flagged earlier for this file.

Consider either:

  • Wrapping the examples in a hidden fn main() -> Result<(), solana_program_error::ProgramError> { ... }, or
  • Marking them as rust,ignore if you don’t want them compiled.

Example fix using a Result-returning function:

-/// ```rust
-/// # use solana_pubkey::Pubkey;
-/// # use light_ctoken_sdk::ctoken::CreateCTokenAccount;
-/// # let payer = Pubkey::new_unique();
-/// # let account = Pubkey::new_unique();
-/// # let mint = Pubkey::new_unique();
-/// # let owner = Pubkey::new_unique();
-/// let instruction =
-///
-///     CreateCTokenAccount::new(payer, account, mint, owner)
-///     .instruction()?;
-/// # Ok::<(), solana_program_error::ProgramError>(())
-/// ```
+/// ```rust
+/// # use solana_pubkey::Pubkey;
+/// # use light_ctoken_sdk::ctoken::CreateCTokenAccount;
+/// # fn example() -> Result<(), solana_program_error::ProgramError> {
+/// # let payer = Pubkey::new_unique();
+/// # let account = Pubkey::new_unique();
+/// # let mint = Pubkey::new_unique();
+/// # let owner = Pubkey::new_unique();
+/// let _instruction =
+///     CreateCTokenAccount::new(payer, account, mint, owner)
+///         .instruction()?;
+/// # Ok(())
+/// # }
+/// ```
@@
-/// ```rust,no_run
+/// ```rust,no_run
 /// # use light_ctoken_sdk::ctoken::{CreateCTokenAccountCpi, CompressibleParamsCpi};
 /// # use solana_account_info::AccountInfo;
 /// # use solana_pubkey::Pubkey;
-/// # let payer: AccountInfo = todo!();
-/// # let account: AccountInfo = todo!();
-/// # let mint: AccountInfo = todo!();
-/// # let owner: Pubkey = todo!();
-/// # let compressible: CompressibleParamsCpi = todo!();
-/// CreateCTokenAccountCpi {
+/// # fn example(
+/// #   payer: AccountInfo,
+/// #   account: AccountInfo,
+/// #   mint: AccountInfo,
+/// #   owner: Pubkey,
+/// #   compressible: CompressibleParamsCpi,
+/// # ) -> Result<(), solana_program_error::ProgramError> {
+/// CreateCTokenAccountCpi {
 ///     payer,
 ///     account,
 ///     mint,
 ///     owner,
 ///     compressible: Some(compressible),
 /// }
-/// .invoke()?;
-/// # Ok::<(), solana_program_error::ProgramError>(())
+/// .invoke()?;
+/// # Ok(())
+/// # }
 /// ```




Also applies to: 106-125

</blockquote></details>
<details>
<summary>sdk-libs/ctoken-sdk/src/ctoken/mint_to.rs (1)</summary><blockquote>

`54-83`: **Fix doc example import path for `CompressedMintWithContext`.**

The doc example (line 57) imports `CompressedMintWithContext` from `light_ctoken_sdk::ctoken`, but this type is not re-exported there. The actual import path is `light_ctoken_interface::instructions::mint_action::CompressedMintWithContext` (as shown in the implementation at line 5). Update the example to use the correct import path or ensure the type is properly re-exported in `light_ctoken_sdk::ctoken::mod.rs`.

</blockquote></details>

</blockquote></details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@SwenSchaeferjohann SwenSchaeferjohann merged commit ff145bd into main Dec 7, 2025
32 checks passed
@ananas-block ananas-block deleted the jorrit/chore-prepare-ctoken-sdk-release branch December 7, 2025 00:45
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.

3 participants