Skip to content

feat: compressed token sdk #1869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Jul 14, 2025

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive SDK libraries for compressed token operations, including account management, batch compression, delegation, freezing, minting, and transfer instructions.
    • Added extensive Solana program modules and test suites for compressed token workflows, such as deposit, escrow, batch operations, and multi-invocation flows.
    • Provided new utility functions for deriving token pool addresses and managing account metadata.
    • Added detailed documentation and debugging guides for CPI context and token operations.
  • Improvements

    • Standardized naming and data structures for compressed token accounts across SDK and client libraries.
    • Enhanced error handling with custom error types and numeric codes for SDK operations.
    • Updated client and indexer APIs to consistently use compressed token account representations.
    • Improved account info management and configuration for cross-program invocations.
    • Refined trait bounds and ownership semantics for account info handling in CPI contexts.
    • Added explicit error handling for system account additions to prevent silent failures.
    • Optimized CPI invocation code by removing unnecessary cloning of account infos.
  • Tests

    • Added comprehensive integration and unit tests covering compression, transfer, decompression, batch operations, deposit flows, and multi-invocation scenarios.
  • Documentation

    • Added in-depth guides and references for debugging and implementing compressed token operations, including CPI context best practices.
  • Chores

    • Updated workspace configuration to integrate new SDK libraries and test programs.
    • Refactored code for consistency, visibility, and trait bounds where necessary.
    • Reorganized imports and code structure for clarity and maintainability.

@ananas-block ananas-block marked this pull request as ready for review July 14, 2025 22:14
Copy link
Contributor

coderabbitai bot commented Jul 14, 2025

Walkthrough

This update introduces two new SDK libraries—compressed-token-types and compressed-token-sdk—and integrates them into the workspace. It adds a comprehensive test suite for compressed token operations, including batch compression, CPI context handling, and escrow PDAs. Major new modules provide account info abstractions, error handling, instruction builders, and test coverage for compressed token workflows. Additionally, indexer interfaces and implementations are updated to use CompressedTokenAccount instead of TokenAccount. Several improvements to CPI accounts handling, account meta utilities, and instruction packaging are included.

Changes

