Skip to content

feat: add create_ata2 instructions with owner/mint as accounts#2000

Merged
ananas-block merged 2 commits intomainfrom
jorrit/feat-create-ata2
Oct 21, 2025
Merged

feat: add create_ata2 instructions with owner/mint as accounts#2000
ananas-block merged 2 commits intomainfrom
jorrit/feat-create-ata2

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Oct 20, 2025

Add CreateAssociatedTokenAccount2 (106) and CreateAssociatedTokenAccount2Idempotent (107) instructions where owner and mint are passed as account infos instead of instruction data.

Changes:

  • Add CreateAssociatedTokenAccount2InstructionData struct (only bump + compressible_config)
  • Refactor create_ata logic to extract core function accepting pubkeys directly
  • Add SDK instruction builders for compressible and non-compressible variants
  • Add minimal functional tests validating basic creation and idempotent mode

Account order: [owner, mint, fee_payer, ata, system_program, ...]
Discriminators: 106 (non-idempotent), 107 (idempotent)

Summary by CodeRabbit

  • New Features

    • Added CreateAssociatedTokenAccount2 instruction variants (regular and idempotent) for ATA creation
    • Added optional compressible extension support for associated token accounts
    • Extended SDK with APIs to create ATA2 (idempotent and non-idempotent) including compressible options
  • Tests

    • Added tests covering compressible and non-compressible ATA creation, plus idempotent creation and idempotency checks

Add CreateAssociatedTokenAccount2 (106) and CreateAssociatedTokenAccount2Idempotent (107) instructions where owner and mint are passed as account infos instead of instruction data.

Changes:
- Add CreateAssociatedTokenAccount2InstructionData struct (only bump + compressible_config)
- Refactor create_ata logic to extract core function accepting pubkeys directly
- Add SDK instruction builders for compressible and non-compressible variants
- Add minimal functional tests validating basic creation and idempotent mode

Account order: [owner, mint, fee_payer, ata, system_program, ...]
Discriminators: 106 (non-idempotent), 107 (idempotent)
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Walkthrough

Adds a new CreateAssociatedTokenAccount2 instruction variant (non-idempotent and idempotent), a new instruction data type including an optional compressible config, refactors ATA creation into a reusable inner function accepting owner/mint bytes, and extends SDK and tests to support ATA2.

Changes

Cohort / File(s) Summary
Type Definition
program-libs/ctoken-types/src/instructions/create_associated_token_account2.rs, program-libs/ctoken-types/src/instructions/mod.rs
New CreateAssociatedTokenAccount2InstructionData { bump: u8, compressible_config: Option<CompressibleExtensionInstructionData> } (repr(C)); derives Debug, Clone, AnchorSerialize, AnchorDeserialize, ZeroCopy; module exported.
Program: Core Refactor
programs/compressed-token/program/src/create_associated_token_account.rs
Extracted core ATA creation into process_create_associated_token_account_inner<const IDEMPOTENT: bool>(..., owner_bytes, mint_bytes, bump, compressible_config); made wrapper process_create_associated_token_account_with_mode pub(crate) and adapted calls to use explicit byte slices and compressible_config parameter.
Program: New ATA2 Module
programs/compressed-token/program/src/create_associated_token_account2.rs
New module with process_create_associated_token_account2 and process_create_associated_token_account2_idempotent entry points; deserializes CreateAssociatedTokenAccount2InstructionData and delegates to inner core with IDEMPOTENT const-generic flag.
Program: Instruction Routing
programs/compressed-token/program/src/lib.rs
Added CreateAssociatedTokenAccount2 (106) and CreateAssociatedTokenAccount2Idempotent (107) enum variants; updated From mapping; imports and routes new processors in process_instruction.
SDK: ATA2 Builders
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
Added discriminators CREATE_ATA2_* and public APIs: create_associated_token_account2, create_associated_token_account2_idempotent, create_compressible_associated_token_account2, create_compressible_associated_token_account2_idempotent; plus private helpers with mode/bump parameterization and unified instruction builder that serializes CreateAssociatedTokenAccount2InstructionData.
Tests
program-tests/compressed-token-test/tests/ctoken.rs, program-tests/compressed-token-test/tests/ctoken/create_ata2.rs
Registered create_ata2 test module and added tests/helpers: create_and_assert_ata2, basic compressible/non-compressible creation tests, and idempotent address-stability/size verification.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant SDK
    participant Program
    participant InnerFn as ATA Inner

    Client->>SDK: call create_associated_token_account2(...)
    SDK->>SDK: build Instruction (accounts: owner,mint) + serialize CreateAssociatedTokenAccount2InstructionData
    Client->>Program: submit transaction (Instruction)
    Program->>Program: match discriminator (106/107)
    Program->>Program: process_create_associated_token_account2(_idempotent)\ndeserialize instruction data
    Program->>InnerFn: call process_create_associated_token_account_inner::<IDEMPOTENT>(..., owner_bytes, mint_bytes, bump, compressible_config)

    alt compressible_config is Some
        InnerFn->>InnerFn: validate/process compressible config\nderive seeds using bump\ninitialize compressible token account
    else
        InnerFn->>InnerFn: derive seeds using bump\ninitialize standard token account
    end

    InnerFn-->>Program: Result<(), ProgramError>
    Program-->>Client: return transaction result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

