refactor: rename light-ctoken-types -> light-ctoken-interface, light-compressed-token-sdk -> light-ctoken-sdk#2099
Conversation
WalkthroughComprehensive crate renaming refactoring updates all imports and Cargo dependencies across the codebase from Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Areas requiring special attention:
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
5250ba2 to
7777362
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (11)
programs/compressed-token/program/src/mint_action/actions/update_metadata.rs (1)
88-94: Commented example correctly updated; consider future import style when enablingThe commented-out
AdditionalMetadataexample now points atlight_ctoken_interface::state::AdditionalMetadata, which keeps the TODO in sync with the crate rename. When you eventually enable support for adding new keys, consider importingAdditionalMetadataalongsideTokenMetadataat the top and using the type directly in this block for consistency with the rest of the file.Based on learnings, this will keep the interface crate as the single source of truth for metadata-related types.
programs/compressed-token/program/src/transfer2/token_outputs.rs (1)
41-42: Fix typo in error message.The error message contains a typo: "delegete" should be "delegate".
Apply this diff:
let delegate_pubkey = if output_data.has_delegate() { let delegate_account = - packed_accounts.get_u8(output_data.delegate, "out token delegete")?; + packed_accounts.get_u8(output_data.delegate, "out token delegate")?; Some(*delegate_account.key()) } else {programs/compressed-token/program/src/transfer2/compression/spl.rs (1)
63-66: Avoidunimplemented!()forCompressAndClosein on‑chain codeRight now
ZCompressionMode::CompressAndClosefor SPL accounts just logs and hitsunimplemented!(). In a Solana program this will panic the BPF VM rather than returning a structured error, which makes failures harder to debug and diverges from the rest of the error‑handling story.Two concrete follow‑ups to consider (even though this predates the rename):
- If
CompressAndCloseis truly unsupported for SPL token accounts, return a well‑defined program error (ideally a specificanchor_compressed_token::ErrorCode) instead of panicking.- If it is meant to be supported as per the Transfer2 guidelines, implement the actual close behavior here, including correct lamport distribution when closing (rent → rent_sponsor, unutilized → destination) and the usual sum checks.
For a minimal safety improvement if you want to keep it unsupported for now:
- ZCompressionMode::CompressAndClose => { - msg!("CompressAndClose is unimplemented for spl token accounts"); - unimplemented!() - } + ZCompressionMode::CompressAndClose => { + msg!("CompressAndClose is unimplemented for spl token accounts"); + return Err(ProgramError::InvalidInstructionData); + }Based on learnings, Transfer2 flows should support or at least cleanly reject CompressAndClose rather than panicking.
programs/compressed-token/program/src/ctoken_transfer.rs (1)
87-109: Constant references now sourced from the interface crate without changing top‑up semanticsUsing
light_ctoken_interface::BASE_TOKEN_ACCOUNT_SIZEandlight_ctoken_interface::COMPRESSIBLE_TOKEN_RENT_EXEMPTIONpreserves the original rent/top‑up logic while routing everything through the renamed interface crate. As long as these constants retain their previous values inlight_ctoken_interface, the compressible‑account budget behavior remains identical. You might optionally pull these constants into the existinguse light_ctoken_interface::{ ... }block for consistency.Based on learnings, this keeps rent and compressibility parameters centralized in the CToken interface crate.
sdk-libs/ctoken-sdk/src/compressed_token/v2/compress_and_close.rs (2)
199-216: Prefer using the importedCTokenalias foramount_from_sliceFunctionally this is fine, but since
CTokenis already imported, you can simplify and make future crate renames cheaper by using the type alias instead of the fully qualified crate path:- let amount = light_ctoken_interface::state::CToken::amount_from_slice(&account_data)?; + let amount = CToken::amount_from_slice(&account_data)?;This also matches the
CToken::zero_copy_atusage earlier in the file.
305-313: Likewise, useCToken::zero_copy_athere for consistencySame nit as above: you already import
CTokenandZeroCopyAt, and earlier in the file you callCToken::zero_copy_at. For consistency and to reduce repetition of the crate path:- let (compressed_token, _) = - light_ctoken_interface::state::CToken::zero_copy_at(&account_data) - .map_err(|_| TokenSdkError::InvalidAccountData)?; + let (compressed_token, _) = + CToken::zero_copy_at(&account_data).map_err(|_| TokenSdkError::InvalidAccountData)?;No behavior change, just a small readability/maintainability improvement.
programs/compressed-token/program/src/mint_action/zero_copy_config.rs (1)
21-23: Consider relaxing the parameter from&mutto&if no mutation is required.
get_zero_copy_configsonly appears to read fromparsed_instruction_dataand does not mutate it locally. If neither this function nor any callees it passes the reference into actually modify the instruction data, you could change the signature to take&ZMintActionCompressedInstructionData<'_>instead of&mut .... That would make the borrowing contract clearer and slightly reduce friction for call sites that only have an immutable reference. This is a low‑priority, opportunistic refactor and not mandatory for this rename‑focused PR; just something to keep in mind next time you touch this path.program-libs/account-checks/CLAUDE.md (1)
8-20: Updated “Used in” entry aligns with the new interface crateReferencing
light-ctoken-interfacehere matches the crate rename and keeps the account-checks docs in sync with whereAccountInfoTraitconsumers now live. As a small follow‑up, you may also want to standardize the SDK bullet (compressed-token-sdk) to the newlight-ctoken-sdknaming to avoid mixed terminology in this list.DOCS.md (1)
165-173: Error crate references updated, but path example still points atctoken-typesThe error‑documentation bullets now correctly call out
light_ctoken_interface::CTokenErrorand addlight_compressed_account::CompressedAccountError, which matches the new crate layout and the guidance to document where error enums live. Nice alignment with the CLAUDE/docs conventions. Based on learnings.One leftover from the rename is the example under “Path References”:
program-libs/ctoken-types/src/state/solana_ctoken.rsTo keep this doc consistent with the actual crate name, it should be updated to something like:
- Example: `program-libs/ctoken-types/src/state/solana_ctoken.rs` + Example: `program-libs/ctoken-interface/src/state/solana_ctoken.rs`Also applies to: 215-216
programs/compressed-token/program/docs/ACCOUNTS.md (1)
32-45: Serialization examples correctly updated to uselight_ctoken_interfaceBoth the zero-copy and Borsh examples now import
CTokenfromlight_ctoken_interface::state::ctoken::CToken, which matches the new crate name and the way the program code accesses these types. That keeps the docs’ sample code in sync with the real API.One small follow-up to consider: the “path” line above still lists
program-libs/ctoken-types/src/state/ctoken/ctoken_struct.rs. If the directory was renamed together with the crate, it should be updated to the new location, e.g.:- path: `program-libs/ctoken-types/src/state/ctoken/ctoken_struct.rs` + path: `program-libs/ctoken-interface/src/state/ctoken/ctoken_struct.rs`Please adjust this to reflect the actual file path in the repo so the docs remain a reliable navigation guide.
program-libs/ctoken-interface/Cargo.toml (1)
41-53: Remove the self dev-dependency onlight-ctoken-interfaceThe crate declares a dev-dependency on itself at line 52:
light-ctoken-interface = { workspace = true, features = ["poseidon"] }This is unnecessary and creates a self-cycle in the dependency graph. Integration tests in
tests/automatically have access to the crate, and theposeidonfeature (defined asposeidon = ["light-hasher/poseidon"]) delegates tolight-hasher's feature, not to the crate itself. Feature unification handles enablingposeidonwhen running tests. No otherprogram-libscrates use this pattern.Remove the line and run
cargo test -p light-ctoken-interface --features poseidonto verify the tests still pass.
| use light_ctoken_interface::{ | ||
| instructions::mint_action::ZCompressedMintInstructionData, COMPRESSED_MINT_SEED, | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Crate rename wiring looks correct; consider importing MINT_ACCOUNT_SIZE for consistency
The switch to light_ctoken_interface for ZCompressedMintInstructionData, COMPRESSED_MINT_SEED, and MINT_ACCOUNT_SIZE is coherent and preserves behavior; the size constant still comes from the shared ctoken interface crate. If you want to keep the style consistent, you could add MINT_ACCOUNT_SIZE to the use light_ctoken_interface::{...} list and drop the fully qualified path at Line 22, but that's purely cosmetic. Based on learnings, keeping these shared types/constants in the dedicated ctoken interface crate matches the intended separation between program and SDK.
Also applies to: 22-22
🤖 Prompt for AI Agents
In
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rs
around lines 2 to 4 and line 22, the file imports ZCompressedMintInstructionData
and COMPRESSED_MINT_SEED from light_ctoken_interface but refers to
MINT_ACCOUNT_SIZE via a fully-qualified path on line 22; update the use
statement to also import MINT_ACCOUNT_SIZE from light_ctoken_interface (adding
it to the existing use list) and then replace the fully-qualified
MINT_ACCOUNT_SIZE reference on line 22 with the local identifier to keep imports
consistent and remove the redundant path.
| use light_ctoken_interface::{ | ||
| hash_cache::HashCache, instructions::mint_action::ZMintToCompressedAction, | ||
| state::CompressedMint, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Searching for old ctoken types crate references ==="
echo "Search 1: light_ctoken_types"
rg -c "light_ctoken_types" . 2>/dev/null | head -20 || echo "No matches found"
echo ""
echo "Search 2: light-ctoken-types"
rg -c "light-ctoken-types" . 2>/dev/null | head -20 || echo "No matches found"
echo ""
echo "=== Searching for old compressed token SDK crate references ==="
echo "Search 3: light_compressed_token_sdk"
rg -c "light_compressed_token_sdk" . 2>/dev/null | head -20 || echo "No matches found"
echo ""
echo "Search 4: light-compressed-token-sdk"
rg -c "light-compressed-token-sdk" . 2>/dev/null | head -20 || echo "No matches found"
echo ""
echo "=== Checking Cargo.toml files for old crate names ==="
rg "light-ctoken-types|light-compressed-token-sdk" --glob 'Cargo.toml' . 2>/dev/null || echo "No matches found"
echo ""
echo "=== Checking for light_ctoken_interface references ==="
rg -c "light_ctoken_interface" . 2>/dev/null | head -20 || echo "No matches found"
echo ""
echo "=== Checking for light-ctoken-interface in Cargo.toml files ==="
rg "light-ctoken-interface" --glob 'Cargo.toml' . 2>/dev/null || echo "No matches found"Repository: Lightprotocol/light-protocol
Length of output: 3202
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking key documentation files ==="
echo ""
echo "1. programs/compressed-token/program/CLAUDE.md:"
if [ -f "programs/compressed-token/program/CLAUDE.md" ]; then
grep -n "light-ctoken" programs/compressed-token/program/CLAUDE.md || echo "No ctoken crate references found"
else
echo "File not found"
fi
echo ""
echo "2. program-libs/ README or CLAUDE files:"
find program-libs -name "CLAUDE.md" -o -name "README.md" | head -5 | while read f; do
if [ -f "$f" ]; then
echo " File: $f"
grep -n "light-ctoken" "$f" 2>/dev/null | head -3 || echo " No ctoken crate references"
fi
done
echo ""
echo "3. Checking for ctoken-types directory references:"
find . -type d -name "*ctoken*types*" 2>/dev/null | grep -v ".git" || echo "No ctoken-types directories found"
echo ""
echo "4. Checking for ctoken-interface directory references:"
find . -type d -name "*ctoken*interface*" 2>/dev/null | grep -v ".git" || echo "No ctoken-interface directories found"Repository: Lightprotocol/light-protocol
Length of output: 968
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking program-libs directory structure ==="
ls -la program-libs/ 2>/dev/null | grep ctoken || echo "No ctoken directories in program-libs"
echo ""
echo "=== Checking actual crate paths ==="
find . -path "./program-libs/*" -name "Cargo.toml" 2>/dev/null | xargs -I {} sh -c 'echo "File: {}" && grep "^\[package\]" -A 1 {}' | grep -A 1 "name.*ctoken" || echo "No ctoken crates found"Repository: Lightprotocol/light-protocol
Length of output: 256
Import rename to light_ctoken_interface is correct; fix outdated path reference in CLAUDE.md
The import cleanly switches to light_ctoken_interface and the crate migration is complete—no stale references to old names (light_ctoken_types, light-compressed-token-sdk) remain in code or manifests.
However, programs/compressed-token/program/CLAUDE.md line 114 still references the old directory path:
All state and instruction data structures are defined in **`program-libs/ctoken-types/`** (`light-ctoken-interface` crate):
Update to:
All state and instruction data structures are defined in **`program-libs/ctoken-interface/`** (`light-ctoken-interface` crate):
This keeps the path documentation aligned with the actual directory structure and prevents future contributor confusion.
🤖 Prompt for AI Agents
In programs/compressed-token/program/src/mint_action/actions/mint_to.rs around
lines 4 to 7 the import was updated to use light_ctoken_interface but
programs/compressed-token/program/CLAUDE.md line 114 still references the old
path program-libs/ctoken-types/; update that line in CLAUDE.md to read
program-libs/ctoken-interface/ and keep the parenthetical crate name as
(`light-ctoken-interface`) so the documented directory path matches the migrated
crate name.
| use light_ctoken_interface::{ | ||
| hash_cache::HashCache, instructions::transfer2::ZCompressedTokenInstructionDataTransfer2, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's read the actual file to see the import and surrounding context
cat -n programs/compressed-token/program/src/transfer2/token_outputs.rs | head -50Repository: Lightprotocol/light-protocol
Length of output: 2378
🏁 Script executed:
# Search for all references to the old and new crate names
echo "=== Searching for light_ctoken_types references ==="
rg "light_ctoken_types" --type rust -c
echo ""
echo "=== Searching for light_ctoken_interface references ==="
rg "light_ctoken_interface" --type rust -c
echo ""
echo "=== Checking for light-ctoken-types in Cargo.toml files ==="
rg "light-ctoken-types" --type toml -c
echo ""
echo "=== Checking for light-ctoken-interface in Cargo.toml files ==="
rg "light-ctoken-interface" --type toml -cRepository: Lightprotocol/light-protocol
Length of output: 7948
🏁 Script executed:
# List the program-libs directory to understand the crate structure
ls -la program-libs/ | grep -E "ctoken|token"Repository: Lightprotocol/light-protocol
Length of output: 137
🏁 Script executed:
# Verify the exact context of the typo and check if there are any other issues
sed -n '38,46p' programs/compressed-token/program/src/transfer2/token_outputs.rsRepository: Lightprotocol/light-protocol
Length of output: 376
🏁 Script executed:
# Check if there are any other imports from light_ctoken_interface in this file
grep -n "light_ctoken_interface" programs/compressed-token/program/src/transfer2/token_outputs.rsRepository: Lightprotocol/light-protocol
Length of output: 103
Import path update is correct; fix pre-existing typo on line 42.
The renaming from light_ctoken_types to light_ctoken_interface is properly applied across the codebase (verified in 148+ files) and maintains the architectural separation between program implementation and type definitions.
However, line 42 has a pre-existing typo in the error message: "out token delegete" should be "out token delegate".
🤖 Prompt for AI Agents
In programs/compressed-token/program/src/transfer2/token_outputs.rs around lines
4-6 and line 42, there is a typo in the error message text: change the string
"out token delegete" to "out token delegate" (correcting the misspelling of
"delegate") so the error message reads properly.
| [features] | ||
|
|
||
| anchor = ["anchor-lang", "light-compressed-token-types/anchor", "light-ctoken-types/anchor"] | ||
| anchor = ["anchor-lang", "light-compressed-token-types/anchor", "light-ctoken-interface/anchor"] |
There was a problem hiding this comment.
Critical: Both old and new crate dependencies coexist.
The refactoring is incomplete:
- Line 8: The
anchorfeature enables bothlight-compressed-token-types/anchor(old) andlight-ctoken-interface/anchor(new) - Line 23: Old dependency
light-compressed-token-typesstill present - Line 26: New dependency
light-ctoken-interfaceadded
This dual dependency can cause type confusion and compilation errors if both crates export similar types.
Apply this fix:
-anchor = ["anchor-lang", "light-compressed-token-types/anchor", "light-ctoken-interface/anchor"]
+anchor = ["anchor-lang", "light-ctoken-interface/anchor"]-light-compressed-token-types = { workspace = true }
light-compressed-account = { workspace = true, features = ["std"] }Also applies to: 23-26
🤖 Prompt for AI Agents
In sdk-libs/ctoken-sdk/Cargo.toml around lines 8 and 23-26, the feature "anchor"
currently enables both the old crate feature light-compressed-token-types/anchor
and the new light-ctoken-interface/anchor while the dependencies section still
contains both light-compressed-token-types (old) and light-ctoken-interface
(new), causing duplicate types; remove the old crate and its feature reference:
update the anchor feature to only include "light-ctoken-interface/anchor" and
delete the light-compressed-token-types dependency (and any of its feature
flags) so only light-ctoken-interface remains referenced to avoid type
collisions and ensure the Cargo.toml consistently references the new crate.
| Ok(Instruction { | ||
| program_id: Pubkey::new_from_array(light_ctoken_types::COMPRESSED_TOKEN_PROGRAM_ID), | ||
| program_id: Pubkey::new_from_array(light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID), | ||
| accounts: account_metas, |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Program ID now sourced from the interface crate; behavior stays the same.
Using Pubkey::new_from_array(light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID) keeps this instruction pointed at the canonical compressed-token program via the interface crate, with no change to accounts or data layout. A small optional cleanup would be to import the constant directly:
-use light_ctoken_interface;
+use light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID;
…
- program_id: Pubkey::new_from_array(light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID),
+ program_id: Pubkey::new_from_array(COMPRESSED_TOKEN_PROGRAM_ID),which tightens the call site without altering behavior.
Verify that COMPRESSED_TOKEN_PROGRAM_ID in light-ctoken-interface matches the old value from the previous crate (e.g., by grepping both definitions in the repo) so you don’t accidentally change the target on-chain program during this rename.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In sdk-libs/ctoken-sdk/src/compressed_token/v1/batch_compress/instruction.rs
around lines 80 to 82, the code constructs the program_id via
Pubkey::new_from_array(light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID) —
keep this behavior but replace the fully-qualified path with a direct import of
COMPRESSED_TOKEN_PROGRAM_ID at the top of the file (use use
light_ctoken_interface::COMPRESSED_TOKEN_PROGRAM_ID;) and then call
Pubkey::new_from_array(COMPRESSED_TOKEN_PROGRAM_ID) at the call site to tighten
the call; additionally verify (grep or otherwise) that the
COMPRESSED_TOKEN_PROGRAM_ID in light-ctoken-interface matches the previous
crate’s constant to ensure the on-chain target was not changed.
Summary by CodeRabbit
Release Notes
light-ctoken-typescrate tolight-ctoken-interfacefor improved clarity and consistency across the library.light-compressed-token-sdkcrate tolight-ctoken-sdkfor streamlined naming conventions.✏️ Tip: You can customize this high-level summary in your review settings.