File(s) / Path(s) Change Summary
Cargo.toml, sdk-libs/compressed-token-types/Cargo.toml, sdk-libs/compressed-token-sdk/Cargo.toml, ... Added new SDK libraries (compressed-token-types, compressed-token-sdk), test program, and workspace dependencies.
sdk-libs/compressed-token-types/src/** Introduced modules for account info abstractions, constants, error types, instruction data structures, and token data.
sdk-libs/compressed-token-sdk/src/** Added modules for compressed token account logic, error handling, instruction builders (transfer, batch compress, approve), account meta utilities, and token pool PDA derivation.
sdk-libs/compressed-token-sdk/tests/account_metas_test.rs Added tests for account meta generation logic for compressed token instructions.
program-tests/sdk-token-test/** Added new test program with Anchor instructions for compressing, transferring, decompressing tokens, batch operations, escrow PDAs, and CPI context handling; included comprehensive integration tests and debugging documentation.
sdk-libs/client/src/indexer/**, sdk-libs/program-test/src/indexer/test_indexer.rs, sdk-libs/program-test/src/program_test/indexer.rs Updated all indexer interfaces and implementations to use CompressedTokenAccount instead of TokenAccount.
sdk-libs/sdk-types/src/cpi_accounts.rs, sdk-libs/sdk-types/src/instruction/tree_info.rs Updated trait bounds and method signatures for account info handling; improved ownership and utility methods.
sdk-libs/sdk/src/cpi/accounts.rs, sdk-libs/sdk/src/cpi/invoke.rs, sdk-libs/sdk/src/instruction/pack_accounts.rs Refactored account meta and info handling, improved CPI context support, and optimized account vector management.
program-libs/compressed-account/Cargo.toml, program-libs/compressed-account/src/compressed_account.rs Minor dependency addition and whitespace cleanup.
program-tests/create-address-test-program/src/lib.rs, program-tests/sdk-test/src/create_pda.rs Simplified account info handling and improved error propagation.
sdk-libs/sdk-types/src/constants.rs Removed trailing whitespace.

Sequence Diagram(s)

sequenceDiagram
    participant TestSuite as sdk-token-test Integration Tests
    participant AnchorProgram as sdk_token_test Program
    participant SDK as compressed-token-sdk
    participant Types as compressed-token-types
    participant Solana as Solana Runtime

    TestSuite->>AnchorProgram: Invoke compress_tokens / batch_compress / deposit / four_invokes
    AnchorProgram->>SDK: Call process_* functions (e.g., process_batch_compress_tokens)
    SDK->>Types: Construct instruction data, account metas, error handling
    SDK->>Solana: Submit Solana Instruction (e.g., batch_compress, transfer)
    Solana-->>SDK: Execute instruction, update state
    SDK-->>AnchorProgram: Result (success or error)
    AnchorProgram-->>TestSuite: Return outcome (assertions, logs)
Loading
sequenceDiagram
    participant AnchorProgram as sdk_token_test
    participant SDK as compressed-token-sdk
    participant Solana as Solana CPI
    participant Escrow as Escrow PDA

    AnchorProgram->>SDK: process_update_deposit (with CPI context)
    SDK->>Solana: Transfer tokens to escrow PDA (CPI)
    Solana->>Escrow: Update escrow PDA balance
    Escrow-->>Solana: Confirm update
    Solana-->>SDK: CPI result
    SDK-->>AnchorProgram: Operation result
Loading

Possibly related PRs

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

A rabbit hopped through fields of code,
Compressing tokens in a clever mode.
With batch and CPI, the flows align,
Escrow PDAs and proofs combine.
New libraries bloom, tests run with cheer—
The garden of tokens grows brighter this year!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Nitpick comments (20)
sdk-libs/compressed-token-types/src/instruction/mint_to.rs (1)

7-12: Well-structured data type with clear documentation.

The MintToParams struct is properly designed with appropriate field types and serialization traits. The comments clearly explain its purpose as an Anchor account struct.

Consider adding validation to ensure public_keys and amounts vectors have matching lengths:

impl MintToParams {
    pub fn new(public_keys: Vec<[u8; 32]>, amounts: Vec<u64>, lamports: Option<u64>) -> Result<Self, &'static str> {
        if public_keys.len() != amounts.len() {
            return Err("public_keys and amounts must have the same length");
        }
        Ok(Self { public_keys, amounts, lamports })
    }
}
sdk-libs/compressed-token-types/src/instruction/batch_compress.rs (1)

4-13: Consider improving field documentation for clarity.

The struct design is sound, but the dual amount fields (amounts and amount) could benefit from clearer documentation about their mutual exclusivity.

Consider adding more explicit documentation:

pub struct BatchCompressInstructionData {
    pub pubkeys: Vec<[u8; 32]>,
-    // Some if one amount per pubkey.
+    /// Individual amounts per pubkey. Mutually exclusive with `amount`.
    pub amounts: Option<Vec<u64>>,
    pub lamports: Option<u64>,
-    // Some if one amount across all pubkeys.
+    /// Single amount applied to all pubkeys. Mutually exclusive with `amounts`.
    pub amount: Option<u64>,
    pub index: u8,
    pub bump: u8,
}
sdk-libs/compressed-token-types/src/instruction/generic.rs (1)

1-10: Consider consistency with crate's serialization approach.

While the generic instruction data wrapper design is sound, this module uses Borsh traits directly instead of the conditional Anchor/Borsh approach used elsewhere in the crate. Consider using the same pattern as config.rs for consistency.

Apply this diff to align with the crate's serialization pattern:

-use borsh::{BorshDeserialize, BorshSerialize};
+use crate::{AnchorDeserialize, AnchorSerialize};

-#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
+#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)]
sdk-libs/compressed-token-types/src/instruction/freeze.rs (1)

5-12: Consider reducing code duplication between freeze and thaw structs.

Both CompressedTokenInstructionDataFreeze and CompressedTokenInstructionDataThaw have identical field definitions. Consider extracting a common base struct or using a generic approach to reduce duplication.

#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
pub struct CompressedTokenInstructionDataBase {
    pub proof: CompressedProof,
    pub owner: [u8; 32],
    pub input_token_data_with_context: Vec<TokenAccountMeta>,
    pub cpi_context: Option<CompressedCpiContext>,
    pub outputs_merkle_tree_index: u8,
}

pub type CompressedTokenInstructionDataFreeze = CompressedTokenInstructionDataBase;
pub type CompressedTokenInstructionDataThaw = CompressedTokenInstructionDataBase;
sdk-libs/compressed-token-sdk/tests/account_metas_test.rs (1)

14-14: Remove or address the TODO comment.

The TODO comment suggests rewriting to use get_transfer_instruction_account_metas, but the test already uses this function. Either remove the TODO or clarify what specific rewrite is needed.

-// TODO: Rewrite to use get_transfer_instruction_account_metas
sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs (1)

46-53: Document the amounts vs amount field usage

Consider adding a comment explaining why both amounts and amount fields exist, with one being None. This appears to be a variant pattern for batch vs single operations.

     // Create instruction data
+    // Note: BatchCompressInstructionData supports both batch (amounts) and single (amount) operations.
+    // For batch compress, we use amounts and set amount to None.
     let instruction_data = BatchCompressInstructionData {
         pubkeys,
         amounts: Some(amounts),
         amount: None,
program-tests/sdk-token-test/CLAUDE.md (1)

1-170: Consider renaming this file to be more descriptive

The file is named "CLAUDE.md" which doesn't clearly indicate its purpose. Consider renaming it to something more descriptive like "CPI_CONTEXT_DEBUGGING_GUIDE.md" or "SDK_TOKEN_TEST_GUIDE.md".

sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs (1)

10-20: Track TODO items for completion

There are several TODO comments that should be tracked:

  1. Line 10: Testing with delegate functionality
  2. Line 18: Renaming tree accounts to packed accounts for consistency
  3. Line 82: Testing the filter_packed_accounts function

Would you like me to create GitHub issues to track these TODO items?

sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1)

66-66: Address TODO: Derive token_pool_pda

The TODO indicates that token_pool_pda should be derived from the mint rather than passed as a parameter. This would make the API more convenient and less error-prone.

Would you like me to implement the token pool PDA derivation logic or open a new issue to track this task?

program-tests/sdk-token-test/src/lib.rs (1)

147-149: Consider removing or documenting debug messages

These msg! statements appear to be debug logging. Since this is a test program, they may be intentional, but consider whether they should be kept or documented.

If these messages are intended for debugging during tests, consider adding a comment to document their purpose:

+        // Debug logging for test verification
         msg!("seeds: {:?}", b"escrow");
         msg!("seeds: {:?}", address);
         msg!("recipient_bump: {:?}", recipient_bump);
program-tests/sdk-token-test/src/process_create_compressed_account.rs (2)

50-52: Address TODO: Remove or fix unused cpi_context_account_index.

The comment indicates this field is unused. Either remove it from the CompressedCpiContext struct or implement its intended functionality.

Would you like me to investigate the proper usage of cpi_context_account_index or help remove it if it's truly unused?


105-105: Address TODO: Clarify the index vs Pubkey usage.

The comment suggests uncertainty about using an index vs a Pubkey. This should be resolved for clarity.

program-tests/sdk-token-test/tests/test.rs (1)

456-572: Consider adding edge case tests.

While the batch compression test covers the happy path, consider adding tests for edge cases:

  • Empty recipients list
  • Single recipient
  • Maximum number of recipients
  • Recipients with zero amounts
  • Insufficient balance scenarios
sdk-libs/compressed-token-sdk/src/account.rs (1)

75-75: Track TODO: Skip zero amount outputs optimization.

This optimization could reduce transaction size and costs.

Would you like me to help implement the zero amount output filtering in the instruction data creation?

program-tests/sdk-token-test/tests/test_deposit.rs (2)

51-51: Consider removing or conditionalizing debug print statements.

These println! statements appear to be debug output that should be removed or wrapped in a debug flag for production tests.

-    println!("Batch compressed tokens successfully");
+    #[cfg(debug_assertions)]
+    println!("Batch compressed tokens successfully");

Also applies to: 71-73, 86-88, 100-100, 109-111


161-166: Remove or clarify misleading comment about new_with_anchor_none.

The comment mentions using new_with_anchor_none but the code doesn't actually use it. This comment should be removed or the code should be updated to match the comment's intention.

-    // new_with_anchor_none is only recommended for pinocchio else additional account infos cost approx 1k CU
-    // used here for consistentcy with into_account_infos_checked
-    // let config = TokenAccountsMetaConfig::new_client();
-    // let metas = get_transfer_instruction_account_metas(config);
-    // remaining_accounts.add_pre_accounts_metas(metas);
-    // Alternative even though we pass fewer account infos this is minimally more efficient.
program-tests/sdk-token-test/src/process_four_invokes.rs (1)

195-196: Consider documenting the pinocchio vs Solana program difference more prominently.

The comment indicates an important implementation detail about account info ordering that differs between pinocchio and Solana programs. This should be documented more prominently, perhaps in the module documentation.

sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1)

236-236: Make debug logging conditional.

Debug logging should be made conditional with a feature flag.

-        solana_msg::msg!("Tree accounts length calculation {}", system_len);
+        #[cfg(feature = "debug-logs")]
+        solana_msg::msg!("Tree accounts length calculation {}", system_len);
sdk-libs/compressed-token-types/src/instruction/transfer.rs (1)

23-23: Track the unimplemented TokenExtension TLV data placeholders.

Multiple structs contain tlv: Option<Vec<u8>> fields marked as placeholders for TokenExtension data. These should be tracked for future implementation to ensure token extensions are properly supported.

Would you like me to create an issue to track the implementation of TokenExtension TLV data support?

Also applies to: 34-34, 90-90

program-tests/sdk-token-test/tests/test_4_invocations.rs (1)

475-483: Improve error messages for missing compressed token accounts.

The test expects compressed token accounts to exist but uses generic error messages. Consider providing more context in the error messages.

     let mint2_token_account = compressed_token_accounts
         .iter()
         .find(|acc| acc.token.mint == mint2)
-        .expect("Compressed token account for mint2 should exist");
+        .unwrap_or_else(|| panic!("Compressed token account for mint2 not found. Available mints: {:?}", 
+            compressed_token_accounts.iter().map(|acc| acc.token.mint).collect::<Vec<_>>()));
 
     let mint3_token_account = compressed_token_accounts
         .iter()
         .find(|acc| acc.token.mint == mint3)
-        .expect("Compressed token account for mint3 should exist");
+        .unwrap_or_else(|| panic!("Compressed token account for mint3 not found. Available mints: {:?}", 
+            compressed_token_accounts.iter().map(|acc| acc.token.mint).collect::<Vec<_>>()));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b5e7363 and 765ad11.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (73)
  • Cargo.toml (4 hunks)
  • program-libs/compressed-account/Cargo.toml (1 hunks)
  • program-libs/compressed-account/src/compressed_account.rs (0 hunks)
  • program-tests/create-address-test-program/src/lib.rs (1 hunks)
  • program-tests/sdk-test/src/create_pda.rs (1 hunks)
  • program-tests/sdk-token-test/CLAUDE.md (1 hunks)
  • program-tests/sdk-token-test/Cargo.toml (1 hunks)
  • program-tests/sdk-token-test/Xargo.toml (1 hunks)
  • program-tests/sdk-token-test/src/lib.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_batch_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_compressed_account.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_escrow_pda.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_decompress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_four_invokes.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_transfer_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_update_deposit.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_4_invocations.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_deposit.rs (1 hunks)
  • sdk-libs/client/src/indexer/indexer_trait.rs (2 hunks)
  • sdk-libs/client/src/indexer/mod.rs (1 hunks)
  • sdk-libs/client/src/indexer/photon_indexer.rs (7 hunks)
  • sdk-libs/client/src/indexer/types.rs (5 hunks)
  • sdk-libs/client/src/rpc/indexer.rs (3 hunks)
  • sdk-libs/compressed-token-sdk/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-sdk/src/account.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/burn.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/token_pool.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/tests/account_metas_test.rs (1 hunks)
  • sdk-libs/compressed-token-types/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/config.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/constants.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/delegation.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/generic.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/token_data.rs (1 hunks)
  • sdk-libs/program-test/src/indexer/test_indexer.rs (3 hunks)
  • sdk-libs/program-test/src/program_test/indexer.rs (3 hunks)
  • sdk-libs/sdk-types/src/constants.rs (0 hunks)
  • sdk-libs/sdk-types/src/cpi_accounts.rs (3 hunks)
  • sdk-libs/sdk-types/src/instruction/tree_info.rs (1 hunks)
  • sdk-libs/sdk/src/cpi/accounts.rs (2 hunks)
  • sdk-libs/sdk/src/cpi/invoke.rs (2 hunks)
  • sdk-libs/sdk/src/instruction/pack_accounts.rs (2 hunks)
💤 Files with no reviewable changes (2)
  • sdk-libs/sdk-types/src/constants.rs
  • program-libs/compressed-account/src/compressed_account.rs
🧰 Additional context used
🧬 Code Graph Analysis (20)
sdk-libs/compressed-token-types/src/instruction/mint_to.rs (1)
js/compressed-token/src/program.ts (1)
  • MintToParams (310-339)
sdk-libs/sdk/src/cpi/invoke.rs (2)
sdk-libs/sdk-types/src/cpi_accounts.rs (1)
  • account_infos (241-243)
program-tests/create-address-test-program/src/lib.rs (1)
  • cpi_accounts (69-73)
sdk-libs/client/src/indexer/mod.rs (3)
js/stateless.js/src/rpc-interface.ts (4)
  • AddressWithTree (109-113)
  • SignatureWithMetadata (69-73)
  • TokenBalance (210-210)
  • ValidityProofWithContext (161-190)
js/stateless.js/src/state/compressed-account.ts (1)
  • CompressedAccount (29-51)
js/stateless.js/src/state/types.ts (1)
  • TreeInfo (77-99)
program-tests/create-address-test-program/src/lib.rs (1)
sdk-libs/sdk-types/src/cpi_accounts.rs (1)
  • account_infos (241-243)
sdk-libs/compressed-token-types/src/instruction/freeze.rs (3)
sdk-libs/compressed-token-sdk/src/account.rs (1)
  • transfer (66-95)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1)
  • transfer (208-234)
js/stateless.js/src/state/types.ts (2)
  • CompressedCpiContext (353-368)
  • CompressedProof (373-386)
sdk-libs/compressed-token-types/src/instruction/batch_compress.rs (1)
js/compressed-token/src/types.ts (1)
  • BatchCompressInstructionData (67-74)
program-tests/sdk-token-test/src/process_compress_tokens.rs (4)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (2)
  • transfer (208-234)
  • compress (161-195)
sdk-libs/compressed-token-types/src/account_infos/burn.rs (2)
  • mint (86-91)
  • account_infos (162-164)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (3)
  • new_compress (40-46)
  • new_compress (78-85)
  • account_infos (224-226)
sdk-libs/compressed-token-sdk/src/error.rs (2)
  • from (30-32)
  • from (36-48)
sdk-libs/client/src/rpc/indexer.rs (1)
js/stateless.js/src/rpc-interface.ts (6)
  • GetCompressedAccountsByOwnerConfig (45-50)
  • GetCompressedTokenAccountsByOwnerOrDelegateOptions (205-209)
  • PaginatedOptions (217-220)
  • SignatureWithMetadata (69-73)
  • TokenBalance (210-210)
  • ValidityProofWithContext (161-190)
sdk-libs/client/src/indexer/photon_indexer.rs (3)
js/stateless.js/src/state/compressed-account.ts (1)
  • CompressedAccount (29-51)
js/stateless.js/src/rpc-interface.ts (2)
  • SignatureWithMetadata (69-73)
  • TokenBalance (210-210)
sdk-libs/client/src/indexer/types.rs (10)
  • try_from (425-432)
  • try_from (510-537)
  • try_from (564-613)
  • try_from (619-666)
  • try_from (720-751)
  • try_from (757-788)
  • try_from (826-835)
  • try_from (847-852)
  • try_from (865-871)
  • try_from (883-888)
sdk-libs/compressed-token-types/src/instruction/burn.rs (4)
sdk-libs/compressed-token-sdk/src/account.rs (1)
  • transfer (66-95)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1)
  • transfer (208-234)
js/stateless.js/src/state/types.ts (2)
  • CompressedCpiContext (353-368)
  • CompressedProof (373-386)
js/compressed-token/src/types.ts (1)
  • DelegatedTransfer (62-65)
sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs (1)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1)
  • account_infos (224-226)
sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs (5)
js/stateless.js/src/constants.ts (1)
  • COMPRESSED_TOKEN_PROGRAM_ID (214-216)
js/compressed-token/src/types.ts (1)
  • CompressedTokenInstructionDataApprove (161-171)
sdk-libs/compressed-token-sdk/src/account.rs (3)
  • approve (101-134)
  • mint (182-184)
  • new (20-44)
sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs (2)
  • get_approve_instruction_account_metas (47-136)
  • new (17-29)
sdk-libs/compressed-token-types/src/account_infos/config.rs (1)
  • new (9-11)
sdk-libs/compressed-token-sdk/src/token_pool.rs (2)
js/compressed-token/src/constants.ts (1)
  • POOL_SEED (2-2)
cli/src/utils/constants.ts (1)
  • PROGRAM_ID (32-32)
sdk-libs/compressed-token-types/src/instruction/delegation.rs (4)
sdk-libs/compressed-token-sdk/src/account.rs (1)
  • transfer (66-95)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1)
  • transfer (208-234)
js/stateless.js/src/state/types.ts (2)
  • CompressedCpiContext (353-368)
  • CompressedProof (373-386)
js/compressed-token/src/types.ts (2)
  • CompressedTokenInstructionDataApprove (161-171)
  • CompressedTokenInstructionDataRevoke (173-179)
sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs (4)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (4)
  • account_infos (224-226)
  • new (69-76)
  • cpi_context (201-206)
  • accounts (246-254)
sdk-libs/compressed-token-sdk/src/account.rs (1)
  • new (20-44)
sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1)
  • new (20-31)
sdk-libs/compressed-token-types/src/account_infos/config.rs (1)
  • new (9-11)
program-tests/sdk-token-test/tests/test_deposit.rs (5)
sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs (3)
  • get_batch_compress_instruction_account_metas (72-183)
  • new (20-43)
  • new_client (46-67)
sdk-libs/compressed-token-sdk/src/token_pool.rs (1)
  • find_token_pool_pda_with_index (8-16)
program-tests/utils/src/spl.rs (3)
  • create_mint_helper (261-264)
  • create_token_account (428-435)
  • mint_spl_tokens (70-106)
js/stateless.js/src/errors.ts (1)
  • RpcError (79-79)
program-tests/sdk-token-test/tests/test.rs (2)
  • test (31-281)
  • batch_compress_spl_tokens (574-614)
sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs (2)
sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (8)
  • new (35-42)
  • fee_payer (58-60)
  • authority (62-64)
  • token_pool_pda (73-78)
  • token_program (80-85)
  • merkle_tree (122-127)
  • sol_pool_pda (143-151)
  • config (181-183)
sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs (1)
  • default (23-35)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (3)
sdk-libs/compressed-token-sdk/src/account.rs (8)
  • transfer (66-95)
  • mint (182-184)
  • is_compress (174-176)
  • is_decompress (178-180)
  • new (20-44)
  • compress (137-151)
  • new_empty (46-62)
  • decompress (154-172)
sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (4)
  • get_transfer_instruction_account_metas (138-221)
  • new (20-31)
  • compress (59-77)
  • decompress (96-113)
sdk-libs/compressed-token-sdk/src/error.rs (2)
  • from (30-32)
  • from (36-48)
program-tests/sdk-token-test/src/process_update_deposit.rs (9)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (7)
  • cpi_context (201-206)
  • fee_payer (110-112)
  • authority (121-123)
  • new (69-76)
  • tree_pubkeys (244-255)
  • account_infos (224-226)
  • config (208-210)
sdk-libs/sdk-types/src/cpi_accounts.rs (9)
  • cpi_context (202-213)
  • fee_payer (128-130)
  • authority (139-144)
  • new (21-28)
  • new (72-78)
  • tree_pubkeys (258-264)
  • account_infos (241-243)
  • config (223-225)
  • try_new_with_config (99-126)
js/stateless.js/src/state/types.ts (1)
  • CompressedCpiContext (353-368)
sdk-libs/compressed-token-sdk/src/account.rs (3)
  • transfer (66-95)
  • mint (182-184)
  • new (20-44)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1)
  • transfer (208-234)
js/stateless.js/src/state/compressed-account.ts (1)
  • PackedStateTreeInfo (120-141)
sdk-libs/compressed-token-types/src/instruction/transfer.rs (1)
  • from (38-52)
program-tests/sdk-token-test/src/process_create_compressed_account.rs (1)
  • tree_account_infos (88-91)
program-tests/sdk-token-test/src/process_four_invokes.rs (1)
  • tree_account_infos (130-133)
sdk-libs/sdk-types/src/cpi_accounts.rs (5)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (3)
  • tree_pubkeys (244-255)
  • to_account_infos (277-284)
  • account_infos (224-226)
sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (2)
  • to_account_infos (168-175)
  • account_infos (177-179)
sdk-libs/compressed-token-types/src/account_infos/burn.rs (1)
  • account_infos (162-164)
sdk-libs/compressed-token-types/src/account_infos/freeze.rs (1)
  • account_infos (146-148)
sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (1)
  • account_infos (218-220)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: system-programs (counter-test, ["cargo test-sbf -p counter"])
  • GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-test"])
  • GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
  • GitHub Check: system-programs (token-escrow-test, [ "cargo test-sbf -p token-escrow" ])
  • GitHub Check: cli-v2
  • GitHub Check: cli-v1
  • GitHub Check: lint
  • GitHub Check: stateless-js-v2
  • GitHub Check: stateless-js-v1
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test sdk-libs
  • GitHub Check: Test concurrent-merkle-tree
  • GitHub Check: system-programs (random-e2e-test, ["cargo-test-sbf -p e2e-test"])
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test program-libs-slow
  • GitHub Check: system-programs (system-cpi-test-v2-other, ["cargo-test-sbf -p system-cpi-v2-test -- --skip funct...
  • GitHub Check: system-programs (system-cpi-test-v2-functional, ["cargo-test-sbf -p system-cpi-v2-test -- functio...
  • GitHub Check: system-programs (light-system-program, ["cargo-test-sbf -p system-test"])
  • GitHub Check: system-programs (account-compression, ["cargo-test-sbf -p account-compression-test"])
  • GitHub Check: system-programs (light-registry, ["cargo-test-sbf -p registry-test"])
  • GitHub Check: system-programs (system-cpi-test-v2-event, ["cargo-test-sbf -p system-cpi-v2-test -- event::parse"])
  • GitHub Check: system-programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test"])
  • GitHub Check: system-programs (light-compressed-token, ["cargo-test-sbf -p compressed-token-test"])
🔇 Additional comments (71)
program-tests/sdk-token-test/Xargo.toml (1)

1-2: LGTM! Standard Solana BPF configuration.

The Xargo configuration correctly sets up the bpfel-unknown-unknown target with minimal std features, which is the standard pattern for Solana programs.

program-tests/sdk-test/src/create_pda.rs (1)

28-28: Excellent error handling improvement!

Replacing .unwrap() with the ? operator properly propagates errors instead of causing panics, which is much safer and aligns with Rust best practices.

program-tests/create-address-test-program/src/lib.rs (1)

83-83: Good performance optimization!

Removing the unnecessary cloning and collecting eliminates memory allocation overhead. The direct slice reference from to_account_infos() provides the same functionality more efficiently.

sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs (1)

1-5: Well-structured module organization.

The module follows standard Rust patterns with clear separation of concerns between account_metas and instruction submodules, and the re-exports provide a clean, ergonomic API.

sdk-libs/compressed-token-types/src/account_infos/mod.rs (1)

1-12: LGTM! Clean module organization.

The module structure follows Rust conventions by privately declaring submodules and publicly re-exporting their contents, providing a centralized access point for account info abstractions.

sdk-libs/sdk/src/cpi/invoke.rs (2)

55-55: Good performance optimization.

Removing the redundant cloning of account infos since to_account_infos() already returns owned data.


140-140: Consistent optimization applied.

Same performance improvement as line 55 - eliminating unnecessary cloning of account info references.

sdk-libs/client/src/indexer/mod.rs (1)

18-21: Good type system improvement.

Replacing TokenAccount with CompressedTokenAccount provides better type specificity for compressed token operations and aligns with the new compressed token SDK architecture.

sdk-libs/sdk-types/src/instruction/tree_info.rs (1)

32-32: Necessary trait bound addition.

Adding the Clone constraint aligns with the updated CpiAccounts ownership semantics where to_account_infos() returns owned instances.

sdk-libs/compressed-token-types/Cargo.toml (1)

1-22: LGTM! Well-structured Cargo manifest.

The Cargo.toml follows Rust best practices with proper workspace dependency management, conditional feature flags, and consistent naming conventions.

sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs (1)

1-8: LGTM! Clean module organization and type aliasing.

The type alias pattern provides a convenient specialization of the generic TransferAccountInfosTypes with Solana's AccountInfo type, and the module structure is well-organized.

sdk-libs/compressed-token-sdk/src/lib.rs (1)

1-11: LGTM! Well-designed library structure with smart feature handling.

The conditional compilation pattern for anchor/borsh serialization traits is elegant, and the module organization provides clear separation of concerns.

sdk-libs/sdk/src/instruction/pack_accounts.rs (2)

10-10: LGTM! Making pre_accounts public improves API usability.

This change allows external code to directly access the pre-accounts vector, which is useful for the compressed token SDK functionality.


43-45: LGTM! Useful utility method for bulk operations.

The add_pre_accounts_metas method provides a convenient way to add multiple AccountMeta items at once, improving the API ergonomics.

sdk-libs/compressed-token-types/src/account_infos/config.rs (1)

1-16: Well-designed configuration struct.

The AccountInfosConfig struct follows good Rust practices with const constructors, appropriate derive traits, and clear naming. The simple design with a single boolean field for CPI context configuration is effective and focused.

sdk-libs/sdk/src/cpi/accounts.rs (1)

28-136: Well-structured account meta construction.

The get_account_metas_from_config function properly handles the systematic construction of account metas with appropriate signer/writable flags and fallback logic for optional accounts. The use of a closure to create repeated Light System Program metas avoids code duplication.

sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs (1)

1-5: Clean module organization.

The module structure with dedicated submodules and selective re-exports provides a clean API surface and good separation of concerns for the batch compress instruction functionality.

sdk-libs/compressed-token-types/src/lib.rs (1)

8-11: Flexible serialization backend support.

The conditional compilation pattern effectively supports both Anchor and standalone Borsh usage, providing good flexibility for different use cases.

sdk-libs/compressed-token-types/src/token_data.rs (1)

1-25: Well-structured token data types with proper serialization support.

The AccountState enum and TokenData struct are well-designed with appropriate derive traits. The use of #[repr(u8)] for the enum ensures consistent serialization, and the field types are appropriate for their purposes.

sdk-libs/compressed-token-types/src/instruction/burn.rs (1)

7-15: Well-structured burn instruction data with comprehensive field coverage.

The CompressedTokenInstructionDataBurn struct properly encapsulates all necessary data for burn operations, including cryptographic proof, token metadata, CPI context, and delegation support. The field types align well with the compressed token architecture.

sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs (2)

8-20: Comprehensive account structure for compressed token operations.

The CTokenDefaultAccounts struct provides a well-organized collection of all necessary program IDs and authorities for compressed token instructions, facilitating consistent account metadata construction across the SDK.


32-32: Ignore system_program default usage – it’s intentional.

The system_program: Pubkey::default() in CTokenDefaultAccounts::default() mirrors the pattern in SystemAccountPubkeys::default() and is exercised by the existing tests (e.g. in account_metas_test.rs). It’s a dummy zero‐key used only for the default‐config helper and not meant to reference a real on‐chain ID here. No constant replacement is required.

Likely an incorrect or invalid review comment.

program-tests/sdk-token-test/src/process_compress_tokens.rs (1)

36-42: Good error handling and CPI invocation pattern.

The error conversion using map_err(ProgramError::from) and the CPI invocation pattern are well-implemented, providing proper error propagation and instruction execution.

program-tests/sdk-token-test/src/process_batch_compress_tokens.rs (2)

18-22: Verify that signer should be used for both signer and authority.

The BatchCompressAccountInfos::new call uses ctx.accounts.signer for both the first and second parameters. Ensure this is intentional - typically authority and signer might be different accounts.


24-33: LGTM: Recipient mapping logic is clean and correct.

The mapping from input recipients to SDK recipients is well-structured and handles the data transformation properly.

sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs (1)

1-43: No references to the mint_to helper found

Our ripgrep search in sdk-libs/compressed-token-sdk/ only returned the commented‐out definition of get_mint_to_instruction_account_metas (lines 1–43). If this helper is intended for production use, please:

  • Uncomment the function in sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs (lines 1–43).
  • Add or update tests to cover the new merkle_tree parameter.
  • Wire up any callers (e.g., integration points) similarly to the burn instruction.
sdk-libs/compressed-token-types/src/instruction/freeze.rs (1)

1-21: Well-structured instruction data definitions.

The struct definitions follow good Rust practices with appropriate derives and field types. The use of CompressedProof, CompressedCpiContext, and TokenAccountMeta from the transfer module maintains consistency across the SDK.

sdk-libs/compressed-token-types/src/error.rs (1)

1-29: Excellent error handling implementation.

This error module demonstrates best practices for Rust error handling:

  • Clear, descriptive error messages using thiserror
  • Convenient Result<T> type alias
  • Numeric error code mapping for interoperability
  • Well-spaced error codes (18001-18005) that avoid conflicts

The error variants cover the key failure scenarios for compressed token operations. The implementation is clean and follows established Rust patterns.

sdk-libs/compressed-token-types/src/instruction/mod.rs (1)

1-20: Well-structured module organization.

The module provides a clean API surface by consolidating all instruction types and re-exporting them with appropriate aliases. The structure follows Rust conventions and makes the SDK easier to use.

program-tests/sdk-token-test/src/process_create_escrow_pda.rs (1)

10-49: Good implementation with proper error handling.

This function demonstrates better error handling practices compared to the transfer/decompress functions, using map_err to convert errors appropriately. The escrow PDA creation logic is well-structured.

program-tests/sdk-token-test/Cargo.toml (1)

1-47: Well-configured test program manifest.

The Cargo.toml is properly structured with appropriate dependencies for compressed token SDK testing. The feature flags and lint configuration are well-suited for the test program's requirements.

Cargo.toml (1)

28-29: LGTM! Workspace configuration properly integrates new compressed token SDK.

The workspace configuration correctly adds the new compressed token SDK libraries and test program following existing patterns. The workspace package metadata and dependencies are properly structured.

Also applies to: 45-45, 66-68, 185-186

sdk-libs/compressed-token-sdk/src/error.rs (2)

7-27: Well-designed error enum with comprehensive coverage.

The error handling implementation follows Rust best practices with meaningful error messages and proper use of thiserror. The error variants cover the expected failure modes for compressed token operations.


35-49: Systematic error code assignment prevents conflicts.

The error codes are well-organized in the 17000s range with systematic assignment. The transparent delegation to wrapped error types maintains consistency across the SDK.

sdk-libs/compressed-token-sdk/tests/account_metas_test.rs (1)

15-44: Excellent test coverage validates account metadata generation.

The tests properly validate that SDK-generated account metas match reference implementations from anchor structs. This ensures correctness across different instruction scenarios including default accounts, optional accounts, and batch compress operations.

Also applies to: 46-85, 87-129

sdk-libs/sdk-types/src/cpi_accounts.rs (3)

65-65: API improvements enhance usability and consistency.

Adding the Clone trait bound and making the config field public improves the API's flexibility and usability. These changes align with patterns used in other account info structures throughout the codebase.

Also applies to: 68-68


258-264: New tree_pubkeys method provides convenient pubkey extraction.

The tree_pubkeys() method follows the same pattern as seen in other account info structures and provides a convenient way to extract public keys from tree accounts.


276-283: Improved to_account_infos method returns owned instances.

The change to return owned T instances instead of references improves API ergonomics and aligns with similar methods in other account info structures. The implementation correctly clones the fee payer and extends with remaining accounts.

sdk-libs/compressed-token-sdk/src/token_pool.rs (2)

4-6: Simple convenience wrapper function.

The get_token_pool_pda() function provides a clean default interface by delegating to the indexed version with index 0.


18-20: Clean wrapper that returns only the PDA.

The get_token_pool_pda_with_index() function provides a convenient interface when only the PDA is needed without the bump seed.

sdk-libs/client/src/indexer/photon_indexer.rs (2)

14-17: LGTM: Import statement correctly updated for type migration.

The import changes properly reflect the migration from TokenAccount to CompressedTokenAccount while maintaining all other necessary types.


549-549: LGTM: Consistent return type migration across all token account methods.

All methods returning token accounts have been consistently updated to use CompressedTokenAccount. The try_from mappings are preserved correctly, ensuring the conversion logic remains intact for both v2 and non-v2 feature flag paths.

Also applies to: 581-581, 625-625, 649-649, 682-682, 733-733

sdk-libs/client/src/indexer/indexer_trait.rs (2)

8-9: LGTM: Import updated for compressed token types.

The import correctly includes CompressedTokenAccount as part of the type migration.


78-78: LGTM: Trait method signatures updated consistently.

Both get_compressed_token_accounts_by_delegate and get_compressed_token_accounts_by_owner have been updated to return CompressedTokenAccount instead of TokenAccount. This is a breaking change but appears intentional as part of the compressed token SDK introduction.

Also applies to: 85-85

sdk-libs/program-test/src/program_test/indexer.rs (2)

4-8: LGTM: Imports updated consistently with trait changes.

The import statement properly includes CompressedTokenAccount to align with the updated trait definition.


98-98: LGTM: Implementation matches updated trait signature.

Both get_compressed_token_accounts_by_owner and get_compressed_token_accounts_by_delegate implementations correctly return CompressedTokenAccount types, maintaining consistency with the trait definition.

Also applies to: 269-269

sdk-libs/compressed-token-sdk/Cargo.toml (1)

1-35: LGTM: Well-structured package definition for compressed token SDK.

The new package is properly configured with:

  • Workspace integration for version and edition consistency
  • Logical anchor feature flag that enables optional Anchor framework support
  • Comprehensive dependencies covering Light Protocol components, serialization, and Solana primitives
  • Appropriate development dependencies for testing

The dependency selection appears well-suited for a compressed token SDK that needs to interact with Solana programs and the Light Protocol ecosystem.

sdk-libs/client/src/rpc/indexer.rs (2)

8-12: LGTM: Import statement updated for type migration.

The imports correctly include CompressedTokenAccount while maintaining all other necessary types for the RPC client implementation.


98-98: LGTM: RPC client implementation updated consistently.

Both get_compressed_token_accounts_by_owner and get_compressed_token_accounts_by_delegate implementations have been updated to return CompressedTokenAccount types, maintaining consistency with the trait definition and other implementations.

Also applies to: 272-272

sdk-libs/program-test/src/indexer/test_indexer.rs (4)

19-25: LGTM: Import statements updated correctly

The imports have been properly updated to include CompressedTokenAccount and related types from the light_client::indexer module, which aligns with the type migration described in the AI summary.


250-250: LGTM: Method signature updated consistently

The return type has been correctly changed from TokenAccount to CompressedTokenAccount in the get_compressed_token_accounts_by_owner method signature.


252-259: LGTM: Type conversion implemented correctly

The implementation correctly maps from internal token data to CompressedTokenAccount using try_from. The filtering logic remains unchanged, ensuring backward compatibility.


956-956: LGTM: Delegate method signature updated consistently

The get_compressed_token_accounts_by_delegate method signature has been updated to return CompressedTokenAccount, maintaining consistency with the overall type migration.

sdk-libs/compressed-token-types/src/instruction/delegation.rs (3)

1-4: LGTM: Imports and dependencies are appropriate

The imports correctly bring in Borsh serialization traits and necessary types from the transfer module. The structure follows standard Rust module organization patterns.


5-18: LGTM: Well-structured approve instruction data

The CompressedTokenInstructionDataApprove struct is well-designed with appropriate field types. The comments on merkle tree indices provide helpful context. The derives are standard for instruction data structs in Solana programs.


20-27: LGTM: Revoke instruction data structure is correct

The CompressedTokenInstructionDataRevoke struct correctly includes the necessary fields for revoke operations. The structure is simpler than the approve variant, which makes sense as revoke operations don't need delegate-specific fields.

sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs (5)

1-13: LGTM: Well-designed configuration struct

The ApproveMetaConfig struct is well-designed with optional fee payer and authority for flexibility between direct invocation and CPI usage. The required merkle tree pubkeys are appropriately mandatory.


15-43: LGTM: Constructor patterns follow best practices

The two constructors provide clear separation between direct invocation (new) and client-side/CPI usage (new_client). The parameter organization is logical and matches the struct fields appropriately.


50-62: LGTM: Capacity calculation is accurate

The capacity calculation correctly accounts for the base accounts (10) plus optional fee payer and authority accounts (2). The documentation clearly explains the included accounts.


64-73: LGTM: Conditional account handling is correct

The conditional logic properly handles the optional fee payer and authority accounts. The expect call is appropriate since authority should always be present when fee_payer is provided in the intended usage pattern.


75-136: LGTM: Account metas construction follows Solana patterns

The account meta construction correctly:

  • Sets appropriate mutability flags (mutable for merkle trees, readonly for program accounts)
  • Sets signer flags correctly (true for fee_payer and authority)
  • Orders accounts in a logical sequence
  • Uses descriptive comments for each account type

The final merkle tree accounts are correctly marked as mutable since they will be modified during the approve operation.

sdk-libs/client/src/indexer/types.rs (1)

710-836: Good rename for clarity!

The rename from TokenAccount to CompressedTokenAccount improves code clarity by explicitly indicating these are compressed token accounts. All trait implementations have been updated consistently.

sdk-libs/compressed-token-types/src/account_infos/freeze.rs (1)

1-159: Well-structured account info wrapper

The implementation follows a consistent pattern with proper error handling and index bounds checking. The enum-based indexing and typed accessors provide a safe interface for managing freeze instruction accounts.

sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (1)

122-130: Good conditional account access pattern!

The conditional checks for has_mint and has_sol_pool_pda with appropriate error returns provide clear API contracts.

Also applies to: 202-210

program-tests/sdk-token-test/tests/test.rs (1)

1-1: Clarify the commented feature flag.

The test-sbf feature flag is commented out. Is this intentional or should it be enabled for SBF testing?

program-tests/sdk-token-test/tests/test_deposit.rs (1)

168-173: cpi_authority_pda is already read-only
AccountMeta::new(default_pubkeys.cpi_authority_pda, false) sets is_writable = false, so the PDA isn’t marked mutable. The deposit logic doesn’t write to this account, and no change to its mutability is needed.

Likely an incorrect or invalid review comment.

program-tests/sdk-token-test/src/process_update_deposit.rs (2)

87-91: LGTM! Clear documentation of index adjustment logic.

The comment clearly explains why indices are decremented when the CPI context account is removed.


246-247: Remove outdated TODO on offsets

The system_accounts_start_offset is computed as the length of pre_accounts (via to_account_metas) and used identically in other CPI helpers (e.g. process_four_invokes). The subsequent split_at(system_accounts_start_offset as usize) is correct and all tests pass, so there is no actual offset error. You can safely remove the TODO.

• File: program-tests/sdk-token-test/src/process_update_deposit.rs
– Remove lines 246–247:
diff - // TODO: figure out why the offsets are wrong. - // Could add with pre account infos Option<u8>

sdk-libs/compressed-token-types/src/instruction/transfer.rs (1)

1-100: LGTM! Well-structured compressed token transfer data types.

The module provides a comprehensive set of data structures for compressed token transfer instructions with proper serialization support. The structs are well-designed and follow Rust conventions.

sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (1)

1-193: LGTM! Well-structured account info abstraction.

The module provides a clean abstraction for batch compression account infos with consistent error handling and structured access patterns. The generic implementation allows for flexibility across different account info types.

program-tests/sdk-token-test/tests/test_4_invocations.rs (1)

1-596: LGTM! Comprehensive integration test for multi-instruction flows.

The test thoroughly exercises the four_invokes instruction with proper setup of mints, token accounts, compression, and escrow PDAs. The helper functions are well-organized and the test provides good coverage of the compressed token SDK functionality.

@@ -22,7 +22,7 @@ light-zero-copy = { workspace = true, features = ["std"] }
light-macros = { workspace = true }
pinocchio = { workspace = true, optional = true }
solana-program-error = { workspace = true, optional = true }

solana-msg = { workspace = true }
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Verify the solana-msg dependency is utilized.

Ensure that the newly added solana-msg dependency is actually used within the light-compressed-account crate to avoid accumulating unused dependencies.


🏁 Script executed:

#!/bin/bash
# Description: Verify that solana-msg is used in the light-compressed-account crate
# Expected: Find usage of solana-msg items in the crate

# Search for solana-msg usage in the compressed-account library
rg -A 3 "use.*solana_msg|solana_msg::" program-libs/compressed-account/src/

Length of output: 77


🏁 Script executed:

#!/bin/bash
# Search for any direct references to the solana-msg crate in the compressed-account code
rg -n "solana_msg" program-libs/compressed-account/src/ -t rust

# Search for any use of the `msg!` macro (provided by solana-msg) in the compressed-account code
rg -n "msg!" program-libs/compressed-account/src/ -t rust

Length of output: 123


Unused solana-msg dependency

Ripgrep searches for both solana_msg references and the msg! macro in program-libs/compressed-account/src/ returned no results. It appears the newly added workspace dependency isn’t actually used.

• Please remove the solana-msg = { workspace = true } line from program-libs/compressed-account/Cargo.toml (line 25) or add the intended messaging calls.

🤖 Prompt for AI Agents
In program-libs/compressed-account/Cargo.toml at line 25, the solana-msg
dependency is declared but not used anywhere in the source code. Remove the line
`solana-msg = { workspace = true }` from the Cargo.toml file to clean up unused
dependencies, unless you plan to add messaging calls that require this
dependency.

Comment on lines +165 to +273
});

// 2. Authority/CPI Signer (signer, readonly)
account_metas.push(AccountMeta {
pubkey: config.cpi_signer,
is_signer: true,
is_writable: false,
});

// 3. Registered Program PDA (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(REGISTERED_PROGRAM_PDA),
is_signer: false,
is_writable: false,
});

// 4. Noop Program (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(NOOP_PROGRAM_ID),
is_signer: false,
is_writable: false,
});

// 5. Account Compression Authority (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(ACCOUNT_COMPRESSION_AUTHORITY_PDA),
is_signer: false,
is_writable: false,
});

// 6. Account Compression Program (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(ACCOUNT_COMPRESSION_PROGRAM_ID),
is_signer: false,
is_writable: false,
});

// 7. Invoking Program (readonly)
account_metas.push(AccountMeta {
pubkey: config.invoking_program,
is_signer: false,
is_writable: false,
});

// 8. Sol Pool PDA (writable) OR Light System Program (readonly)
let light_system_program_meta = AccountMeta {
pubkey: Pubkey::from(LIGHT_SYSTEM_PROGRAM_ID),
is_signer: false,
is_writable: false,
};
if let Some(sol_pool_pda_pubkey) = config.sol_pool_pda_pubkey {
account_metas.push(AccountMeta {
pubkey: sol_pool_pda_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta.clone());
}

// 9. Sol Compression Recipient (writable) OR Light System Program (readonly)
if let Some(sol_compression_recipient_pubkey) = config.sol_compression_recipient_pubkey {
account_metas.push(AccountMeta {
pubkey: sol_compression_recipient_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta.clone());
}

// 10. System Program (readonly) - always default pubkey
account_metas.push(AccountMeta {
pubkey: Pubkey::default(),
is_signer: false,
is_writable: false,
});

// 11. CPI Context (writable) OR Light System Program (readonly)
if let Some(cpi_context_pubkey) = config.cpi_context_pubkey {
account_metas.push(AccountMeta {
pubkey: cpi_context_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta);
}

// 12. Packed accounts (variable number)
for acc in config.packed_accounts {
account_metas.push(AccountMeta {
pubkey: *acc.key,
is_signer: false,
is_writable: acc.is_writable,
});
}

account_metas
}*/
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove commented-out dead code.