🐰 In fields of bytes I hop and play,

ATA2 springs up to greet the day.
Bump and config tucked in my paw,
Idempotent hops — same address I saw.
SDK and tests cheer, a burrow of law.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "feat: add create_ata2 instructions with owner/mint as accounts" directly and accurately describes the primary change in the changeset. The title captures the key addition (new create_ata2 instructions) and highlights the distinguishing architectural feature (owner/mint passed as accounts instead of in instruction data), which is the core innovation of this PR. The title is concise, specific, and clear enough for a reviewer scanning the history to understand the main objective without needing to review the details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jorrit/feat-create-ata2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
programs/compressed-token/program/src/create_associated_token_account.rs (1)

65-146: Missing “ACTIVE only” config validation for compressible accounts.

Per guidelines, the Create Associated Token Account flow must accept compressible config only when its state is ACTIVE. Add an explicit state check before using compressible_config_account.

As per coding guidelines

Apply in process_compressible_config right after next_config_account:

 fn process_compressible_config<'info>(
     compressible_config_ix_data: &CompressibleExtensionInstructionData,
     iter: &mut AccountIterator<'info, AccountInfo>,
     token_account_size: usize,
     fee_payer: &'info AccountInfo,
     associated_token_account: &'info AccountInfo,
     ata_bump: u8,
     owner_bytes: &[u8; 32],
     mint_bytes: &[u8; 32],
 ) -> Result<(&'info CompressibleConfig, Option<Pubkey>), ProgramError> {
@@
-    let compressible_config_account = next_config_account(iter)?;
+    let compressible_config_account = next_config_account(iter)?;
+    // Enforce ACTIVE state only
+    use light_compressible::config::ConfigState;
+    if compressible_config_account.state != ConfigState::Active {
+        msg!("CompressibleConfig is not ACTIVE");
+        return Err(anchor_compressed_token::ErrorCode::InvalidConfigState.into());
+    }

Also applies to: 102-115

🧹 Nitpick comments (9)
program-libs/ctoken-types/src/instructions/mod.rs (1)

2-2: Re-export the new instruction data for a flatter public API.

Expose types via pub use to match other modules and simplify imports. Also remember to document the new instruction in the instructions docs. Based on learnings.

 pub mod create_associated_token_account;
 pub mod create_associated_token_account2;
 pub mod transfer2;
+// Re-exports
+pub use create_associated_token_account2::*;

I can add the minimal docs section for ATA2 (path, discriminator 106/107, accounts order, data fields) if you want.

program-tests/compressed-token-test/tests/ctoken/create_ata2.rs (2)

16-44: Prefer expect(...) over bare unwrap() for clearer failures.

Use context-rich messages so flakes are diagnosable in CI.

-        )
-        .unwrap()
+        )
+        .expect("failed to build compressible create_ata2 instruction")
@@
-        create_fn(payer_pubkey, owner_pubkey, context.mint_pubkey).unwrap()
+        create_fn(payer_pubkey, owner_pubkey, context.mint_pubkey)
+            .expect("failed to build create_ata2 instruction")

