@@ -65,12 +65,12 @@ End-to-end flow for using this crate:
6565 find_spl_interface_pda(mint) → SPL pool PDA (for wrap/unwrap/SPL decompress)
6666
67675. Build instruction(s)
68- create_transfer2_instruction( ...) → compressed-to-compressed
69- create_decompress_instruction( ...) → compressed → on-chain account
70- create_wrap_instruction( ...) → SPL → light-token
71- create_unwrap_instruction( ...) → light-token → SPL
72- create_ata_idempotent_instruction (...) → create ATA
73- create_transfer_checked_instruction( ...) → ATA-to-ATA
68+ Transfer2 { ... }.instruction() → compressed-to-compressed
69+ Decompress { ... }.instruction() → compressed → on-chain account
70+ Wrap { ... }.instruction() → SPL → light-token
71+ Unwrap { ... }.instruction() → light-token → SPL
72+ CreateAta::new (...).idempotent().instruction() → create ATA
73+ TransferChecked { ... }.instruction() → ATA-to-ATA
7474
75756. Set compute budget
7676 Use constants from load_ata.rs or create_load_ata_batches() for automatic estimation
@@ -136,121 +136,101 @@ Packed accounts for wrap/unwrap use fixed indices (not HashMap):
136136
137137## Public API — Instruction builders
138138
139- ### create_transfer2_instruction
139+ All builders follow the same pattern: struct with named fields + ` .instruction() -> Result<Instruction, KoraLightError> ` .
140+
141+ ### Transfer2
140142
141143``` rust
142- fn create_transfer2_instruction (
143- payer : & Pubkey , // fee payer (signer)
144- authority : & Pubkey , // token owner or delegate (signer)
145- mint : & Pubkey , // token mint
146- inputs : & [ CompressedTokenAccountInput ], // source compressed accounts
147- proof : & CompressedProof , // validity proof from RPC
148- destination_owner : & Pubkey , // owner of destination compressed account
149- amount : u64 , // amount to transfer
150- ) -> Result < Instruction , KoraLightError >
144+ Transfer2 {
145+ payer , // fee payer (signer)
146+ authority , // token owner or delegate (signer)
147+ mint , // token mint
148+ inputs : & accounts , // source compressed accounts
149+ proof : & proof , // validity proof from RPC
150+ destination_owner , // owner of destination compressed account
151+ amount : 1_000 ,
152+ } . instruction () ?
151153```
152154
153155- ** discriminator:** 101 (` TRANSFER2_DISCRIMINATOR ` )
154156- ** layout:** standard (7 static + packed)
155157- ** path:** ` src/transfer.rs `
156158
157- Builds a Transfer2 instruction for compressed - to - compressed token transfers . Automatically creates a change output if `amount < input_total `. Omits the proof from instruction data when all inputs use `prove_by_index `.
158-
159- Signers : payer , authority .
159+ Compressed-to-compressed token transfer. Automatically creates a change output if ` amount < input_total ` . Omits the proof when all inputs use ` prove_by_index ` .
160160
161- ### create_decompress_instruction
161+ ### Decompress
162162
163163``` rust
164- fn create_decompress_instruction (
165- payer : & Pubkey ,
166- owner : & Pubkey ,
167- mint : & Pubkey ,
168- inputs : & [CompressedTokenAccountInput ],
169- proof : & CompressedProof ,
170- destination : & Pubkey , // on-chain token account (light-token ATA or SPL ATA)
171- amount : u64 ,
172- decimals : u8 ,
173- spl_interface : Option <& SplInterfaceInfo >, // None for light-token, Some for SPL
174- ) -> Result <Instruction , KoraLightError >
164+ Decompress {
165+ payer , owner , mint ,
166+ inputs : & accounts ,
167+ proof : & proof ,
168+ destination , // light-token ATA or SPL ATA
169+ amount : 1_000 ,
170+ decimals : 6 ,
171+ spl_interface : None , // None for light-token, Some(&info) for SPL
172+ }. instruction ()?
175173```
176174
177175- ** discriminator:** 101 (Transfer2 with ` Compression::Decompress ` )
178176- ** layout:** standard (7 static + packed)
179177- ** path:** ` src/decompress.rs `
180178
181- Routes between light - token decompress (no pool , `spl_interface = None `) and SPL decompress (with pool account and token program added to packed accounts ). Creates a change output if `amount < input_total `.
179+ Routes between light-token decompress (` spl_interface=None ` ) and SPL decompress (with pool + token_program ). Creates change output if ` amount < input_total ` .
182180
183- Signers : payer , owner . Packed accounts include pool (writable ) and token_program when `spl_interface ` is provided .
184-
185- ### create_wrap_instruction
181+ ### Wrap
186182
187183``` rust
188- fn create_wrap_instruction (
189- source : & Pubkey , // SPL token account (writable)
190- destination : & Pubkey , // light-token account (writable)
191- owner : & Pubkey , // token owner (signer)
192- mint : & Pubkey ,
193- amount : u64 ,
194- decimals : u8 ,
195- payer : & Pubkey , // fee payer (signer)
196- spl_interface : & SplInterfaceInfo ,
197- ) -> Result <Instruction , KoraLightError >
184+ Wrap {
185+ source : spl_ata ,
186+ destination : light_token_ata ,
187+ owner , mint ,
188+ amount : 1_000 ,
189+ decimals : 6 ,
190+ payer ,
191+ spl_interface : & spl_info ,
192+ }. instruction ()?
198193```
199194
200195- ** discriminator:** 101 (Transfer2 with two compressions)
201196- ** layout:** decompressed-only (2 static + fixed packed)
202197- ** path:** ` src/wrap.rs `
203198
204- Uses two compression operations : `Compress (SPL )` moves tokens from SPL source to pool , then `Decompress (light - token )` moves them from pool to light - token destination . No compressed inputs or outputs (empty vecs ), no proof needed .
205-
206- Signers : payer , owner . Total accounts : 10 (2 static + 6 packed + 2 appended programs ).
199+ SPL → light-token via dual compression. Total accounts: 10.
207200
208- ### create_unwrap_instruction
201+ ### Unwrap
209202
210203``` rust
211- fn create_unwrap_instruction (
212- source : & Pubkey , // light-token account (writable)
213- destination : & Pubkey , // SPL token account (writable)
214- owner : & Pubkey , // token owner (signer)
215- mint : & Pubkey ,
216- amount : u64 ,
217- decimals : u8 ,
218- payer : & Pubkey , // fee payer (signer)
219- spl_interface : & SplInterfaceInfo ,
220- ) -> Result <Instruction , KoraLightError >
204+ Unwrap {
205+ source : light_token_ata ,
206+ destination : spl_ata ,
207+ owner , mint ,
208+ amount : 1_000 ,
209+ decimals : 6 ,
210+ payer ,
211+ spl_interface : & spl_info ,
212+ }. instruction ()?
221213```
222214
223215- ** discriminator:** 101 (Transfer2 with two compressions)
224216- ** layout:** decompressed-only (2 static + fixed packed)
225217- ** path:** ` src/unwrap.rs `
226218
227- Reverse of wrap : ` Compress ( light - token )` then ` Decompress ( SPL )` . Same account layout and structure as wrap with different compression modes .
219+ Reverse of Wrap: light-token → SPL via dual compression.
228220
229- ### CreateAta / create_ata_idempotent_instruction
221+ ### CreateAta
230222
231223``` rust
232- struct CreateAta {
233- payer : Pubkey ,
234- owner : Pubkey ,
235- mint : Pubkey ,
236- idempotent : bool , // default: false
237- compressible_config : Pubkey , // default: LIGHT_TOKEN_CONFIG
238- rent_sponsor : Pubkey , // default: RENT_SPONSOR_V1
239- pre_pay_num_epochs : u8 , // default: 16
240- write_top_up : u32 , // default: 766 lamports
241- compression_only : bool , // default: true
242- }
243-
244- // Builder usage
245- CreateAta :: new (payer , owner , mint ). idempotent (). instruction ()
246-
247- // Convenience function
248- fn create_ata_idempotent_instruction (payer , owner , mint ) -> Result <Instruction >
224+ CreateAta :: new (payer , owner , mint )
225+ . idempotent ()
226+ . instruction ()?
249227```
250228
251- - * * discriminator : ** 100 (CreateATA ) or 102 (CreateATA idempotent )
229+ - ** discriminator:** 100 (CreateATA) or 102 (idempotent)
252230- ** path:** ` src/create_ata.rs `
253231
232+ Builder fields: ` compressible_config ` , ` rent_sponsor ` , ` pre_pay_num_epochs ` , ` write_top_up ` , ` compression_only ` all have sensible defaults.
233+
254234Accounts (7, fixed order):
255235
256236| Index | Account | Signer | Writable |
@@ -263,28 +243,24 @@ Accounts (7, fixed order):
263243| 5 | compressible_config | | |
264244| 6 | rent_sponsor | | yes |
265245
266- ATA address is derived from `get_associated_token_address (owner , mint )`.
267-
268- ### create_transfer_checked_instruction
246+ ### TransferChecked
269247
270248``` rust
271- fn create_transfer_checked_instruction (
272- source_ata : & Pubkey ,
273- destination_ata : & Pubkey ,
274- mint : & Pubkey ,
275- owner : & Pubkey , // signer
276- amount : u64 ,
277- decimals : u8 ,
278- payer : & Pubkey , // signer, only added if != owner
279- ) -> Result < Instruction , KoraLightError >
249+ TransferChecked {
250+ source_ata ,
251+ destination_ata ,
252+ mint ,
253+ owner ,
254+ amount : 1_000 ,
255+ decimals : 6 ,
256+ payer ,
257+ } . instruction () ?
280258```
281259
282260- ** discriminator:** 12
283261- ** path:** ` src/transfer.rs `
284262
285- For decompressed (on - chain ) light - token ATA - to - ATA transfers . Not for compressed accounts . Data format : discriminator (1 ) + amount (8 LE ) + decimals (1 ) = 10 bytes .
286-
287- Accounts : source (writable ), mint , destination (writable ), owner (signer ), SystemProgram , [payer (signer ) if payer != owner ].
263+ Decompressed (on-chain) light-token ATA-to-ATA transfers. Not for compressed accounts.
288264
289265## Public API — Utilities
290266
@@ -424,12 +400,11 @@ All types must remain byte-identical to the on-chain program. Verified by golden
424400| Constant | Value | Purpose |
425401| ---------- | ------- | --------- |
426402| `TRANSFER2_DISCRIMINATOR ` | `101 ` | Transfer2 instruction discriminator |
427- | `TOKEN_COMPRESSED_ACCOUNT_DISCRIMINATOR ` | `[ 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ` | Compressed token account discriminator |
403+ | `DEFAULT_MAX_TOP_UP ` | `u16 :: MAX ` | Default max top - up for Transfer2 ( no limit ) |
428404| `WSOL_MINT ` | `So11111111111111111111111111111111111111112 ` | Wrapped SOL mint |
429405| `CPI_AUTHORITY_PDA_SEED ` | `b " cpi_authority" ` | Seed for CPI authority derivation |
430406| `BUMP_CPI_AUTHORITY ` | `254 ` | Known bump for CPI authority PDA |
431407| `POOL_SEED ` | `b " pool" ` | Seed for SPL pool PDA derivation |
432- | `NUM_MAX_POOL_ACCOUNTS ` | `5 ` | Maximum pool accounts per mint |
433408| `LIGHT_LUT_MAINNET ` | `9NYFyEqPeWQHiS8Jv4VjZcjKBMPRCJ3KbEbaBcy4Mza` | Mainnet address lookup table |
434409| `LIGHT_LUT_DEVNET ` | `9NYFyEqPeWQHiS8Jv4VjZcjKBMPRCJ3KbEbaBcy4Mza` | Devnet address lookup table |
435410
@@ -452,34 +427,34 @@ All types must remain byte-identical to the on-chain program. Verified by golden
452427
453428| File | Lines | Description |
454429| ------ | ------- | ------------- |
455- | `src / transfer . rs` | 416 | Transfer2 (compressed - to - compressed ) and TransferChecked (ATA - to - ATA ) |
456- | `src / decompress . rs` | 523 | Decompress via Transfer2 with Compression operation |
457- | `src / wrap . rs` | 153 | SPL → light - token via dual - compression Transfer2 (decompressed_accounts_only layout ) |
458- | `src / unwrap . rs` | 187 | Light - token → SPL via dual - compression Transfer2 (decompressed_accounts_only layout ) |
459- | `src / create_ata . rs` | 183 | CreateAssociatedTokenAccount builder with compressible config |
430+ | `src / transfer . rs` | 448 | Transfer2 (compressed - to - compressed ) and TransferChecked (ATA - to - ATA ) |
431+ | `src / decompress . rs` | 554 | Decompress via Transfer2 with Compression operation |
432+ | `src / wrap . rs` | 150 | SPL → light - token via dual - compression Transfer2 (decompressed_accounts_only layout ) |
433+ | `src / unwrap . rs` | 184 | Light - token → SPL via dual - compression Transfer2 (decompressed_accounts_only layout ) |
434+ | `src / create_ata . rs` | 182 | CreateAssociatedTokenAccount builder with compressible config |
460435
461436### Utilities
462437
463438| File | Lines | Description |
464439| ------ | ------- | ------------- |
465- | `src / account_select . rs` | 161 | Greedy descending account selection (max 8 , `MAX_INPUT_ACCOUNTS `) |
466- | `src / load_ata . rs` | 375 | Multi - transaction batch orchestration with compute budget estimation |
440+ | `src / account_select . rs` | 160 | Greedy descending account selection (max 8 , `MAX_INPUT_ACCOUNTS `) |
441+ | `src / load_ata . rs` | 416 | Multi - transaction batch orchestration with compute budget estimation |
467442
468443### Core
469444
470445| File | Lines | Description |
471446| ------ | ------- | ------------- |
472- | `src / lib . rs` | 44 | Module declarations and re - exports |
473- | `src / types . rs` | 560 | All Borsh - serializable types (on - chain mirrors + client - only ) |
474- | `src / program_ids . rs` | 82 | 31 constants (program IDs , PDAs , seeds , LUT addresses ) |
475- | `src / pda . rs` | 78 | 6 PDA derivation functions |
476- | `src / error . rs` | 23 | `KoraLightError ` enum (6 variants ) |
447+ | `src / lib . rs` | 43 | Module declarations and re - exports |
448+ | `src / types . rs` | 559 | All Borsh - serializable types (on - chain mirrors + client - only ) |
449+ | `src / program_ids . rs` | 78 | Constants (program IDs , PDAs , seeds , LUT addresses ) |
450+ | `src / pda . rs` | 77 | 6 PDA derivation functions |
451+ | `src / error . rs` | 22 | `KoraLightError ` enum (6 variants ) |
477452
478453### Tests
479454
480455| File | Lines | Description |
481456| ------ | ------- | ------------- |
482- | `tests / golden_bytes . rs` | 382 | Borsh serialization cross - verification against on - chain format |
457+ | `tests / golden_bytes . rs` | 381 | Borsh serialization cross - verification against on - chain format |
483458| `src / types . rs` (inline ) | ~60 | Borsh verification gates (proof = 128B, context = 7B, compression = 16B, input = 22B, output = 13B) |
484459| `src / ` (inline per module ) | ~200 | Unit tests per module (account order , deduplication , error paths , round - trips ) |
485460
0 commit comments