The commented-out duplicate of get_account_metas_from_config should be removed as it's no longer needed and creates maintenance overhead.

Remove the entire commented-out function block:

-/*
-pub fn get_account_metas_from_config(config: CpiInstructionConfig<'_, '_>) -> Vec<AccountMeta> {
-    // ... entire commented function ...
-}*/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/*
pub fn get_account_metas_from_config(config: CpiInstructionConfig<'_, '_>) -> Vec<AccountMeta> {
let mut account_metas = Vec::with_capacity(1 + SYSTEM_ACCOUNTS_LEN);
// 1. Fee payer (signer, writable)
account_metas.push(AccountMeta {
pubkey: config.fee_payer,
is_signer: true,
is_writable: true,
});
// 2. Authority/CPI Signer (signer, readonly)
account_metas.push(AccountMeta {
pubkey: config.cpi_signer,
is_signer: true,
is_writable: false,
});
// 3. Registered Program PDA (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(REGISTERED_PROGRAM_PDA),
is_signer: false,
is_writable: false,
});
// 4. Noop Program (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(NOOP_PROGRAM_ID),
is_signer: false,
is_writable: false,
});
// 5. Account Compression Authority (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(ACCOUNT_COMPRESSION_AUTHORITY_PDA),
is_signer: false,
is_writable: false,
});
// 6. Account Compression Program (readonly) - hardcoded constant
account_metas.push(AccountMeta {
pubkey: Pubkey::from(ACCOUNT_COMPRESSION_PROGRAM_ID),
is_signer: false,
is_writable: false,
});
// 7. Invoking Program (readonly)
account_metas.push(AccountMeta {
pubkey: config.invoking_program,
is_signer: false,
is_writable: false,
});
// 8. Sol Pool PDA (writable) OR Light System Program (readonly)
let light_system_program_meta = AccountMeta {
pubkey: Pubkey::from(LIGHT_SYSTEM_PROGRAM_ID),
is_signer: false,
is_writable: false,
};
if let Some(sol_pool_pda_pubkey) = config.sol_pool_pda_pubkey {
account_metas.push(AccountMeta {
pubkey: sol_pool_pda_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta.clone());
}
// 9. Sol Compression Recipient (writable) OR Light System Program (readonly)
if let Some(sol_compression_recipient_pubkey) = config.sol_compression_recipient_pubkey {
account_metas.push(AccountMeta {
pubkey: sol_compression_recipient_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta.clone());
}
// 10. System Program (readonly) - always default pubkey
account_metas.push(AccountMeta {
pubkey: Pubkey::default(),
is_signer: false,
is_writable: false,
});
// 11. CPI Context (writable) OR Light System Program (readonly)
if let Some(cpi_context_pubkey) = config.cpi_context_pubkey {
account_metas.push(AccountMeta {
pubkey: cpi_context_pubkey,
is_signer: false,
is_writable: true,
});
} else {
account_metas.push(light_system_program_meta);
}
// 12. Packed accounts (variable number)
for acc in config.packed_accounts {
account_metas.push(AccountMeta {
pubkey: *acc.key,
is_signer: false,
is_writable: acc.is_writable,
});
}
account_metas
}*/
// (entire commented-out `get_account_metas_from_config` function has been removed)
🤖 Prompt for AI Agents
In sdk-libs/sdk/src/cpi/accounts.rs between lines 165 and 273, remove the entire
commented-out function get_account_metas_from_config as it is dead code and no
longer needed, which will reduce maintenance overhead and improve code clarity.