And:

-        .await
-        .unwrap();
+        .await
+        .expect("failed to send create_ata2 transaction");

95-138: Add a non-compressible idempotent test case.

Covers the ATA2 idempotent path without compressible config to prevent regressions across both modes.

 #[tokio::test]
 async fn test_create_ata2_idempotent() {
@@
 }
+
+#[tokio::test]
+async fn test_create_ata2_idempotent_non_compressible() {
+    let mut context = setup_account_test().await.unwrap();
+    // Fresh mint to avoid prior state.
+    context.mint_pubkey = solana_sdk::pubkey::Pubkey::new_unique();
+    let ata1 = create_and_assert_ata2(&mut context, None, true, "idemp_nc_1").await;
+    let ata2 = create_and_assert_ata2(&mut context, None, true, "idemp_nc_2").await;
+    assert_eq!(ata1, ata2, "ATA should be stable for idempotent non-compressible");
+    let account = context.rpc.get_account(ata1).await.unwrap().unwrap();
+    assert_eq!(
+        account.data.len(),
+        light_ctoken_types::BASE_TOKEN_ACCOUNT_SIZE as usize,
+        "Non-compressible ATA should keep base account size"
+    );
+}
program-libs/ctoken-types/src/instructions/create_associated_token_account2.rs (2)

9-14: Derive Borsh traits explicitly to match processor deserialization.

Processor invokes BorshDeserialize::deserialize; make derivations explicit to avoid trait‑resolution surprises across crates.

