|
| 1 | +# Compressed Claim |
| 2 | + |
| 3 | +Claims time-locked compressed tokens and decompresses them to an SPL token account. |
| 4 | + |
| 5 | +## [README](README.md) |
| 6 | + |
| 7 | +## Source Structure |
| 8 | + |
| 9 | +```text |
| 10 | +program/src/ |
| 11 | +├── lib.rs # entrypoint, declare_id! |
| 12 | +├── error.rs # ClaimError (3 variants) |
| 13 | +├── instruction.rs # ClaimIxData, ClaimAccounts, builders |
| 14 | +└── processor.rs # process_claim logic |
| 15 | +``` |
| 16 | + |
| 17 | +## Accounts |
| 18 | + |
| 19 | +### Airdrop PDA |
| 20 | + |
| 21 | +Seeds: `[claimant.to_bytes(), mint.to_bytes(), unlock_slot.to_le_bytes(), bump]` |
| 22 | + |
| 23 | +Derived via `Pubkey::create_program_address`. Holds compressed tokens until claim. |
| 24 | + |
| 25 | +### ClaimIxData (Instruction Data) |
| 26 | + |
| 27 | +| Field | Type | Description | |
| 28 | +|-------|------|-------------| |
| 29 | +| proof | ValidityProof | ZK proof for compressed account | |
| 30 | +| packed_tree_info | PackedStateTreeInfo | Merkle tree state info | |
| 31 | +| amount | u64 | Tokens to claim | |
| 32 | +| lamports | Option<u64> | Optional lamports to transfer | |
| 33 | +| mint | Pubkey | Token mint address | |
| 34 | +| unlock_slot | u64 | Slot when tokens unlock | |
| 35 | +| bump_seed | u8 | PDA bump seed | |
| 36 | + |
| 37 | +## Instructions |
| 38 | + |
| 39 | +| Instruction | Path | Accounts | Logic | |
| 40 | +|-------------|------|----------|-------| |
| 41 | +| Claim | processor.rs | claimant (signer), fee_payer (signer), airdrop_pda, + 13 Light/CToken accounts | Verifies unlock_slot <= current_slot, validates PDA, invokes decompress CPI | |
| 42 | + |
| 43 | +### Claim Accounts (16 total) |
| 44 | + |
| 45 | +0. claimant (signer) |
| 46 | +1. fee_payer (signer) |
| 47 | +2. associated_airdrop_pda |
| 48 | +3. ctoken_cpi_authority_pda |
| 49 | +4. light_system_program |
| 50 | +5. registered_program_pda |
| 51 | +6. noop_program |
| 52 | +7. account_compression_authority |
| 53 | +8. account_compression_program |
| 54 | +9. ctoken_program |
| 55 | +10. spl_interface_pda (token_pool) |
| 56 | +11. decompress_destination (writable) |
| 57 | +12. token_program |
| 58 | +13. system_program |
| 59 | +14. state_tree (writable) |
| 60 | +15. queue (writable) |
| 61 | + |
| 62 | +## Key Concepts |
| 63 | + |
| 64 | +**Time-lock**: Tokens unlock at `unlock_slot`. Claim fails if `current_slot < unlock_slot`. |
| 65 | + |
| 66 | +**PDA Derivation**: `[claimant, mint, unlock_slot, bump]` - ensures only rightful claimant can claim. |
| 67 | + |
| 68 | +**Decompress CPI**: Invokes `light_ctoken_sdk::decompress` to convert compressed tokens to SPL. |
| 69 | + |
| 70 | +## Security |
| 71 | + |
| 72 | +**Signer checks**: Both claimant and fee_payer must sign. |
| 73 | + |
| 74 | +**PDA validation**: Derived PDA must match provided airdrop_pda account. |
| 75 | + |
| 76 | +**Program check**: ctoken_program must equal `light_ctoken_sdk::ctoken::id()`. |
| 77 | + |
| 78 | +## Errors |
| 79 | + |
| 80 | +| Error | Description | |
| 81 | +|-------|-------------| |
| 82 | +| MissingRequiredSignature | Claimant or fee_payer not signer | |
| 83 | +| TokensLocked | current_slot < unlock_slot | |
| 84 | +| InvalidPDA | Derived PDA doesn't match provided account | |
0 commit comments