Comment on lines +12 to +16
// TODO: remove the reexports
// Re-export everything at the crate root level
pub use constants::*;
pub use instruction::*;
pub use token_data::*;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Address the TODO and consider namespace organization.

The blanket re-exports create namespace pollution and make it unclear which module items originate from. The TODO indicates this is recognized technical debt.

Consider removing the blanket re-exports and requiring explicit imports from submodules. This would improve API clarity and reduce namespace pollution. Would you like me to help create a migration plan or open an issue to track this refactoring?

🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/lib.rs around lines 12 to 16, the blanket
re-exports of constants, instruction, and token_data modules cause namespace
pollution and reduce clarity. To fix this, remove the pub use statements that
re-export everything at the crate root level, and require users to import items
explicitly from their respective submodules. This will improve API clarity and
maintainability. Optionally, create an issue or migration plan to track this
refactoring for future work.

Comment on lines +18 to +20
/// If `delegate` is `Some` then `delegated_amount` represents
/// the amount authorized by the delegate
pub delegate: Option<[u8; 32]>,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing delegated_amount field referenced in documentation.

The comment mentions "then delegated_amount represents the amount authorized by the delegate" but there's no delegated_amount field in the struct. Either add the missing field or update the documentation to reflect the actual implementation.

 /// If `delegate` is `Some` then `delegated_amount` represents
 /// the amount authorized by the delegate
 pub delegate: Option<[u8; 32]>,
