Skip to content

Commit 8dec314

Browse files
docs: Add Light Protocol compression integration guide
1 parent 505505d commit 8dec314

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

docs/LIGHT_COMPRESSION.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Light Protocol Compression Integration
2+
3+
## Fork Changes
4+
5+
This fork adds compressed token support to anchor-spl's `token_interface`:
6+
7+
```rust
8+
// anchor-spl/src/token_interface.rs
9+
pub const COMPRESSED_TOKEN_ID: Pubkey = ...;
10+
static IDS: [Pubkey; 3] = [spl_token::ID, spl_token_2022::ID, COMPRESSED_TOKEN_ID];
11+
```
12+
13+
`InterfaceAccount<'info, Mint>` and `InterfaceAccount<'info, TokenAccount>` now work with compressed tokens.
14+
15+
## TS SDK
16+
17+
The TS SDK adds `decompressIfNeeded()` to method builders. It auto-decompresses accounts before instruction execution when needed.
18+
19+
```typescript
20+
await program.methods
21+
.swap(amount)
22+
.decompressIfNeeded() // auto-decompresses any compressed accounts
23+
.rpc();
24+
```
25+
26+
### Limitations
27+
28+
- Cross-program PDAs (seeds::program) not supported for auto-resolution
29+
- Instruction argument seeds require explicit account addresses
30+
31+
## Rust Macros (light-sdk-macros)
32+
33+
### `#[add_compressible_instructions]`
34+
35+
Add to `#[program]` module. Generates compress/decompress instructions for listed accounts.
36+
37+
```rust
38+
#[add_compressible_instructions(
39+
PoolState = (POOL_SEED, ctx.accounts.amm_config, ctx.accounts.token_0_mint, ctx.accounts.token_1_mint),
40+
LpVault = (is_token, POOL_VAULT_SEED, ctx.accounts.lp_mint, authority = AUTH_SEED),
41+
)]
42+
#[program]
43+
pub mod my_program { ... }
44+
```
45+
46+
### `#[derive(LightFinalize)]` + `#[compressible]`
47+
48+
Auto-compresses PDAs at instruction end.
49+
50+
```rust
51+
#[derive(Accounts, LightFinalize)]
52+
#[instruction(params: MyParams)]
53+
pub struct MyInstruction<'info> {
54+
#[account(mut)]
55+
pub creator: Signer<'info>,
56+
57+
#[account(init, payer = creator, space = 8 + MyAccount::INIT_SPACE, seeds = [...], bump)]
58+
#[compressible(
59+
address_tree_info = params.address_tree_info,
60+
output_tree = params.output_state_tree_index
61+
)]
62+
pub my_account: Account<'info, MyAccount>,
63+
64+
pub compression_config: AccountInfo<'info>,
65+
}
66+
```
67+
68+
### `#[light_instruction(params)]`
69+
70+
Auto-calls `light_finalize()` at instruction end.
71+
72+
```rust
73+
#[light_instruction(params)]
74+
pub fn create_account(ctx: Context<MyInstruction>, params: MyParams) -> Result<()> {
75+
// your logic
76+
Ok(()) // light_finalize auto-called here
77+
}
78+
```
79+
80+
## Required Program Setup
81+
82+
```rust
83+
use light_sdk_types::CpiSigner;
84+
use light_macros::derive_light_cpi_signer;
85+
86+
pub const LIGHT_CPI_SIGNER: CpiSigner = derive_light_cpi_signer!("YOUR_PROGRAM_ID");
87+
```
88+
89+
## What's NOT Supported
90+
91+
- `#[light_mint]` attribute - use `light_ctoken_sdk` directly for mint creation
92+
- Mixed PDAs + mints in single `LightFinalize` - handle mints manually
93+
94+
## Gotchas
95+
96+
1. **Fee payer field**: LightFinalize looks for `fee_payer`, `payer`, or `creator` field names
97+
2. **compression_config field**: Required field in accounts struct - must be `AccountInfo<'info>`
98+
3. **params struct**: First `#[instruction(...)]` arg is used for compression params. Must contain `proof: ValidityProof` and tree info fields.
99+
4. **remaining_accounts**: Light system accounts go in remaining_accounts - client must pass them
100+
5. **Token accounts/mints**: Use `light_ctoken_sdk` directly (`CreateCTokenAccountCpi`, `CTokenMintToCpi`). Don't use `#[compressible]` on token accounts.
101+
6. **Only PDAs**: `#[compressible]` only works on `Account<'info, T>` fields, not token accounts or mints
102+
103+
## Example: Mixed PDA + Token Setup (raydium-cp-swap pattern)
104+
105+
```rust
106+
#[derive(Accounts, LightFinalize)]
107+
#[instruction(params: MyParams)]
108+
pub struct Initialize<'info> {
109+
#[account(mut)]
110+
pub creator: Signer<'info>,
111+
112+
// PDA - auto-compressed via LightFinalize
113+
#[account(init, ...)]
114+
#[compressible(address_tree_info = params.tree_info, output_tree = params.output_tree)]
115+
pub my_pda: Account<'info, MyState>,
116+
117+
// Token vault - manual compression via SDK
118+
/// CHECK: Created via CreateCTokenAccountCpi
119+
#[account(mut)]
120+
pub token_vault: UncheckedAccount<'info>,
121+
122+
// Mint - manual creation via SDK
123+
/// CHECK: Created via Light SDK CreateCMint
124+
#[account(mut)]
125+
pub my_mint: UncheckedAccount<'info>,
126+
127+
pub compression_config: AccountInfo<'info>,
128+
// ... light system accounts in remaining_accounts
129+
}
130+
131+
#[light_instruction(params)]
132+
pub fn initialize(ctx: Context<Initialize>, params: MyParams) -> Result<()> {
133+
// Manual token vault creation
134+
CreateCTokenAccountCpi { ... }.invoke_signed(...)?;
135+
136+
// Manual mint creation (if needed)
137+
// ... use light_ctoken_sdk
138+
139+
// PDA (my_pda) auto-compressed at end via light_finalize
140+
Ok(())
141+
}
142+
```

0 commit comments

Comments
 (0)