-#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize, ZeroCopy)]
+#[derive(
+    Debug,
+    Clone,
+    AnchorSerialize,
+    AnchorDeserialize,
+    borsh::BorshSerialize,
+    borsh::BorshDeserialize,
+    ZeroCopy
+)]
 pub struct CreateAssociatedTokenAccount2InstructionData {

Confirm your existing instruction data types also derive Borsh; if not, align for consistency.


1-6: Validate ZeroCopy applicability (struct contains Option<...>).

Zero‑copy markers usually require POD layouts; Option<CompressibleExtensionInstructionData> may not be zero‑copy safe.

  • If zero‑copy is unused for instruction data, drop ZeroCopy here.
  • Otherwise, please justify safety guarantees or switch to a plain Borsh‑only struct.

Can you confirm light_zero_copy::ZeroCopy supports Option<T> for this T?

programs/compressed-token/program/src/create_associated_token_account2.rs (3)

43-46: Pre-validate minimum accounts to surface clear errors early.

Inner call will fail later; make the contract explicit here.

-    if account_infos.len() < 2 {
+    // owner, mint, fee_payer, ata, system_program are required
+    if account_infos.len() < 5 {
         return Err(ProgramError::NotEnoughAccountKeys);
     }

8-16: #[inline(always)] is unnecessary here.

These are thin wrappers but not hot in tight loops; let the compiler decide.

Remove #[inline(always)] attributes to reduce codegen pressure.

Also applies to: 18-26


31-38: Augment docs with signer/writable flags in account order.

Clarify that owner/mint are readonly, non‑signer; fee_payer signer+mutable; ata mutable; system program readonly.

Update the comment block accordingly and mirror it in the public docs. Based on learnings.

I can add the docs in programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md for ATA2.

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

244-335: ATA2 SDK builders look solid; consider de‑duping with ATA v1.

The ATA2 builder logic duplicates v1. Extract shared helpers for:

  • compressible extension encoding
  • account metas assembly (parametrized by account order)
    This reduces drift risk between v1/v2.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4de2eca and 2e44c01.

📒 Files selected for processing (8)
  • program-libs/ctoken-types/src/instructions/create_associated_token_account2.rs (1 hunks)
  • program-libs/ctoken-types/src/instructions/mod.rs (1 hunks)
  • program-tests/compressed-token-test/tests/ctoken.rs (1 hunks)
  • program-tests/compressed-token-test/tests/ctoken/create_ata2.rs (1 hunks)
  • programs/compressed-token/program/src/create_associated_token_account.rs (2 hunks)
  • programs/compressed-token/program/src/create_associated_token_account2.rs (1 hunks)
  • programs/compressed-token/program/src/lib.rs (5 hunks)
  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
programs/compressed-token/program/src/create_associated_token_account.rs

📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)

Create Associated Token Account instruction must validate that the config state is ACTIVE only

Files:

  • programs/compressed-token/program/src/create_associated_token_account.rs
🧠 Learnings (8)
📚 Learning: 2025-10-15T03:46:26.767Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.767Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.

Applied to files:

  • program-libs/ctoken-types/src/instructions/mod.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • program-libs/ctoken-types/src/instructions/mod.rs
  • programs/compressed-token/program/src/lib.rs
  • program-libs/ctoken-types/src/instructions/create_associated_token_account2.rs
  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account2.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • programs/compressed-token/program/src/lib.rs
  • program-libs/ctoken-types/src/instructions/create_associated_token_account2.rs
  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account2.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • programs/compressed-token/program/src/lib.rs
  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account2.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account.rs
  • programs/compressed-token/program/src/create_associated_token_account2.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Account documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions

Applied to files:

  • programs/compressed-token/program/src/create_associated_token_account2.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors

Applied to files:

  • programs/compressed-token/program/src/create_associated_token_account2.rs
🧬 Code graph analysis (6)
program-libs/ctoken-types/src/instructions/mod.rs (1)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (1)
  • create_associated_token_account2 (294-300)
programs/compressed-token/program/src/lib.rs (2)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (1)
  • create_associated_token_account2 (294-300)
programs/compressed-token/program/src/create_associated_token_account2.rs (2)
  • process_create_associated_token_account2 (11-16)
  • process_create_associated_token_account2_idempotent (21-26)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (2)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
programs/compressed-token/program/src/lib.rs (1)
  • from (86-101)
program-tests/compressed-token-test/tests/ctoken/create_ata2.rs (3)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (5)
  • derive_ctoken_ata (229-238)
  • create_compressible_associated_token_account2_idempotent (254-258)
  • create_compressible_associated_token_account2 (246-250)
  • create_associated_token_account2_idempotent (304-310)
  • create_associated_token_account2 (294-300)
program-tests/utils/src/assert_create_token_account.rs (1)
  • assert_create_associated_token_account (258-291)
program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
  • setup_account_test (40-63)
programs/compressed-token/program/src/create_associated_token_account.rs (3)
programs/compressed-token/program/src/create_associated_token_account2.rs (1)
  • process_create_associated_token_account_inner (55-55)
programs/compressed-token/program/src/shared/create_pda_account.rs (1)
  • create_pda_account (37-70)
programs/compressed-token/program/src/shared/initialize_ctoken_account.rs (1)
  • initialize_ctoken_account (18-108)
programs/compressed-token/program/src/create_associated_token_account2.rs (3)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (2)
  • create_associated_token_account2 (294-300)
  • create_associated_token_account (101-107)
programs/compressed-token/program/src/create_associated_token_account.rs (2)
  • process_create_associated_token_account_inner (56-56)
  • process_create_associated_token_account_inner (68-146)
programs/compressed-token/program/src/lib.rs (1)
  • from (86-101)
⏰ 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). (21)
  • GitHub Check: system-programs (anchor & pinocchio, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -p sdk...
  • GitHub Check: Forester e2e test
  • GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
  • GitHub Check: system-programs (token test, ["cargo-test-sbf -p sdk-token-test"])
  • GitHub Check: system-programs (native, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v1-native-t...
  • GitHub Check: cli-v1
  • GitHub Check: lint
  • GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
  • GitHub Check: Test program-libs-slow
  • GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test program-libs-fast
  • GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
  • GitHub Check: stateless-js-v1
  • GitHub Check: cli-v2
  • GitHub Check: stateless-js-v2
🔇 Additional comments (13)
program-tests/compressed-token-test/tests/ctoken.rs (1)

29-31: Module wiring looks good.

New test module is correctly registered alongside existing suites.

programs/compressed-token/program/src/create_associated_token_account2.rs (1)

51-54: No program-side validation required—Solana runtime already enforces account metadata constraints.

The verification confirms that SDK builders correctly construct owner/mint accounts as readonly, non-signer (lines 383–384 in the SDK). Solana's runtime validates during transaction processing that provided accounts match their AccountMeta constraints, so program-side re-validation is redundant. The suggested defensive check is unnecessary.

programs/compressed-token/program/src/lib.rs (3)

12-12: ATA2 wiring looks correct.

Module is exported and processors imported symmetrically to ATA v1.

Also applies to: 28-30


158-165: Dispatch branches LGTM.

Logs and call targets align with new variants.


77-81: Discriminators 106/107 verified: unique and synchronized across program and SDK.

Verification confirms discriminators are not reused and match SDK constants. All occurrences of 106 and 107 correspond exclusively to CreateAssociatedTokenAccount2 variants, with consistent definitions in both the program enum and SDK constants (CREATE_ATA2_DISCRIMINATOR and CREATE_ATA2_IDEMPOTENT_DISCRIMINATOR).

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

5-9: Correct data type import for ATA2.

Using CreateAssociatedTokenAccount2InstructionData matches the new on-chain format (bump + optional compressible config).


371-381: Instruction data layout LGTM.

Only bump + optional compressible extension is serialized; owner/mint are accounts as intended.


18-20: Discriminators 106/107 are correctly aligned with the program.

The verification confirms the SDK constants match the program enum exactly:

  • CREATE_ATA2_DISCRIMINATOR: 106 matches CreateAssociatedTokenAccount2 = 106
  • CREATE_ATA2_IDEMPOTENT_DISCRIMINATOR: 107 matches CreateAssociatedTokenAccount2Idempotent = 107

382-388: Clarify the uninitialized account check: zero pubkey is not the Solana System Program ID.

The zero pubkey [0; 32] pattern is consistently used across program (line 92) and SDK (line 387), but the program-side comment "Check account is owned by system program (uninitialized)" is misleading. In Solana, the System Program ID is 11111111111111111111111111111111, not zero pubkey. This zero pubkey check appears to verify an uninitialized account state rather than actual system program ownership. Update the comment to clarify intent, or reconsider whether this check is validating the correct invariant.


229-238: No PDA seed parity issue found—review comment can be resolved.

Verification confirms that SDK and on-chain code use identical PDA derivation seeds and authorities. Both LIGHT_CPI_SIGNER.program_id (on-chain) and COMPRESSED_TOKEN_PROGRAM_ID (SDK) are derived from the same hardcoded address string "cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m" through standard Solana address parsing. The derive_light_cpi_signer! macro and pubkey_array! macro both parse the base58 string identically, producing equivalent [u8; 32] byte arrays. Seed lists [owner, program_id, mint] and program authorities are consistent across both implementations, eliminating any address drift risk.

programs/compressed-token/program/src/create_associated_token_account.rs (3)

48-64: Wrapper refactor LGTM.

Parsing once and delegating to a byte‑oriented core reduces duplication and clarifies ATA2 reuse.


81-89: Idempotent check order is correct.

Derivation is validated before early return on existing ownership; avoids false positives.


96-101: Account size selection is correct.

Switching between BASE and COMPRESSIBLE sizes based on presence of config is appropriate.

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

🧹 Nitpick comments (3)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (3)

385-386: Use system_program::ID instead of a zero Pubkey.

Zero [0;32] works but hides intent. Prefer the canonical constant.

Apply this diff (and mirror in the v1 path at Line 207):

-        solana_instruction::AccountMeta::new_readonly(Pubkey::new_from_array([0; 32]), false),
+        solana_instruction::AccountMeta::new_readonly(solana_program::system_program::ID, false),

Add import if needed:

use solana_program::system_program;

If this crate uses solana_sdk reexports, swap to solana_sdk::system_program::ID.


351-367: Deduplicate compressible-extension assembly.

The block is duplicated in v1 and v2. Extract a helper to reduce drift.

Example helper:

fn build_compressible_ext(
  cfg: Option<(u8, Option<u32>, Pubkey, Pubkey, TokenDataVersion)>
) -> Result<Option<CompressibleExtensionInstructionData>> {
  if let Some((pre, top_up, _rent_sponsor, _cfg_acc, ver)) = cfg {
    Ok(Some(CompressibleExtensionInstructionData {
      token_account_version: ver as u8,
      rent_payment: pre,
      has_top_up: u8::from(top_up.is_some()),
      write_top_up: top_up.unwrap_or(0),
      compress_to_account_pubkey: None,
    }))
  } else {
    Err(TokenSdkError::InvalidAccountData)
  }
}

Then call let compressible_extension = if COMPRESSIBLE { build_compressible_ext(compressible_config)? } else { None };


270-276: Consider making ATA2 “with_bump_and_mode” public for API parity.

v1 exposes *_with_bump_and_mode as pub. Mirror for ATA2 to aid advanced callers.

-fn create_compressible_associated_token_account2_with_bump_and_mode<const IDEMPOTENT: bool>(
+pub fn create_compressible_associated_token_account2_with_bump_and_mode<const IDEMPOTENT: bool>(
@@
-fn create_associated_token_account2_with_bump_and_mode<const IDEMPOTENT: bool>(
+pub fn create_associated_token_account2_with_bump_and_mode<const IDEMPOTENT: bool>(

Also applies to: 324-333

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e44c01 and 6a6450c.

📒 Files selected for processing (1)
  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (3 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/** : Define all state and instruction data structures in the light-ctoken-types crate (program-libs/ctoken-types), including state/, instructions/, and state/extensions/

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_associated_token_account.rs : Create Associated Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
📚 Learning: 2025-10-16T06:33:55.362Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-16T06:33:55.362Z
Learning: Applies to programs/compressed-token/program/src/create_token_account.rs : Create Token Account instruction must validate that the config state is ACTIVE only

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:46:03.556Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.556Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:45:40.038Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.038Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions

Applied to files:

  • sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs
🧬 Code graph analysis (1)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (2)
program-libs/compressed-account/src/pubkey.rs (1)
  • new_from_array (79-81)
programs/compressed-token/program/src/lib.rs (1)
  • from (86-101)
⏰ 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). (21)
  • GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
  • GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
  • GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
  • GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
  • GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
  • GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
  • GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
  • GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
  • GitHub Check: Test batched-merkle-tree-simulate
  • GitHub Check: Test program-libs-slow
  • GitHub Check: Test program-libs-fast
  • GitHub Check: Forester e2e test
  • GitHub Check: cli-v1
  • GitHub Check: system-programs (anchor & pinocchio, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -p sdk...
  • GitHub Check: system-programs (token test, ["cargo-test-sbf -p sdk-token-test"])
  • GitHub Check: cli-v2
  • GitHub Check: system-programs (native, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v1-native-t...
  • GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
  • GitHub Check: stateless-js-v2
  • GitHub Check: stateless-js-v1
  • GitHub Check: lint
🔇 Additional comments (4)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (4)

5-5: Correct type import for ATA2 data.

Import matches the new on‑chain instruction schema.


18-19: ATA2 discriminators match on-chain mapping.

106/107 align with program’s enum mapping.


335-343: ATA2 builder looks correct; account order and data layout LGTM.

  • Accounts order is [owner, mint, payer, ata, system_program, ...] as required.
  • Data = [discriminator | borsh(CreateAssociatedTokenAccount2InstructionData{ bump, compressible_config })].

Please confirm TokenDataVersion is a u8-backed enum on the program side to avoid schema drift.

Also applies to: 380-386, 369-378


229-238: PDA seeds verification confirmed—no issues found.

The on-chain derivation in validate_ata_derivation.rs uses seeds [owner, LIGHT_CPI_SIGNER.program_id, mint] with program authority LIGHT_CPI_SIGNER.program_id ("cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m"). The SDK's derive_ctoken_ata function uses identical seeds [owner, COMPRESSED_TOKEN_PROGRAM_ID, mint] with the same constant value. Both implementations match.

Copy link
Contributor

@SwenSchaeferjohann SwenSchaeferjohann left a comment

Choose a reason for hiding this comment

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

thanks!

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.

2 participants