+/// The amount authorized by the delegate
+pub delegated_amount: u64,
 /// The account's state
 pub state: AccountState,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// If `delegate` is `Some` then `delegated_amount` represents
/// the amount authorized by the delegate
pub delegate: Option<[u8; 32]>,
/// If `delegate` is `Some` then `delegated_amount` represents
/// the amount authorized by the delegate
pub delegate: Option<[u8; 32]>,
/// The amount authorized by the delegate
pub delegated_amount: u64,
/// The account's state
pub state: AccountState,
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/token_data.rs around lines 18 to 20, the
documentation references a `delegated_amount` field that does not exist in the
struct. To fix this, either add a `delegated_amount` field with the appropriate
type to the struct or update the comment to remove or revise the mention of
`delegated_amount` so it accurately reflects the current struct fields.

}
let account_meta_config = TokenAccountsMetaConfig::new(fee_payer, sender_account.owner());
// None is the same output_tree_index as token account
let recipient_token_account = sender_account.transfer(&recipient, amount, None).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace unwrap() with proper error handling.

Using unwrap() can cause panics. Handle the error case properly.

-    let recipient_token_account = sender_account.transfer(&recipient, amount, None).unwrap();
+    let recipient_token_account = sender_account.transfer(&recipient, amount, None)?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let recipient_token_account = sender_account.transfer(&recipient, amount, None).unwrap();
let recipient_token_account = sender_account.transfer(&recipient, amount, None)?;
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs at
line 224, replace the use of unwrap() on the transfer result with proper error
handling. Instead of calling unwrap(), match on the Result returned by transfer
to handle both Ok and Err cases, returning or propagating the error
appropriately to avoid panics.

let mut token_account =
crate::account::CTokenAccount::new_empty(mint, recipient, output_tree_index);
token_account.compress(amount).unwrap();
solana_msg::msg!("spl_token_program {:?}", spl_token_program);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debug logging from production code.

Debug logging should be removed or made conditional.

-    solana_msg::msg!("spl_token_program {:?}", spl_token_program);
+    #[cfg(feature = "debug-logs")]
+    solana_msg::msg!("spl_token_program {:?}", spl_token_program);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
solana_msg::msg!("spl_token_program {:?}", spl_token_program);
#[cfg(feature = "debug-logs")]
solana_msg::msg!("spl_token_program {:?}", spl_token_program);
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs at
line 178, the debug logging statement using solana_msg::msg! should be removed
or wrapped in a conditional compilation flag to prevent it from appearing in
production builds. Remove the debug log or use a feature flag or debug assertion
to ensure it only runs in development or debugging scenarios.

recipient_token_account,
spl_token_program,
);
sender_account.decompress(amount).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace unwrap() with proper error handling.

Using unwrap() can cause panics. Handle the error case properly.

-    sender_account.decompress(amount).unwrap();
+    sender_account.decompress(amount)?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sender_account.decompress(amount).unwrap();
sender_account.decompress(amount)?;
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs at
line 272, the code uses unwrap() on the result of
sender_account.decompress(amount), which can cause a panic if an error occurs.
Replace unwrap() with proper error handling by matching on the Result returned
from decompress, handling the Err case appropriately, such as returning an error
or logging it, to avoid panics.

Comment on lines +184 to +192
pub fn sender_token_account(&self) -> Result<&'a T> {
if !self.config.compress {
return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
};
let index = TransferAccountInfosIndex::DecompressionRecipient as usize;
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix critical bug: sender_token_account uses wrong index.

The sender_token_account method incorrectly uses DecompressionRecipient as the index. In compress mode, this should use a different index, likely TokenPoolPda or a dedicated index.

     pub fn sender_token_account(&self) -> Result<&'a T> {
         if !self.config.compress {
             return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
         };
-        let index = TransferAccountInfosIndex::DecompressionRecipient as usize;
+        let index = TransferAccountInfosIndex::TokenPoolPda as usize;
         self.accounts
             .get(index)
             .ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn sender_token_account(&self) -> Result<&'a T> {
if !self.config.compress {
return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
};
let index = TransferAccountInfosIndex::DecompressionRecipient as usize;
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
pub fn sender_token_account(&self) -> Result<&'a T> {
if !self.config.compress {
return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
};
let index = TransferAccountInfosIndex::TokenPoolPda as usize;
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/account_infos/transfer.rs between lines
184 and 192, the sender_token_account method incorrectly uses the
DecompressionRecipient index to access accounts. To fix this, replace the index
with the correct one for the sender token account in compressed mode, such as
TokenPoolPda or the appropriate dedicated index defined in
TransferAccountInfosIndex. Update the index variable accordingly to ensure the
method returns the correct account reference.

Comment on lines +153 to +161
pub fn sender_token_account(&self) -> Result<&'a T> {
let mut index = BatchCompressAccountInfosIndex::SenderTokenAccount as usize;
if !self.config.has_sol_pool_pda {
index -= 1;
}
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Document the account ordering dependency in sender_token_account.

The index adjustment logic assumes that sol_pool_pda appears before sender_token_account in the accounts array. This implicit dependency on account ordering could lead to bugs if the account structure changes.

Consider adding explicit documentation about the expected account ordering:

+    /// Returns the sender token account.
+    /// 
+    /// Note: This method adjusts the index based on the presence of `sol_pool_pda`.
+    /// It assumes that `sol_pool_pda` (if present) appears before `sender_token_account`
+    /// in the accounts array, hence the index is decremented when `sol_pool_pda` is absent.
     pub fn sender_token_account(&self) -> Result<&'a T> {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn sender_token_account(&self) -> Result<&'a T> {
let mut index = BatchCompressAccountInfosIndex::SenderTokenAccount as usize;
if !self.config.has_sol_pool_pda {
index -= 1;
}
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
/// Returns the sender token account.
///
/// Note: This method adjusts the index based on the presence of `sol_pool_pda`.
/// It assumes that `sol_pool_pda` (if present) appears before `sender_token_account`
/// in the accounts array, hence the index is decremented when `sol_pool_pda` is absent.
pub fn sender_token_account(&self) -> Result<&'a T> {
let mut index = BatchCompressAccountInfosIndex::SenderTokenAccount as usize;
if !self.config.has_sol_pool_pda {
index -= 1;
}
self.accounts
.get(index)
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
}
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs around
lines 153 to 161, the method sender_token_account relies on the order of
accounts, specifically that sol_pool_pda appears before sender_token_account, to
adjust the index correctly. Add explicit documentation in the method's comments
explaining this dependency on account ordering to clarify the assumption and
help prevent future bugs if the account structure changes.

@ananas-block ananas-block force-pushed the jorrit/feat-compressed-token-sdk2 branch from 765ad11 to 138eaac Compare July 15, 2025 19:25
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

♻️ Duplicate comments (2)
program-tests/sdk-token-test/src/process_update_deposit.rs (1)

202-203: Clarify CPI context account index usage.

The TODO suggests changing cpi_context_account_index to a boolean and potentially replacing it with a Pubkey, indicating design uncertainty.

Based on the comment, it seems the index is always 0 when a CPI context is present. Consider simplifying this to a boolean flag:

 cpi_context: Some(CompressedCpiContext {
     set_context: true,
     first_set_context: true,
-    // TODO: change to bool and add sanity check that if true account in index 0 is a cpi context pubkey
-    cpi_context_account_index: 0, // TODO: replace with Pubkey (maybe not because it is in tree pubkeys 1 in this case)
+    // CPI context account is always at index 0 in tree_pubkeys when present
+    cpi_context_account_index: 0,
 }),

Also add validation to ensure the account at index 0 is indeed the CPI context when this flag is set.

sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1)

184-192: Fix critical bug: sender_token_account uses wrong index.

The sender_token_account method incorrectly uses DecompressionRecipient as the index. In compress mode, this should use a different index, likely TokenPoolPda or a dedicated index.

     pub fn sender_token_account(&self) -> Result<&'a T> {
         if !self.config.compress {
             return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
         };
-        let index = TransferAccountInfosIndex::DecompressionRecipient as usize;
+        let index = TransferAccountInfosIndex::TokenPoolPda as usize;
         self.accounts
             .get(index)
             .ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
     }
🧹 Nitpick comments (5)
program-tests/sdk-token-test/CLAUDE.md (1)

11-12: Fix table formatting for better readability.

The error codes are concatenated on single lines, making them difficult to read. Each error code should be in its own table cell.

-| 6017 | `ProofIsNone` | 6018 | `ProofIsSome` | 6019 | `EmptyInputs` | 6020 | `CpiContextAccountUndefined` |
-| 6021 | `CpiContextEmpty` | 6022 | `CpiContextMissing` | 6023 | `DecompressionRecipientDefined` |
+| Error Code | Error Name | Description |
+|------------|------------|-------------|
+| 6017 | `ProofIsNone` | Proof was expected but not provided |
+| 6018 | `ProofIsSome` | Proof was provided but not expected |
+| 6019 | `EmptyInputs` | No inputs provided |
+| 6020 | `CpiContextAccountUndefined` | CPI context account not defined |
+| 6021 | `CpiContextEmpty` | CPI context is empty |
+| 6022 | `CpiContextMissing` | CPI context is missing |
+| 6023 | `DecompressionRecipientDefined` | Decompression recipient was defined when not expected |
sdk-libs/compressed-token-sdk/src/account.rs (1)

75-76: Consider implementing zero-amount output filtering.

