Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3d6af47
fix rebase
ananas-block Dec 18, 2025
8a48486
fix tests
ananas-block Dec 18, 2025
a3ac67c
test: add compression only cmint scenario
ananas-block Dec 18, 2025
c650ecb
test: add compression only restricted spl mint scenario
ananas-block Dec 18, 2025
e258fbb
fix decompress full test
ananas-block Dec 18, 2025
6913986
fix lint
ananas-block Dec 18, 2025
403575a
rebase cleanup and small fixes
ananas-block Dec 18, 2025
b695ff6
fix ci tests
ananas-block Dec 18, 2025
15181c9
cleanup
ananas-block Dec 18, 2025
d716f2f
fix: forester test
ananas-block Dec 19, 2025
e56a346
feat: sdk support approve, revoke, freeze, thaw
ananas-block Dec 19, 2025
82893e9
stash freeze thaw!
ananas-block Dec 20, 2025
2681c50
fix: cmint decompress validations
ananas-block Dec 20, 2025
5d1c287
feat: add decompress cmint sdk and test
ananas-block Dec 20, 2025
3172c05
test: burn ctokens
ananas-block Dec 20, 2025
778ffc8
test: ctoken mint to
ananas-block Dec 20, 2025
2f5eb6c
feat: add freeze thaw program ownership check, test: spl mint freeze …
ananas-block Dec 20, 2025
200cac6
feat: transfer checked
ananas-block Dec 20, 2025
c1cf3db
test: transfer checked
ananas-block Dec 20, 2025
6673309
stash add decimals to compressible extension
ananas-block Dec 20, 2025
b53a80e
stash decimals in ctoken account implemented sdk ctoken tests green
ananas-block Dec 21, 2025
26748fb
stash ctoken type refactor
ananas-block Dec 21, 2025
e282f43
stash CompressedMint CompressionInfo refactor
ananas-block Dec 21, 2025
bc8d051
adapted token program
ananas-block Dec 21, 2025
fe686d1
fix tests
ananas-block Dec 21, 2025
d293dc3
fix integration tests
ananas-block Dec 21, 2025
ebd9e9e
fix: failing tests
ananas-block Dec 22, 2025
3feb4ca
self review fixes and cleanup
ananas-block Dec 22, 2025
c149670
refactor: consolidate t22 extensions into light-ctoken-interface
ananas-block Dec 22, 2025
161ac37
cleanup
ananas-block Dec 22, 2025
2e9308c
doc: create token pool, add token pool
ananas-block Dec 23, 2025
260a28b
stash extension docs
ananas-block Dec 24, 2025
f571583
security: add separate derivation for restricted mint spl interace pdas
ananas-block Dec 24, 2025
2581537
feat: support restricted mints add token pool
ananas-block Dec 25, 2025
2665113
test: approve, revoke, freeze, thaw
ananas-block Dec 25, 2025
5805c34
stash pre extension test reorg
ananas-block Dec 26, 2025
acd1f22
refactor: split extensions.rs into compress_only directory
ananas-block Dec 26, 2025
ba15f02
stash
ananas-block Dec 28, 2025
55db958
stash tests
ananas-block Dec 28, 2025
1b5b3c1
fix feedback
ananas-block Dec 28, 2025
b33c6ce
update docs
ananas-block Dec 28, 2025
ab83e6f
feat: add claim from cmint
ananas-block Dec 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,57 @@ Format and clippy checks across the entire codebase.
- **`program-tests/`**: Integration tests requiring Solana runtime, depend on `light-test-utils`
- **`sdk-tests/`**: SDK-specific integration tests
- **Special case**: `zero-copy-derive-test` in `program-tests/` only to break cyclic dependencies

### Test Assertion Pattern

When testing account state, use borsh deserialization with a single `assert_eq` against an expected reference account:

```rust
use borsh::BorshDeserialize;
use light_ctoken_types::state::{
AccountState, CToken, ExtensionStruct, PausableAccountExtension,
PermanentDelegateAccountExtension,
};

// Deserialize the account
let ctoken = CToken::deserialize(&mut &account.data[..])
.expect("Failed to deserialize CToken account");

// Extract runtime-specific values from deserialized account
let compression_info = ctoken
.extensions
.as_ref()
.and_then(|exts| {
exts.iter().find_map(|e| match e {
ExtensionStruct::Compressible(info) => Some(info.clone()),
_ => None,
})
})
.expect("Should have Compressible extension");

// Build expected account for comparison
let expected_ctoken = CToken {
mint: mint_pubkey.to_bytes().into(),
owner: payer.pubkey().to_bytes().into(),
amount: 0,
delegate: None,
state: AccountState::Frozen,
is_native: None,
delegated_amount: 0,
close_authority: None,
extensions: Some(vec![
ExtensionStruct::Compressible(compression_info),
ExtensionStruct::PausableAccount(PausableAccountExtension),
ExtensionStruct::PermanentDelegateAccount(PermanentDelegateAccountExtension),
]),
};

// Single assert comparing full account state
assert_eq!(ctoken, expected_ctoken, "CToken account should match expected");
Comment on lines +245 to +246
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider documenting additional test patterns beyond the single assertion approach.

The section demonstrates a comprehensive single-assert pattern, which is excellent for full account validation. However, consider adding guidance for scenarios where tests need to: (a) assert on specific fields only (partial validation), (b) handle variable extension ordering, or (c) test failed account creation paths. A follow-up section with these patterns would strengthen the testing guidance.

🤖 Prompt for AI Agents
In CLAUDE.md around lines 245-246, expand the testing section by adding a
follow-up subsection that covers three patterns: (a) partial validation — show
how to assert specific fields rather than the entire account (e.g., compare
selected fields or use helper matchers to ignore irrelevant fields), (b)
extension-order resilience — describe comparing extensions in an
order-independent way (e.g., sort or compare by key/ID or convert to a map/set
before asserting), and (c) negative/failure paths — demonstrate testing failed
account creation by asserting error kinds/messages and any preserved state. Keep
each pattern short with a one-paragraph explanation and a small example outline
for the assertion strategy and test setup.

```

**Benefits:**
- Type-safe assertions using actual struct fields instead of magic byte offsets
- Maintainable - if account layout changes, deserialization handles it
- Readable - clear field names vs `account.data[108]`
- Single assertion point for the entire account state
Loading
Loading