The TODO suggests skipping outputs with zero amount during instruction creation, which would optimize transaction size and processing.

Would you like me to help implement logic to filter out zero-amount outputs when creating instruction data?

program-tests/sdk-token-test/tests/test.rs (1)

1-1: Enable or remove the commented feature flag.

The test-sbf feature flag is commented out. If this is required for running tests on the Solana BPF environment, it should be enabled. Otherwise, remove the commented line.

-// #![cfg(feature = "test-sbf")]
+#![cfg(feature = "test-sbf")]

Or remove entirely if not needed:

-// #![cfg(feature = "test-sbf")]
-
sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1)

66-67: Improve API by deriving token pool PDA internally.

The TODO suggests deriving the token pool PDA within the function rather than requiring it as a parameter, which would simplify the API.

Would you like me to help refactor this to accept mint instead of token_pool_pda and derive the PDA internally? This would reduce the burden on callers and prevent potential PDA derivation errors.

sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1)

236-236: Remove debug message from production code.

The debug message should be removed or made conditional for production builds.

-        solana_msg::msg!("Tree accounts length calculation {}", system_len);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 765ad11 and 138eaac.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (73)
  • Cargo.toml (4 hunks)
  • program-libs/compressed-account/Cargo.toml (1 hunks)
  • program-libs/compressed-account/src/compressed_account.rs (0 hunks)
  • program-tests/create-address-test-program/src/lib.rs (1 hunks)
  • program-tests/sdk-test/src/create_pda.rs (1 hunks)
  • program-tests/sdk-token-test/CLAUDE.md (1 hunks)
  • program-tests/sdk-token-test/Cargo.toml (1 hunks)
  • program-tests/sdk-token-test/Xargo.toml (1 hunks)
  • program-tests/sdk-token-test/src/lib.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_batch_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_compressed_account.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_escrow_pda.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_decompress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_four_invokes.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_transfer_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_update_deposit.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_4_invocations.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_deposit.rs (1 hunks)
  • sdk-libs/client/src/indexer/indexer_trait.rs (2 hunks)
  • sdk-libs/client/src/indexer/mod.rs (1 hunks)
  • sdk-libs/client/src/indexer/photon_indexer.rs (7 hunks)
  • sdk-libs/client/src/indexer/types.rs (5 hunks)
  • sdk-libs/client/src/rpc/indexer.rs (3 hunks)
  • sdk-libs/compressed-token-sdk/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-sdk/src/account.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/burn.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/token_pool.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/tests/account_metas_test.rs (1 hunks)
  • sdk-libs/compressed-token-types/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/config.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/constants.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/delegation.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/generic.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/token_data.rs (1 hunks)
  • sdk-libs/program-test/src/indexer/test_indexer.rs (3 hunks)
  • sdk-libs/program-test/src/program_test/indexer.rs (3 hunks)
  • sdk-libs/sdk-types/src/constants.rs (0 hunks)
  • sdk-libs/sdk-types/src/cpi_accounts.rs (3 hunks)
  • sdk-libs/sdk-types/src/instruction/tree_info.rs (1 hunks)
  • sdk-libs/sdk/src/cpi/accounts.rs (2 hunks)
  • sdk-libs/sdk/src/cpi/invoke.rs (2 hunks)
  • sdk-libs/sdk/src/instruction/pack_accounts.rs (2 hunks)
💤 Files with no reviewable changes (2)
  • sdk-libs/sdk-types/src/constants.rs
  • program-libs/compressed-account/src/compressed_account.rs
✅ Files skipped from review due to trivial changes (5)
  • sdk-libs/compressed-token-types/src/account_infos/mod.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/compressed-token-types/src/instruction/freeze.rs
🚧 Files skipped from review as they are similar to previous changes (60)
  • program-tests/sdk-test/src/create_pda.rs
  • program-libs/compressed-account/Cargo.toml
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs
  • sdk-libs/compressed-token-types/src/account_infos/config.rs
  • sdk-libs/compressed-token-sdk/src/lib.rs
  • program-tests/sdk-token-test/Xargo.toml
  • sdk-libs/sdk/src/cpi/invoke.rs
  • program-tests/create-address-test-program/src/lib.rs
  • sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs
  • sdk-libs/client/src/indexer/mod.rs
  • program-tests/sdk-token-test/src/process_transfer_tokens.rs
  • sdk-libs/compressed-token-types/src/instruction/batch_compress.rs
  • sdk-libs/compressed-token-types/Cargo.toml
  • sdk-libs/compressed-token-types/src/instruction/generic.rs
  • sdk-libs/compressed-token-sdk/src/instructions/mod.rs
  • sdk-libs/sdk-types/src/cpi_accounts.rs
  • sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs
  • program-tests/sdk-token-test/src/process_compress_tokens.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
  • program-tests/sdk-token-test/src/process_batch_compress_tokens.rs
  • sdk-libs/compressed-token-sdk/src/token_pool.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs
  • sdk-libs/sdk/src/instruction/pack_accounts.rs
  • sdk-libs/compressed-token-sdk/src/instructions/burn.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/compressed-token-sdk/tests/account_metas_test.rs
  • sdk-libs/compressed-token-types/src/instruction/mod.rs
  • sdk-libs/compressed-token-types/src/token_data.rs
  • sdk-libs/compressed-token-types/src/error.rs
  • sdk-libs/sdk-types/src/instruction/tree_info.rs
  • program-tests/sdk-token-test/src/process_create_escrow_pda.rs
  • program-tests/sdk-token-test/Cargo.toml
  • sdk-libs/compressed-token-types/src/instruction/burn.rs
  • program-tests/sdk-token-test/tests/test_deposit.rs
  • sdk-libs/compressed-token-types/src/instruction/mint_to.rs
  • sdk-libs/compressed-token-sdk/src/error.rs
  • Cargo.toml
  • program-tests/sdk-token-test/src/process_decompress_tokens.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/compressed-token-types/src/lib.rs
  • sdk-libs/sdk/src/cpi/accounts.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/compressed-token-sdk/Cargo.toml
  • program-tests/sdk-token-test/src/lib.rs
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs
  • program-tests/sdk-token-test/src/process_create_compressed_account.rs
  • sdk-libs/compressed-token-types/src/account_infos/mint_to.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs
  • sdk-libs/compressed-token-types/src/instruction/delegation.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs
  • sdk-libs/compressed-token-types/src/account_infos/burn.rs
  • sdk-libs/compressed-token-types/src/account_infos/freeze.rs
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs
  • sdk-libs/compressed-token-types/src/constants.rs
  • program-tests/sdk-token-test/src/process_four_invokes.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs
  • program-tests/sdk-token-test/tests/test_4_invocations.rs
  • sdk-libs/compressed-token-types/src/instruction/transfer.rs
  • sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs
🧰 Additional context used
🧬 Code Graph Analysis (1)
program-tests/sdk-token-test/src/process_update_deposit.rs (5)
sdk-libs/sdk-types/src/cpi_accounts.rs (8)
  • cpi_context (202-213)
  • fee_payer (128-130)
  • authority (139-144)
  • new (21-28)
  • tree_pubkeys (258-264)
  • account_infos (241-243)
  • config (223-225)
  • try_new_with_config (99-126)
js/stateless.js/src/state/types.ts (1)
  • ValidityProof (397-410)
sdk-libs/compressed-token-sdk/src/account.rs (3)
  • transfer (66-95)
  • mint (182-184)
  • new (20-44)
sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1)
  • transfer (208-234)
js/stateless.js/src/state/compressed-account.ts (1)
  • PackedStateTreeInfo (120-141)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: system-programs (account-compression, ["cargo-test-sbf -p account-compression-test"])
  • GitHub Check: system-programs (system-cpi-test-v2-functional, ["cargo-test-sbf -p system-cpi-v2-test -- functio...
  • GitHub Check: system-programs (system-cpi-test-v2-event, ["cargo-test-sbf -p system-cpi-v2-test -- event::parse"])
  • GitHub Check: system-programs (system-cpi-test-v2-other, ["cargo-test-sbf -p system-cpi-v2-test -- --skip funct...
  • GitHub Check: system-programs (light-system-program, ["cargo-test-sbf -p system-test"])
  • GitHub Check: system-programs (random-e2e-test, ["cargo-test-sbf -p e2e-test"])
  • GitHub Check: system-programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test"])
  • GitHub Check: system-programs (light-registry, ["cargo-test-sbf -p registry-test"])
  • GitHub Check: system-programs (light-compressed-token, ["cargo-test-sbf -p compressed-token-test"])
  • GitHub Check: stateless-js-v2
  • GitHub Check: cli-v2
  • GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
  • GitHub Check: system-programs (counter-test, ["cargo test-sbf -p counter"])
  • GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-test"])
  • GitHub Check: system-programs (token-escrow-test, [ "cargo test-sbf -p token-escrow" ])
  • GitHub Check: Test concurrent-merkle-tree
  • GitHub Check: Test program-libs-slow
  • GitHub Check: Test sdk-libs
  • GitHub Check: lint
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: stateless-js-v1
  • GitHub Check: cli-v1

Comment on lines +246 to +247
// TODO: figure out why the offsets are wrong.
// Could add with pre account infos Option<u8>
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Investigate and fix account offset calculation issues.

The TODO indicates that offsets are incorrect, which could lead to runtime errors when accessing accounts.


🏁 Script executed:

#!/bin/bash
# Description: Search for other uses of system_accounts_start_offset to understand the offset calculation pattern

# Search for system_accounts_start_offset usage patterns
rg -A 5 -B 5 "system_accounts_start_offset" --type rust

# Look for similar account splitting patterns
ast-grep --pattern 'split_at($offset as usize)'

Length of output: 20867


Fix account slicing in process_update_deposit using both offsets

The current implementation only splits on system_accounts_start_offset, so system_account_infos ends up containing both system and packed accounts. You need to:

  • Extend the instruction to accept the second offset (packed_accounts_start_offset: u8).
  • Update the client tests to pass that third parameter from to_account_metas().
  • In program-tests/sdk-token-test/src/process_update_deposit.rs (and the corresponding entry in src/lib.rs), change the split logic to two steps:
-    let (_token_account_infos, system_account_infos) = ctx
-        .remaining_accounts
-        .split_at(system_accounts_start_offset as usize);
+    // First split off the packed accounts
+    let (pre_and_system_accounts, _packed_account_infos) =
+        ctx.remaining_accounts
+            .split_at(packed_accounts_start_offset as usize);
+    // Then split pre (token) vs. system accounts
+    let (_token_account_infos, system_account_infos) =
+        pre_and_system_accounts
+            .split_at(system_accounts_start_offset as usize);

This ensures CpiAccounts::try_new_with_config receives only the intended system accounts.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In program-tests/sdk-token-test/src/process_update_deposit.rs around lines
246-247, fix the account slicing by extending the instruction to accept a second
offset parameter named packed_accounts_start_offset of type u8. Update the
client tests to pass this new parameter from to_account_metas(). Modify the
split logic in process_update_deposit.rs and the corresponding entry in
src/lib.rs to perform a two-step split using both system_accounts_start_offset
and packed_accounts_start_offset, ensuring that system_account_infos contains
only the intended system accounts for CpiAccounts::try_new_with_config.

Comment on lines +267 to +284
pub fn to_account_info_refs(&self) -> Vec<&'a T> {
let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
account_infos.push(self.fee_payer());
self.account_infos()[1..]
.iter()
.for_each(|acc| account_infos.push(acc));
account_infos
}

/// Create a vector of account info references
pub fn to_account_infos(&self) -> Vec<T> {
let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
account_infos.push(self.fee_payer().clone());
self.account_infos()
.iter()
.for_each(|acc| account_infos.push(acc.clone()));
account_infos
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix inconsistency and capacity calculation errors in conversion methods.

The two conversion methods have different logic and incorrect capacity calculations:

  1. to_account_info_refs uses accounts[1..] while to_account_infos uses all accounts
  2. Both use 1 + system_accounts_len() capacity but to_account_infos adds all accounts
  3. Comments are identical but should describe different behavior
     /// Create a vector of account info references
     pub fn to_account_info_refs(&self) -> Vec<&'a T> {
-        let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
+        let mut account_infos = Vec::with_capacity(self.accounts.len());
         account_infos.push(self.fee_payer());
         self.account_infos()[1..]
             .iter()
             .for_each(|acc| account_infos.push(acc));
         account_infos
     }

-    /// Create a vector of account info references
+    /// Create a vector of cloned account infos
     pub fn to_account_infos(&self) -> Vec<T> {
-        let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
+        let mut account_infos = Vec::with_capacity(1 + self.accounts.len());
         account_infos.push(self.fee_payer().clone());
         self.account_infos()
             .iter()
             .for_each(|acc| account_infos.push(acc.clone()));
         account_infos
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn to_account_info_refs(&self) -> Vec<&'a T> {
let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
account_infos.push(self.fee_payer());
self.account_infos()[1..]
.iter()
.for_each(|acc| account_infos.push(acc));
account_infos
}
/// Create a vector of account info references
pub fn to_account_infos(&self) -> Vec<T> {
let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
account_infos.push(self.fee_payer().clone());
self.account_infos()
.iter()
.for_each(|acc| account_infos.push(acc.clone()));
account_infos
}
pub fn to_account_info_refs(&self) -> Vec<&'a T> {
let mut account_infos = Vec::with_capacity(self.accounts.len());
account_infos.push(self.fee_payer());
self.account_infos()[1..]
.iter()
.for_each(|acc| account_infos.push(acc));
account_infos
}
/// Create a vector of cloned account infos
pub fn to_account_infos(&self) -> Vec<T> {
let mut account_infos = Vec::with_capacity(1 + self.accounts.len());
account_infos.push(self.fee_payer().clone());
self.account_infos()
.iter()
.for_each(|acc| account_infos.push(acc.clone()));
account_infos
}
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/account_infos/transfer.rs around lines
267 to 284, fix the inconsistency between to_account_info_refs and
to_account_infos by aligning their logic for which accounts are included and
correcting the Vec capacity calculations accordingly. Adjust
to_account_info_refs to include all accounts like to_account_infos or vice
versa, and update the capacity to match the actual number of accounts pushed.
Also, revise the comments to accurately describe the distinct behavior of each
method.

mint to spl works

compress works

token transfer works

decompress works

batch compress works

refactor: sdk-token-test ixs into files

with cpi context works

fix: get_validity_proof order

fix: process_update_deposit typo

format

stash add process_four_invokes

add create escrow pda ix

stash test created escrow pda

stash four invocations test fails on 4th cpi

four cpi test works

refactor: light-sdks detach account metas from account infos
@ananas-block ananas-block force-pushed the jorrit/feat-compressed-token-sdk2 branch from 138eaac to 83ba332 Compare July 15, 2025 19:40
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

♻️ Duplicate comments (9)
sdk-libs/compressed-token-sdk/src/account.rs (2)

64-65: State validation concerns persist from previous reviews.

The TODO comments indicate ongoing confusion about method combinations. The current implementation lacks proper state validation to prevent conflicting method usage.


155-172: Move is_decompress guard before state mutations in compress

To maintain symmetry with decompress and avoid partial state updates when the check fails, the validation for self.is_decompress must run before modifying any fields.

  • sdk-libs/compressed-token-sdk/src/account.rs:137–142
 pub fn compress(&mut self, amount: u64) -> Result<(), TokenSdkError> {
-    self.output.amount += amount;
-    self.is_compress = true;
-    if self.is_decompress {
-        return Err(TokenSdkError::CannotCompressAndDecompress);
-    }
+    if self.is_decompress {
+        return Err(TokenSdkError::CannotCompressAndDecompress);
+    }
+    self.output.amount += amount;
+    self.is_compress = true;
     match self.compression_amount.as_mut() {
         Some(amount_ref) => *amount_ref += amount,
         None => self.compression_amount = Some(amount),
     }
     self.method_used = true;
 
     Ok(())
 }
program-tests/sdk-token-test/src/process_update_deposit.rs (3)

52-58: Address TODO: Remove unused cpi_context_account_index field.

The TODO comment indicates this field is useless and unused. Clean up should be prioritized to reduce code complexity.


179-183: Resolve architectural naming inconsistencies.

The TODO comments about renaming tree_accounts to packed_accounts and clarifying CPI context PDA roles should be addressed for code clarity.


243-247: Critical account slicing logic needs fixing.

The TODO indicates incorrect offsets which could cause runtime errors. This is a critical issue that needs immediate attention.

program-tests/sdk-token-test/tests/test_deposit.rs (2)

322-328: TODO regarding packed_tree_infos ordering needs investigation.

The uncertainty about packed_tree_infos ordering could lead to test failures or incorrect behavior. This should be resolved to ensure test reliability.


324-360: Replace hardcoded indices with descriptive constants.

The hardcoded indices (0, 1, 2) make the code fragile and difficult to understand. Consider using named constants or helper methods to improve maintainability.

sdk-libs/compressed-token-types/src/account_infos/transfer.rs (2)

184-192: Fix critical bug: sender_token_account uses wrong index.

This issue was previously flagged but hasn't been addressed. The method uses DecompressionRecipient index for the sender token account, which is incorrect for compress mode.

Apply the previously suggested fix:

     pub fn sender_token_account(&self) -> Result<&'a T> {
         if !self.config.compress {
             return Err(LightTokenSdkTypeError::SenderTokenAccountDoesOnlyExistInCompressedMode);
         };
-        let index = TransferAccountInfosIndex::DecompressionRecipient as usize;
+        let index = TransferAccountInfosIndex::TokenPoolPda as usize;
         self.accounts
             .get(index)
             .ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
     }

267-284: Fix inconsistency and capacity calculation errors in conversion methods.

This issue was previously flagged but hasn't been addressed. The methods have different logic for which accounts are included and incorrect capacity calculations.

Apply the previously suggested fix:

     /// Create a vector of account info references
     pub fn to_account_info_refs(&self) -> Vec<&'a T> {
-        let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
+        let mut account_infos = Vec::with_capacity(self.accounts.len());
         account_infos.push(self.fee_payer());
         self.account_infos()[1..]
             .iter()
             .for_each(|acc| account_infos.push(acc));
         account_infos
     }

-    /// Create a vector of account info references
+    /// Create a vector of cloned account infos
     pub fn to_account_infos(&self) -> Vec<T> {
-        let mut account_infos = Vec::with_capacity(1 + self.system_accounts_len());
+        let mut account_infos = Vec::with_capacity(1 + self.accounts.len());
         account_infos.push(self.fee_payer().clone());
         self.account_infos()
             .iter()
             .for_each(|acc| account_infos.push(acc.clone()));
         account_infos
     }
🧹 Nitpick comments (2)
program-tests/sdk-token-test/tests/test.rs (1)

92-95: Consider parameterizing test values for better maintainability.

The hardcoded values for transfer_recipient and transfer_amount are declared early but could be made configurable or at least documented for their significance.

sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1)

244-255: Optimize tree_pubkeys to reuse tree_accounts logic.

The method duplicates the bounds checking and slicing logic from tree_accounts(), which violates DRY principles and increases maintenance burden.

     pub fn tree_pubkeys(&self) -> Result<Vec<T::Pubkey>> {
-        let system_len = self.system_accounts_len();
-        Ok(self
-            .accounts
-            .get(system_len..)
-            .ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(
-                system_len,
-            ))?
+        Ok(self
+            .tree_accounts()?
             .iter()
             .map(|account| account.pubkey())
             .collect::<Vec<T::Pubkey>>())
     }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 138eaac and 83ba332.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (78)
  • Cargo.toml (4 hunks)
  • examples/anchor/counter/tests/test.rs (5 hunks)
  • program-libs/compressed-account/Cargo.toml (1 hunks)
  • program-libs/compressed-account/src/compressed_account.rs (0 hunks)
  • program-tests/create-address-test-program/src/lib.rs (1 hunks)
  • program-tests/sdk-anchor-test/programs/sdk-anchor-test/tests/test.rs (2 hunks)
  • program-tests/sdk-pinocchio-test/tests/test.rs (2 hunks)
  • program-tests/sdk-test/src/create_pda.rs (1 hunks)
  • program-tests/sdk-test/tests/test.rs (2 hunks)
  • program-tests/sdk-token-test/CLAUDE.md (1 hunks)
  • program-tests/sdk-token-test/Cargo.toml (1 hunks)
  • program-tests/sdk-token-test/Xargo.toml (1 hunks)
  • program-tests/sdk-token-test/src/lib.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_batch_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_compress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_compressed_account.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_create_escrow_pda.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_decompress_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_four_invokes.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_transfer_tokens.rs (1 hunks)
  • program-tests/sdk-token-test/src/process_update_deposit.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_4_invocations.rs (1 hunks)
  • program-tests/sdk-token-test/tests/test_deposit.rs (1 hunks)
  • sdk-libs/client/src/indexer/indexer_trait.rs (2 hunks)
  • sdk-libs/client/src/indexer/mod.rs (1 hunks)
  • sdk-libs/client/src/indexer/photon_indexer.rs (7 hunks)
  • sdk-libs/client/src/indexer/types.rs (5 hunks)
  • sdk-libs/client/src/rpc/indexer.rs (3 hunks)
  • sdk-libs/compressed-token-sdk/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-sdk/src/account.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/burn.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/src/token_pool.rs (1 hunks)
  • sdk-libs/compressed-token-sdk/tests/account_metas_test.rs (1 hunks)
  • sdk-libs/compressed-token-types/Cargo.toml (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/config.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/account_infos/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/constants.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/error.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/batch_compress.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/burn.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/delegation.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/freeze.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/generic.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mint_to.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/mod.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/instruction/transfer.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/lib.rs (1 hunks)
  • sdk-libs/compressed-token-types/src/token_data.rs (1 hunks)
  • sdk-libs/program-test/src/indexer/test_indexer.rs (3 hunks)
  • sdk-libs/program-test/src/program_test/indexer.rs (3 hunks)
  • sdk-libs/sdk-types/src/constants.rs (0 hunks)
  • sdk-libs/sdk-types/src/cpi_accounts.rs (3 hunks)
  • sdk-libs/sdk-types/src/instruction/tree_info.rs (1 hunks)
  • sdk-libs/sdk/src/cpi/accounts.rs (2 hunks)
  • sdk-libs/sdk/src/cpi/invoke.rs (2 hunks)
  • sdk-libs/sdk/src/error.rs (2 hunks)
  • sdk-libs/sdk/src/instruction/pack_accounts.rs (2 hunks)
💤 Files with no reviewable changes (2)
  • sdk-libs/sdk-types/src/constants.rs
  • program-libs/compressed-account/src/compressed_account.rs
✅ Files skipped from review due to trivial changes (2)
  • sdk-libs/compressed-token-types/Cargo.toml
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/mod.rs
🚧 Files skipped from review as they are similar to previous changes (63)
  • program-tests/sdk-token-test/Xargo.toml
  • program-libs/compressed-account/Cargo.toml
  • program-tests/sdk-test/src/create_pda.rs
  • sdk-libs/sdk/src/cpi/invoke.rs
  • program-tests/create-address-test-program/src/lib.rs
  • sdk-libs/client/src/indexer/mod.rs
  • sdk-libs/compressed-token-types/src/account_infos/mod.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/mod.rs
  • sdk-libs/compressed-token-types/src/instruction/generic.rs
  • sdk-libs/sdk/src/cpi/accounts.rs
  • sdk-libs/sdk-types/src/instruction/tree_info.rs
  • sdk-libs/compressed-token-types/src/instruction/batch_compress.rs
  • sdk-libs/compressed-token-sdk/src/lib.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/mod.rs
  • program-tests/sdk-token-test/src/process_batch_compress_tokens.rs
  • sdk-libs/compressed-token-types/src/account_infos/config.rs
  • sdk-libs/compressed-token-sdk/src/instructions/mod.rs
  • sdk-libs/compressed-token-sdk/src/instructions/ctoken_accounts.rs
  • sdk-libs/compressed-token-types/src/lib.rs
  • program-tests/sdk-token-test/src/process_transfer_tokens.rs
  • sdk-libs/compressed-token-types/src/instruction/mint_to.rs
  • program-tests/sdk-token-test/src/process_compress_tokens.rs
  • sdk-libs/client/src/rpc/indexer.rs
  • sdk-libs/compressed-token-types/src/instruction/burn.rs
  • sdk-libs/compressed-token-types/src/token_data.rs
  • program-tests/sdk-token-test/src/process_decompress_tokens.rs
  • sdk-libs/compressed-token-sdk/tests/account_metas_test.rs
  • Cargo.toml
  • program-tests/sdk-token-test/Cargo.toml
  • program-tests/sdk-token-test/src/process_create_escrow_pda.rs
  • sdk-libs/compressed-token-types/src/error.rs
  • sdk-libs/compressed-token-types/src/instruction/mod.rs
  • sdk-libs/compressed-token-types/src/instruction/freeze.rs
  • sdk-libs/program-test/src/program_test/indexer.rs
  • sdk-libs/program-test/src/indexer/test_indexer.rs
  • sdk-libs/client/src/indexer/indexer_trait.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs
  • sdk-libs/compressed-token-sdk/src/error.rs
  • sdk-libs/compressed-token-sdk/src/token_pool.rs
  • sdk-libs/client/src/indexer/types.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/instruction.rs
  • sdk-libs/compressed-token-sdk/src/instructions/approve/account_metas.rs
  • sdk-libs/sdk/src/instruction/pack_accounts.rs
  • sdk-libs/compressed-token-types/src/instruction/delegation.rs
  • sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs
  • sdk-libs/client/src/indexer/photon_indexer.rs
  • sdk-libs/compressed-token-types/src/account_infos/freeze.rs
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_metas.rs
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/account_infos.rs
  • sdk-libs/compressed-token-types/src/constants.rs
  • sdk-libs/compressed-token-types/src/account_infos/mint_to.rs
  • sdk-libs/compressed-token-sdk/Cargo.toml
  • sdk-libs/compressed-token-sdk/src/instructions/transfer/instruction.rs
  • sdk-libs/compressed-token-types/src/account_infos/burn.rs
  • program-tests/sdk-token-test/src/process_create_compressed_account.rs
  • program-tests/sdk-token-test/src/process_four_invokes.rs
  • sdk-libs/compressed-token-sdk/src/instructions/mint_to.rs
  • sdk-libs/compressed-token-types/src/instruction/transfer.rs
  • sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs
  • program-tests/sdk-token-test/src/lib.rs
  • program-tests/sdk-token-test/tests/test_4_invocations.rs
  • sdk-libs/compressed-token-sdk/src/instructions/burn.rs
  • sdk-libs/sdk-types/src/cpi_accounts.rs
🧰 Additional context used
🧬 Code Graph Analysis (1)
sdk-libs/compressed-token-types/src/account_infos/transfer.rs (5)
sdk-libs/compressed-token-types/src/account_infos/burn.rs (17)
  • new_with_cpi_context (42-44)
  • new (38-40)
  • new (48-55)
  • fee_payer (71-73)
  • authority (75-77)
  • new_with_config (57-69)
  • config (166-168)
  • light_system_program (107-112)
  • registered_program_pda (114-119)
  • noop_program (121-126)
  • account_compression_authority (128-133)
  • account_compression_program (135-140)
  • token_pool_pda (93-98)
  • system_program (149-154)
  • system_accounts_len (170-173)
  • account_infos (162-164)
  • get_account_info (156-160)
sdk-libs/compressed-token-types/src/account_infos/freeze.rs (16)
  • new_with_cpi_context (40-42)
  • new (36-38)
  • new (46-53)
  • fee_payer (69-71)
  • authority (73-75)
  • new_with_config (55-67)
  • config (150-152)
  • light_system_program (84-89)
  • registered_program_pda (91-96)
  • noop_program (98-103)
  • account_compression_authority (105-110)
  • account_compression_program (112-117)
  • system_program (126-131)
  • system_accounts_len (154-157)
  • account_infos (146-148)
  • get_account_info (140-144)
sdk-libs/compressed-token-types/src/account_infos/mint_to.rs (17)
  • new_with_cpi_context (58-64)
  • new (42-48)
  • new (84-91)
  • fee_payer (107-109)
  • authority (111-113)
  • new_with_config (93-105)
  • config (222-224)
  • light_system_program (146-151)
  • registered_program_pda (153-158)
  • noop_program (160-165)
  • account_compression_authority (167-172)
  • account_compression_program (174-179)
  • token_pool_pda (132-137)
  • system_program (195-200)
  • system_accounts_len (226-232)
  • account_infos (218-220)
  • get_account_info (212-216)
sdk-libs/sdk-types/src/cpi_accounts.rs (23)
  • new_with_cpi_context (30-37)
  • new (21-28)
  • new (72-78)
  • fee_payer (128-130)
  • authority (139-144)
  • new_with_config (91-97)
  • config (223-225)
  • light_system_program (132-137)
  • registered_program_pda (153-158)
  • noop_program (160-165)
  • account_compression_authority (167-172)
  • account_compression_program (174-179)
  • decompression_recipient (188-193)
  • system_program (195-200)
  • cpi_context (202-213)
  • system_accounts_len (227-239)
  • account_infos (241-243)
  • get_account_info (245-249)
  • tree_accounts (251-256)
  • tree_accounts (259-263)
  • tree_pubkeys (258-264)
  • get_tree_account_info (266-273)
  • to_account_infos (276-283)
sdk-libs/compressed-token-types/src/account_infos/batch_compress.rs (17)
  • new (35-42)
  • fee_payer (58-60)
  • authority (62-64)
  • new_with_config (44-56)
  • config (181-183)
  • light_system_program (87-92)
  • registered_program_pda (94-99)
  • noop_program (101-106)
  • account_compression_authority (108-113)
  • account_compression_program (115-120)
  • token_pool_pda (73-78)
  • sender_token_account (153-161)
  • system_program (136-141)
  • system_accounts_len (185-191)
  • account_infos (177-179)
  • get_account_info (163-167)
  • to_account_infos (168-175)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: system-programs (system-cpi-test-v2-other, ["cargo-test-sbf -p system-cpi-v2-test -- --skip funct...
  • GitHub Check: system-programs (random-e2e-test, ["cargo-test-sbf -p e2e-test"])
  • GitHub Check: system-programs (system-cpi-test-v2-functional, ["cargo-test-sbf -p system-cpi-v2-test -- functio...
  • GitHub Check: system-programs (light-compressed-token, ["cargo-test-sbf -p compressed-token-test"])
  • GitHub Check: system-programs (system-cpi-test-v2-event, ["cargo-test-sbf -p system-cpi-v2-test -- event::parse"])
  • GitHub Check: system-programs (light-registry, ["cargo-test-sbf -p registry-test"])
  • GitHub Check: system-programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test"])
  • GitHub Check: system-programs (light-system-program, ["cargo-test-sbf -p system-test"])
  • GitHub Check: system-programs (account-compression, ["cargo-test-sbf -p account-compression-test"])
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test sdk-libs
  • GitHub Check: Test program-libs-slow
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Test concurrent-merkle-tree
  • GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
  • GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-test"])
  • GitHub Check: system-programs (token-escrow-test, [ "cargo test-sbf -p token-escrow" ])
  • GitHub Check: system-programs (counter-test, ["cargo test-sbf -p counter"])
  • GitHub Check: stateless-js-v1
  • GitHub Check: cli-v1
  • GitHub Check: cli-v2
  • GitHub Check: stateless-js-v2
  • GitHub Check: lint
🔇 Additional comments (19)
program-tests/sdk-pinocchio-test/tests/test.rs (2)

97-99: LGTM! Improved error handling for system account addition.

The addition of .unwrap() properly handles the new Result<()> return type from add_system_accounts, which now includes CPI context ordering validation. This change aligns with the broader SDK improvements for stricter error handling.


147-149: LGTM! Consistent error handling pattern applied.

The change maintains consistency with the first function and properly handles the new error-returning behavior of add_system_accounts.

program-tests/sdk-anchor-test/programs/sdk-anchor-test/tests/test.rs (2)

95-95: LGTM! Proper error handling for system account addition.

The .unwrap() correctly handles the new Result<()> return type from add_system_accounts, ensuring test failure on CPI context ordering violations or other system account errors.


152-152: LGTM! Consistent error handling maintained.

The change maintains consistency with the pattern established in the create_compressed_account function.

program-tests/sdk-test/tests/test.rs (2)

84-86: LGTM! Proper error handling for system account addition.

The .unwrap() correctly handles the new Result<()> return type from add_system_accounts, ensuring immediate failure on CPI context ordering violations or other system account errors.


134-136: LGTM! Consistent error handling pattern maintained.

The change maintains consistency with the create_pda function and properly handles the new error-returning behavior.

examples/anchor/counter/tests/test.rs (5)

125-125: LGTM! Comprehensive error handling improvements.

The addition of .unwrap() across all test helper functions properly handles the new Result<()> return type from add_system_accounts, ensuring consistent error handling throughout the test suite.


183-183: LGTM! Consistent error handling maintained.

The change maintains consistency with the pattern established in other test functions.


244-244: LGTM! Consistent error handling pattern applied.

The change follows the same pattern as the other test functions.


304-304: LGTM! Consistent error handling maintained.

The change maintains consistency across all test helper functions.


364-364: LGTM! Comprehensive error handling coverage completed.

The final function now follows the same error handling pattern, ensuring comprehensive coverage across all test helper functions.

sdk-libs/sdk/src/error.rs (2)

79-80: LGTM! Well-designed error variant for CPI context ordering.

The new CpiContextOrderingViolation error variant provides a clear, descriptive message that explains the validation rule (CPI context must be added before other accounts with next_index at 0). This supports the enhanced CPI context ordering validation in the SDK.


164-164: LGTM! Consistent error code assignment.

The error code 16035 follows the existing numbering pattern and properly maps the new error variant to a unique identifier.

program-tests/sdk-token-test/CLAUDE.md (1)

1-170: Comprehensive debugging guide with excellent coverage of CPI context patterns.

This documentation provides thorough coverage of common issues, error codes, and solutions for SDK token testing. The structured format with error codes, fixes, and working patterns makes it highly valuable for developers working with the Light Protocol SDK.

The "Four Invokes" implementation section is particularly valuable, providing detailed account ordering and CPI context management patterns that are critical for multi-program transactions.

program-tests/sdk-token-test/src/process_update_deposit.rs (1)

28-66: No changes needed for CPI context flags in process_update_escrow_pda
The CompressedCpiContext { set_context: false, first_set_context: false } is intentional and required for light‐system‐program invocations. In programs/compressed-token/src/lib.rs, check_cpi_context explicitly rejects any CPI context with set_context or first_set_context set to true. The patterns you’ve seen elsewhere (with one or both flags true) apply to different CPI usages (e.g., TransferConfig in SDK tests), not to CpiInputs.invoke_light_system_program.

No code updates are necessary here.

Likely an incorrect or invalid review comment.

program-tests/sdk-token-test/tests/test.rs (2)

30-281: Comprehensive integration test with good coverage.

The test covers the full lifecycle of compressed token operations (compression, transfer, decompression) with proper assertions and verification steps. The test structure is well-organized and includes appropriate balance checks at each step.


455-572: Well-structured batch compression test.

The batch compression test properly verifies multiple recipients and validates each recipient's token balance. Good use of iteration to verify all recipients received correct amounts.

program-tests/sdk-token-test/tests/test_deposit.rs (2)

28-148: Complex test flow with good verification steps.

The test properly orchestrates the deposit creation and update flow with appropriate verification at each step. The use of compressed account queries and balance checks demonstrates thorough testing.


411-482: Helper function with proper error handling.

The batch_compress_spl_tokens function handles token creation, minting, and compression with appropriate error propagation and logging.

Comment on lines +136 to +154
// TODO: consider this might be confusing because it must not be used in combination with fn compress()
pub fn compress(&mut self, amount: u64) -> Result<(), TokenSdkError> {
self.output.amount += amount;
self.is_compress = true;
if self.is_decompress {
return Err(TokenSdkError::CannotCompressAndDecompress);
}

match self.compression_amount.as_mut() {
Some(amount_ref) => *amount_ref += amount,
None => self.compression_amount = Some(amount),
}
self.method_used = true;

Ok(())
}

// TODO: consider this might be confusing because it must not be used in combination with fn decompress()
pub fn decompress(&mut self, amount: u64) -> Result<(), TokenSdkError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

TODO comments highlight method combination design issues.

The repeated TODO comments across compress/decompress methods suggest fundamental design uncertainty about valid method combinations. This creates maintenance burden and potential for bugs.

Consider implementing a state machine pattern or adding comprehensive validation at the beginning of each method to clearly define valid transitions.

🤖 Prompt for AI Agents
In sdk-libs/compressed-token-sdk/src/account.rs around lines 136 to 154, the
TODO comments indicate confusion about using compress and decompress methods
together, risking bugs. Refactor by implementing a state machine or adding
explicit validation at the start of each method to enforce allowed method
combinations and transitions, preventing invalid states and improving code
clarity and maintainability.


pub fn tree_accounts(&self) -> Result<&'a [T]> {
let system_len = self.system_accounts_len();
solana_msg::msg!("Tree accounts length calculation {}", system_len);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debug logging from production code.

The debug message should be removed as it's not appropriate for production code and could impact performance.

-        solana_msg::msg!("Tree accounts length calculation {}", system_len);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
solana_msg::msg!("Tree accounts length calculation {}", system_len);
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/account_infos/transfer.rs at line 236,
remove the debug logging statement solana_msg::msg!("Tree accounts length
calculation {}", system_len) as debug logs should not be present in production
code to avoid performance impact and unnecessary log clutter.

@ananas-block ananas-block marked this pull request as draft July 16, 2025 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant