diff --git a/api-reference/json-rpc-methods/getvalidityproof.mdx b/api-reference/json-rpc-methods/getvalidityproof.mdx index aee8652c..fb4a46d7 100644 --- a/api-reference/json-rpc-methods/getvalidityproof.mdx +++ b/api-reference/json-rpc-methods/getvalidityproof.mdx @@ -210,7 +210,7 @@ async function generateProofForTransfer() { console.log(\` Token accounts: ${hashes.length}\`); console.log(\` Roots: ${validityProof.roots.length}\`); - // This proof is now ready to use with CompressedTokenProgram.transfer() + // This proof is now ready to use with LightTokenProgram.transfer() console.log('\nProof ready for token transfer instruction'); console.log('Use this with:'); console.log(' recentValidityProof: validityProof.compressedProof'); diff --git a/compressed-tokens/advanced-guides/add-wallet-support-for-compressed-tokens.mdx b/compressed-tokens/advanced-guides/add-wallet-support-for-compressed-tokens.mdx index c03840d7..8f7c9112 100644 --- a/compressed-tokens/advanced-guides/add-wallet-support-for-compressed-tokens.mdx +++ b/compressed-tokens/advanced-guides/add-wallet-support-for-compressed-tokens.mdx @@ -128,7 +128,7 @@ import { buildAndSignTx, } from "@lightprotocol/stateless.js"; import { - CompressedTokenProgram, + LightTokenProgram, selectMinCompressedTokenAccountsForTransfer, } from "@lightprotocol/compressed-token"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; @@ -158,7 +158,7 @@ const amount = bn(1e8); inputAccounts.map((account) => account.compressedAccount.hash) ); - const ix = await CompressedTokenProgram.transfer({ + const ix = await LightTokenProgram.transfer({ payer: payer.publicKey, inputCompressedTokenAccounts: inputAccounts, toAddress: recipient.publicKey, @@ -291,7 +291,7 @@ import * as fs from 'fs'; import * as os from 'os'; // 1. Setup RPC connection and load filesystem wallet for mint operations -// 2. Call createMint() to create SPL mint with token pool for compression +// 2. Call createMint() to create SPL mint with SPL interface for compression // 3. Call mintTo() to mint compressed tokens to filesystem wallet const connection: Rpc = createRpc(); // defaults to localhost:8899 @@ -307,7 +307,7 @@ const mintKeypair = Keypair.generate(); await connection.requestAirdrop(payer.publicKey, 1e9); await new Promise(resolve => setTimeout(resolve, 1000)); - // Create SPL mint with token pool for compression + // Create SPL mint with SPL interface for compression const { mint, transactionSignature } = await createMint( connection, payer, @@ -322,7 +322,7 @@ const mintKeypair = Keypair.generate(); const mintToTxId = await mintTo( connection, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression payer.publicKey, // recipient address payer, 10e9, @@ -344,7 +344,7 @@ Make sure you add your Mint address to `send-tokens.ts`. // 1. Load wallet and fetch compressed token accounts with getCompressedTokenAccountsByOwner() // 2. Select accounts for transfer using selectMinCompressedTokenAccountsForTransfer() // and get validity proof with getValidityProof() -// 3. Create transfer instruction with CompressedTokenProgram.transfer() +// 3. Create transfer instruction with LightTokenProgram.transfer() // and submit transaction with sendAndConfirmTx() // 4. Verify balances via getCompressedTokenAccountsByOwner() @@ -357,7 +357,7 @@ import { buildAndSignTx, } from "@lightprotocol/stateless.js"; import { - CompressedTokenProgram, + LightTokenProgram, selectMinCompressedTokenAccountsForTransfer, } from "@lightprotocol/compressed-token"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; @@ -381,7 +381,7 @@ const amount = bn(1e8); // Step 2: Fetch compressed account hashes from state trees const compressedTokenAccounts = await connection.getCompressedTokenAccountsByOwner(owner.publicKey, { - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression }); if (compressedTokenAccounts.items.length === 0) { @@ -405,7 +405,7 @@ const amount = bn(1e8); ); // Step 4: Create transfer instruction that consumes input accounts and creates new output accounts - const ix = await CompressedTokenProgram.transfer({ + const ix = await LightTokenProgram.transfer({ payer: payer.publicKey, inputCompressedTokenAccounts: inputAccounts, // accounts to consume toAddress: recipient.publicKey, @@ -454,7 +454,7 @@ Use these integrations to let users convert between regular and compressed forma -This example converts compressed tokens to regular SPL format using `CompressedTokenProgram.decompress().` +This example converts compressed tokens to regular SPL format using `LightTokenProgram.decompress().` ```javascript import { @@ -467,15 +467,15 @@ import { } from "@lightprotocol/stateless.js"; import { ComputeBudgetProgram } from "@solana/web3.js"; import { - CompressedTokenProgram, + LightTokenProgram, getTokenPoolInfos, selectMinCompressedTokenAccountsForTransfer, selectTokenPoolInfosForDecompression, } from "@lightprotocol/compressed-token"; // 1. Setup RPC connection and fetch compressed token accounts with getCompressedTokenAccountsByOwner() -// 2. Select accounts and token pool infos using selectMinCompressedTokenAccountsForTransfer() and selectTokenPoolInfosForDecompression() -// 3. Create decompress instruction with CompressedTokenProgram.decompress() and submit transaction +// 2. Select accounts and SPL interface infos using selectMinCompressedTokenAccountsForTransfer() and selectTokenPoolInfosForDecompression() +// 3. Create decompress instruction with LightTokenProgram.decompress() and submit transaction // Step 1: Setup RPC connection and define decompression parameters const connection: Rpc = createRpc("https://mainnet.helius-rpc.com?api-key=";); @@ -510,7 +510,7 @@ const amount = 1e5; // 100K tokens to decompress ); // 5. Build instruction - const ix = await CompressedTokenProgram.decompress({ + const ix = await LightTokenProgram.decompress({ payer: payer.publicKey, inputCompressedTokenAccounts: inputAccounts, toAddress: owner.publicKey, @@ -540,12 +540,12 @@ const amount = 1e5; // 100K tokens to decompress -This example converts regular SPL tokens to compressed format using `CompressedTokenProgram.compress().` +This example converts regular SPL tokens to compressed format using `LightTokenProgram.compress().` ```typescript // 1. Setup RPC connection and get user ATA with getOrCreateAssociatedTokenAccount() -// 2. Fetch state tree and token pool infos using getStateTreeInfos() and getTokenPoolInfos() -// 3. Create compress instruction with CompressedTokenProgram.compress() and submit transaction +// 2. Fetch state tree and SPL interface infos using getStateTreeInfos() and getTokenPoolInfos() +// 3. Create compress instruction with LightTokenProgram.compress() and submit transaction import { @@ -557,7 +557,7 @@ import { } from "@lightprotocol/stateless.js"; import { ComputeBudgetProgram } from "@solana/web3.js"; import { - CompressedTokenProgram, + LightTokenProgram, getTokenPoolInfos, selectTokenPoolInfo, } from "@lightprotocol/compressed-token"; @@ -584,12 +584,12 @@ const amount = 1e5; // 100K tokens to compress const treeInfos = await connection.getStateTreeInfos(); const treeInfo = selectStateTreeInfo(treeInfos); - // Step 4: Fetch and select token pool info for compression + // Step 4: Fetch and select SPL interface info for compression const tokenPoolInfos = await getTokenPoolInfos(connection, mint); const tokenPoolInfo = selectTokenPoolInfo(tokenPoolInfos); // Step 5: Create compress instruction - transfer SPL tokens to pool and create compressed accounts - const compressInstruction = await CompressedTokenProgram.compress({ + const compressInstruction = await LightTokenProgram.compress({ payer: payer.publicKey, // fee payer owner: payer.publicKey, // owner of source SPL tokens source: sourceTokenAccount.address, // source ATA address @@ -597,7 +597,7 @@ const amount = 1e5; // 100K tokens to compress amount, // amount to compress mint, // token mint address outputStateTreeInfo: treeInfo, // state tree for compressed accounts - tokenPoolInfo, // token pool for compression + tokenPoolInfo, }); // Step 6: Build, sign, and submit compression transaction diff --git a/compressed-tokens/advanced-guides/airdrop.mdx b/compressed-tokens/advanced-guides/airdrop.mdx index 92c26808..ce18f3ef 100644 --- a/compressed-tokens/advanced-guides/airdrop.mdx +++ b/compressed-tokens/advanced-guides/airdrop.mdx @@ -71,7 +71,7 @@ Run this `mint-spl-tokens.ts` to mint SPL tokens to your wallet. ```typescript mint-spl-tokens.ts expandable // Mint SPL Tokens for Airdrop - LocalNet // 1. Load wallet and connect to local validator -// 2. Create SPL mint with token pool for compression via createMint() +// 2. Create SPL mint with SPL interface via createMint() // 3. Create ATA and mint SPL tokens to sender for airdrop preparation // 4. Output mint address for use in simple-airdrop.ts @@ -82,7 +82,7 @@ import { getOrCreateAssociatedTokenAccount, mintTo, } from "@solana/spl-token"; -import { createTokenPool } from "@lightprotocol/compressed-token"; +import { createSplInterface } from "@lightprotocol/compressed-token"; import * as fs from 'fs'; import * as os from 'os'; @@ -95,18 +95,18 @@ const secretKey = JSON.parse(fs.readFileSync(walletPath, 'utf8')); const payer = Keypair.fromSecretKey(Buffer.from(secretKey)); (async () => { - // Step 2: Create SPL mint with token pool for compression + // Step 2: Create SPL mint with SPL interface const mint = await createMint(connection, payer, payer.publicKey, null, 9); - const poolTxId = await createTokenPool(connection, payer, mint); + const poolTxId = await createSplInterface(connection, payer, mint); console.log(`Mint address: ${mint.toBase58()}`); - console.log(`TokenPool created: ${poolTxId}`); + console.log(`SPL interface created: ${poolTxId}`); // Step 3: Create associated token account for sender // The sender will send tokens from this account to the recipients as compressed tokens. const ata = await getOrCreateAssociatedTokenAccount( connection, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression payer.publicKey ); console.log(`ATA address: ${ata.address.toBase58()}`); @@ -116,7 +116,7 @@ const payer = Keypair.fromSecretKey(Buffer.from(secretKey)); const mintToTxId = await mintTo( connection, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression ata.address, // distributor ATA payer.publicKey, 100_000_000_000 // amount: 100 tokens with 9 decimals @@ -141,13 +141,13 @@ Ensure you have the latest `@lightprotocol/stateless.js` and `@lightprotocol/com ```typescript simple-airdrop.ts expandable highlight={29-30,45,74,100} // Simple Airdrop - LocalNet // 1. Load wallet and select compression infrastructure with getStateTreeInfos() and getTokenPoolInfos() -// 2. Build CompressedTokenProgram.compress() instruction for multiple recipients in one transaction +// 2. Build LightTokenProgram.compress() instruction for multiple recipients in one transaction // 3. Execute transaction with compute budget and confirm compression operation with sendAndConfirmTx() // 4. Verify distribution via getCompressedTokenAccountsByOwner import { Keypair, PublicKey, ComputeBudgetProgram } from "@solana/web3.js"; import { - CompressedTokenProgram, + LightTokenProgram, getTokenPoolInfos, selectTokenPoolInfo, } from "@lightprotocol/compressed-token"; @@ -175,7 +175,7 @@ const payer = Keypair.fromSecretKey(Buffer.from(secretKey)); const owner = payer; (async () => { - // Step 2: Select state tree and token pool + // Step 2: Select state tree and SPL interface const activeStateTrees = await connection.getStateTreeInfos(); const treeInfo = selectStateTreeInfo(activeStateTrees); @@ -187,7 +187,7 @@ const owner = payer; const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( connection, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression payer.publicKey ); @@ -221,13 +221,13 @@ const owner = payer; ); // Create compression instruction for multiple recipients in one transaction - const compressInstruction = await CompressedTokenProgram.compress({ + const compressInstruction = await LightTokenProgram.compress({ payer: payer.publicKey, owner: owner.publicKey, source: sourceTokenAccount.address, // source ATA holding SPL tokens toAddress: airDropAddresses, // recipient addresses for compressed tokens amount: amounts, // different amounts for each recipient - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression tokenPoolInfo: info, outputStateTreeInfo: treeInfo, // destination state tree }); @@ -346,7 +346,7 @@ Run the airdrop script with your configured environment: ```typescript expandable // 1. Load environment and select compression infrastructure with getStateTreeInfos() and getTokenPoolInfos() -// 2. Build CompressedTokenProgram.compress() instruction for multiple recipients in one transaction +// 2. Build LightTokenProgram.compress() instruction for multiple recipients in one transaction // 3. Execute transaction with compute budget, address lookup table, and confirm with sendAndConfirmTx() // 4. Verify distribution via getCompressedTokenAccountsByOwner @@ -356,7 +356,7 @@ import { ComputeBudgetProgram, } from '@solana/web3.js'; import { - CompressedTokenProgram, + LightTokenProgram, getTokenPoolInfos, selectTokenPoolInfo, } from '@lightprotocol/compressed-token'; @@ -387,7 +387,7 @@ import { MINT_ADDRESS, PAYER_KEYPAIR, RPC_ENDPOINT } from '../constants'; const treeInfos = await connection.getStateTreeInfos(); // Fixed: removed deprecated getCachedActiveStateTreeInfos const treeInfo = selectStateTreeInfo(treeInfos); - // 2. Select a token pool + // 2. Select SPL interface const tokenPoolInfos = await getTokenPoolInfos(connection, mintAddress); const tokenPoolInfo = selectTokenPoolInfo(tokenPoolInfos); @@ -415,7 +415,7 @@ import { MINT_ADDRESS, PAYER_KEYPAIR, RPC_ENDPOINT } from '../constants'; }), ]; - const compressInstruction = await CompressedTokenProgram.compress({ + const compressInstruction = await LightTokenProgram.compress({ payer: payer.publicKey, owner: owner.publicKey, source: sourceTokenAccount.address, @@ -479,12 +479,12 @@ Process recipients in chunks and create batched instructions with optimized comp ```typescript create-instructions.ts expandable -// 1. Process recipients in chunks with selectStateTreeInfo() and selectTokenPoolInfo() for each batch -// 2. Create CompressedTokenProgram.compress() instructions with ComputeBudgetProgram limits for multiple recipients +// 1. Process recipients in chunks with selectStateTreeInfo() and selectTokenPoolInfo() per batch +// 2. Create LightTokenProgram.compress() instructions with ComputeBudgetProgram limits for multiple recipients // 3. Return batched instructions for optimized large-scale airdrop execution import { - CompressedTokenProgram, + LightTokenProgram, TokenPoolInfo, } from "@lightprotocol/compressed-token"; import { @@ -561,7 +561,7 @@ export async function createAirdropInstructions({ if (recipientBatch.length === 0) break; - const compressIx = await CompressedTokenProgram.compress({ + const compressIx = await LightTokenProgram.compress({ payer, owner: payer, source: sourceTokenAccount, @@ -765,8 +765,8 @@ export async function* signAndSendAirdropBatches( Put it all together in the main airdrop file. ```typescript airdrop.ts expandable -// 1. Create compressed mint with createMint(), mint supply with mintTo(), get infrastructure with getStateTreeInfos() and getTokenPoolInfos() -// 2. Generate batched compression instructions with createAirdropInstructions() - create CompressedTokenProgram.compress() calls +// 1. Create compressed mint with createMint(), mint supply with mintTo(), get infrastructure with getStateTreeInfos() and getTokenPoolInfos() (SPL interface infos) +// 2. Generate batched compression instructions with createAirdropInstructions() - create LightTokenProgram.compress() calls // 3. Execute batched airdrop with signAndSendAirdropBatches() - sign transactions and confirm with sendAndConfirmTx() for large-scale distribution import { Keypair, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; @@ -851,7 +851,7 @@ const recipients = [ // 6a: Fetch available state trees for compressed account storage const stateTreeInfos = await connection.getStateTreeInfos(); - // 6b: Get token pool infos for compression operations + // 6b: Get SPL interface infos for compression const tokenPoolInfos = await getTokenPoolInfos(connection, mint); // Step 7: Create instruction batches for large-scale airdrop @@ -863,7 +863,7 @@ const recipients = [ sourceTokenAccount: ata.address, // source ATA holding SPL tokens mint, // token mint stateTreeInfos, // state trees for compressed accounts - tokenPoolInfos, // token pools for compression + tokenPoolInfos, computeUnitPrice: calculateComputeUnitPrice(10_000, 500_000), // dynamic priority fee }); @@ -913,7 +913,7 @@ import { } from "@lightprotocol/stateless.js"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; import { - CompressedTokenProgram, + LightTokenProgram, getTokenPoolInfos, selectMinCompressedTokenAccountsForTransfer, selectTokenPoolInfosForDecompression, @@ -958,7 +958,7 @@ const connection: Rpc = createRpc(RPC_ENDPOINT); inputAccounts.map((account) => account.compressedAccount.hash) ); - // 5. Fetch token pool infos + // 5. Fetch SPL interface infos const tokenPoolInfos = await getTokenPoolInfos(connection, mint); // 6. Select @@ -968,7 +968,7 @@ const connection: Rpc = createRpc(RPC_ENDPOINT); ); // 7. Build instruction - const ix = await CompressedTokenProgram.decompress({ + const ix = await LightTokenProgram.decompress({ payer: payer.publicKey, inputCompressedTokenAccounts: inputAccounts, toAddress: ata.address, diff --git a/compressed-tokens/advanced-guides/how-to-combine-operations-in-one-transaction.mdx b/compressed-tokens/advanced-guides/how-to-combine-operations-in-one-transaction.mdx index 3201b90c..26fc80a6 100644 --- a/compressed-tokens/advanced-guides/how-to-combine-operations-in-one-transaction.mdx +++ b/compressed-tokens/advanced-guides/how-to-combine-operations-in-one-transaction.mdx @@ -1,6 +1,6 @@ --- title: Combine Instructions in One Transaction -description: Guide to combine multiple instructions in a single transaction. Full code example for token pool creation and for first-time compression of existing SPL tokens. +description: Combine multiple instructions in one transaction. Full example: create SPL Interface PDA and first-time compression of existing SPL tokens. keywords: ["batch token operations solana", "combine transactions solana"] --- @@ -9,7 +9,7 @@ import SetupEnvironment from '/snippets/setup/setup-environment-tabs.mdx'; The SDK provides instruction-level APIs that return instructions without sending transactions. Combine these instructions to build custom transactions with multiple instructions. -This guide demonstrates creating a token pool and compressing existing SPL tokens in a single transaction. +This guide demonstrates creating an SPL interface and compressing existing SPL tokens in a single transaction. # Full Code Example @@ -32,11 +32,11 @@ Make sure you have dependencies and developer environment set up! -### Create Token Pool + Compress +### Create SPL interface + compress ```typescript create-pool-and-compress.ts highlight={26,71} expandable // 1. Setup: Create regular SPL token and mint to ATA -// 2. Build instructions for create token pool and compress +// 2. Build instructions for SPL interface and compress // 3. Combine instructions in one transaction // 4. Verify compressed balance @@ -50,7 +50,7 @@ import { sendAndConfirmTx, selectStateTreeInfo, } from '@lightprotocol/stateless.js'; -import { CompressedTokenProgram } from '@lightprotocol/compressed-token'; +import { LightTokenProgram } from '@lightprotocol/compressed-token'; import { createMint, getOrCreateAssociatedTokenAccount, @@ -105,20 +105,20 @@ async function createPoolAndCompress() { console.log("Regular SPL token created:", mint.toBase58()); console.log("ATA balance:", 1, "token"); - // Step 2: Build instructions for create token pool and compress + // Step 2: Build instructions for SPL interface and compress const outputStateTreeInfo = selectStateTreeInfo(await rpc.getStateTreeInfos()); - // Derive token pool PDA - const tokenPoolPda = CompressedTokenProgram.deriveTokenPoolPda(mint); + // Derive SPL Interface PDA + const tokenPoolPda = LightTokenProgram.deriveTokenPoolPda(mint); - // Create token pool instruction - const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({ + // Create SPL interface instruction + const createSplInterfaceIx = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint, - tokenProgram: TOKEN_PROGRAM_ID, + tokenProgramId: TOKEN_PROGRAM_ID, }); - // Manually construct TokenPoolInfo for first-time compression + // Manually construct TokenPoolInfo for first-time compression (SPL interface not yet on-chain) const tokenPoolInfo = { mint: mint, tokenPoolPda: tokenPoolPda, @@ -130,7 +130,7 @@ async function createPoolAndCompress() { }; // Create compress instruction - const compressIx = await CompressedTokenProgram.compress({ + const compressIx = await LightTokenProgram.compress({ outputStateTreeInfo, tokenPoolInfo, payer: payer.publicKey, @@ -146,7 +146,7 @@ async function createPoolAndCompress() { const allInstructions = [ ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), - createTokenPoolIx, + createSplInterfaceIx, compressIx, ]; diff --git a/compressed-tokens/advanced-guides/use-token-2022-with-compression.mdx b/compressed-tokens/advanced-guides/use-token-2022-with-compression.mdx index 0afaf0a1..25597daa 100644 --- a/compressed-tokens/advanced-guides/use-token-2022-with-compression.mdx +++ b/compressed-tokens/advanced-guides/use-token-2022-with-compression.mdx @@ -64,14 +64,14 @@ Run `compress-t22.ts`. ```typescript compress-t22.ts expandable // Token-2022 with ZK Compression - Local // 1. Load wallet and connect to local validator -// 2. Create Token-2022 mint with metadata extension and register for compression via createTokenPool() +// 2. Create Token-2022 mint with metadata extension and register for compression via createSplInterface() // 3. Mint SPL tokens to ATA, compress via compress(), and transfer compressed tokens via transfer() // 4. Verify balances via getTokenAccountBalance and getCompressedTokenAccountsByOwner import { confirmTx, createRpc } from "@lightprotocol/stateless.js"; import { compress, - createTokenPool, + createSplInterface, transfer, } from "@lightprotocol/compressed-token"; import { @@ -177,10 +177,10 @@ const connection = createRpc(); // defaults to localhost:8899 ); console.log(`Token-2022 mint created with address: ${mint.publicKey.toString()}`); - // Step 3: Call createTokenPool() to initialize omnibus account + // Step 3: Call createSplInterface() to initialize omnibus account // and register Token-2022 mint with Light Token Program // Create PDA that holds SPL tokens for compressed tokens - const registerTxId = await createTokenPool( + const registerTxId = await createSplInterface( connection, payer, mint.publicKey, // Token-2022 mint to register with Light Token Program @@ -192,7 +192,7 @@ const connection = createRpc(); // defaults to localhost:8899 const ata = await getOrCreateAssociatedTokenAccount( connection, payer, - mint.publicKey, // Token-2022 mint with token pool for compression + mint.publicKey, // Token-2022 mint with SPL interface for compression payer.publicKey, undefined, undefined, @@ -205,7 +205,7 @@ const connection = createRpc(); // defaults to localhost:8899 const mintToTxId = await mintToSpl( connection, payer, - mint.publicKey, // Token-2022 mint with token pool for compression + mint.publicKey, // Token-2022 mint with SPL interface for compression ata.address, // destination token account payer.publicKey, // mint authority mintAmount, // amount to mint @@ -222,7 +222,7 @@ const connection = createRpc(); // defaults to localhost:8899 const compressTxId = await compress( connection, payer, - mint.publicKey, // Token-2022 mint with token pool for compression + mint.publicKey, // Token-2022 mint with SPL interface for compression compressAmount, // amount to compress payer, // owner of SPL tokens ata.address, // Source ATA for compression @@ -237,7 +237,7 @@ const connection = createRpc(); // defaults to localhost:8899 const transferTxId = await transfer( connection, payer, - mint.publicKey, // Token-2022 mint with token pool for compression + mint.publicKey, // Token-2022 mint with SPL interface for compression transferAmount, payer, transferRecipient.publicKey diff --git a/compressed-tokens/for-privy.mdx b/compressed-tokens/for-privy.mdx index a7200aa6..035d3061 100644 --- a/compressed-tokens/for-privy.mdx +++ b/compressed-tokens/for-privy.mdx @@ -96,7 +96,7 @@ const rpc = createRpc(RPC_ENDPOINT); Before we call compress or decompresss, we need: -* An SPL mint with a interface PDA for compression. This PDA can be created for new SPL mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or added to existing SPL mints via [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). +* An SPL mint with a interface PDA for compression. This PDA can be created for new SPL mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or added to existing SPL mints via [`createSplInterface()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). * For `compress()` SPL tokens in an Associated Token Account, or * For `decompress()` compressed token accounts with sufficient balance. diff --git a/compressed-tokens/guides/add-token-pools-to-mint-accounts.mdx b/compressed-tokens/guides/add-token-pools-to-mint-accounts.mdx index d0f1da85..bcc62989 100644 --- a/compressed-tokens/guides/add-token-pools-to-mint-accounts.mdx +++ b/compressed-tokens/guides/add-token-pools-to-mint-accounts.mdx @@ -1,22 +1,22 @@ --- -title: Create Token Pools for Compression to Existing Mints -description: "Create a token pool for an existing SPL mint. Requires only fee_payer with no mint authority constraint." -keywords: ["compressed token pools", "token pool on solana"] +title: Create SPL Interface for Existing Mints +description: "Create an SPL Interface PDA (omnibus account) for an existing SPL mint. Requires only fee_payer with no mint authority constraint." +keywords: ["SPL interface", "compression", "omnibus account"] --- import FullSetup from "/snippets/setup/full-setup.mdx"; import ActionCode from '/snippets/code-snippets/compressed-token/create-token-pool/action.mdx'; -Create a token for compression fo an existing SPL mint. `createTokenPool()` requires only `fee_payer` and has no mint authority constraint. +Create an SPL interface (omnibus account) for an existing SPL mint. `createSplInterface()` requires only `fee_payer` and has no mint authority constraint. -The token pool account itself requires rent, but individual compressed token accounts are rent-free. +The SPL Interface PDA requires rent; individual compressed token accounts are rent-free. ```typescript function-create-token-pool.ts -// Creates token pool account for existing SPL mint -const transactionSignature = await createTokenPool( +// Creates SPL interface (omnibus account) for existing SPL mint +const transactionSignature = await createSplInterface( rpc, payer, mint, @@ -25,14 +25,14 @@ const transactionSignature = await createTokenPool( -**Best Practice:** Each mint supports a maximum of 4 token pools total. During compression/decompression operations, token pools get write-locked. Use `addTokenPools()` to create additional pools that increase per-block write-lock capacity. +**Best Practice:** Each mint supports up to 4 SPL interfaces. During compression/decompression, SPL Interface PDAs get write-locked. Use `addTokenPools()` to create additional interfaces and increase per-block write-lock capacity. ## Get Started -### Create Token Pool +### Create SPL interface @@ -43,14 +43,13 @@ const transactionSignature = await createTokenPool( # Troubleshooting - + -You're trying to access a token pool that doesn't exist. +The mint has no SPL Interface PDA. ```typescript -// Create the missing token pool -const poolTx = await createTokenPool(rpc, payer, mint); -console.log("Token pool created:", poolTx); +const poolTx = await createSplInterface(rpc, payer, mint); +console.log("SPL interface created:", poolTx); ``` @@ -59,9 +58,9 @@ console.log("Token pool created:", poolTx); # Advanced Configuration - + -Create pools for multiple mints: +Create SPL interfaces for multiple mints: ```typescript const mints = [ @@ -72,8 +71,8 @@ const mints = [ for (const mint of mints) { try { - const poolTx = await createTokenPool(rpc, payer, mint); - console.log(`Pool created for ${mint.toBase58()}:`, poolTx); + const poolTx = await createSplInterface(rpc, payer, mint); + console.log(`SPL interface created for ${mint.toBase58()}:`, poolTx); } catch (error) { console.log(`Failed for ${mint.toBase58()}:`, error.message); } @@ -82,14 +81,14 @@ for (const mint of mints) { - + -Create token pools for Token-2022 mints: +Create SPL interface for Token-2022 mints: ```typescript import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'; -const poolTx = await createTokenPool( +const poolTx = await createSplInterface( rpc, payer, mint, // Token-2022 mint diff --git a/compressed-tokens/guides/compress-decompress.mdx b/compressed-tokens/guides/compress-decompress.mdx index 8b9e2b73..af196600 100644 --- a/compressed-tokens/guides/compress-decompress.mdx +++ b/compressed-tokens/guides/compress-decompress.mdx @@ -15,7 +15,7 @@ import DecompressActionCode from '/snippets/code-snippets/compressed-token/decom const compressionSignature = await compress( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression amount, payer, // owner of SPL tokens tokenAccount.address, // source SPL token account (sourceTokenAccount parameter) @@ -28,7 +28,7 @@ const compressionSignature = await compress( const transactionSignature = await decompress( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression amount, payer, // owner of compressed tokens tokenAccount.address, // destination token account (toAddress parameter) @@ -54,7 +54,7 @@ const transactionSignature = await decompress( Before we can compress or decompresss, we need: -* An SPL mint with a token pool for compression. This token pool can be created for new SPL mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or added to existing SPL mints via [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). +* An SPL mint with an SPL interface. Create one for new mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or for existing mints via [`createSplInterface()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). * For `compress()` SPL tokens in an Associated Token Account, or * For `decompress()` compressed token accounts with sufficient balance. diff --git a/compressed-tokens/guides/compress-spl-token-account.mdx b/compressed-tokens/guides/compress-spl-token-account.mdx index 1d26a2c1..3c0d1d6e 100644 --- a/compressed-tokens/guides/compress-spl-token-account.mdx +++ b/compressed-tokens/guides/compress-spl-token-account.mdx @@ -14,7 +14,7 @@ import ActionCode from '/snippets/code-snippets/compressed-token/compress-spl-ac const transactionSignature = await compressSplTokenAccount( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression owner, tokenAccount, // SPL token account to compress ); @@ -25,7 +25,7 @@ const transactionSignature = await compressSplTokenAccount( const transactionSignature = await compressSplTokenAccount( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression owner, tokenAccount, // SPL token account to compress remainingAmount, // amount to keep in SPL format @@ -181,7 +181,7 @@ for (const { account, owner } of tokenAccounts) { # Next Steps ```typescript createMint() -// Create SPL mint with token pool for compression +// Create SPL mint with SPL interface for compression const { mint, transactionSignature } = await createMint( rpc, payer, @@ -24,14 +24,14 @@ const { mint, transactionSignature } = await createMint( -**Best Practice:** Each mint supports a maximum of 4 token pools total. During compression/decompression, token pools get write-locked. Use `addTokenPools()` to create additional pools that increase per-block write-lock capacity. +**Best Practice:** Each mint supports up to 4 SPL interfaces. During compression/decompression, SPL Interface PDAs get write-locked. Use `addTokenPools()` to create additional interfaces and increase per-block write-lock capacity. ## Get Started -### Create a Mint Account with Token Pool for Compression +### Create a mint with SPL interface for compression @@ -91,7 +91,7 @@ const { mint, transactionSignature } = await createMint( # Next Steps diff --git a/compressed-tokens/guides/merge-compressed-token-accounts.mdx b/compressed-tokens/guides/merge-compressed-token-accounts.mdx index e2d53e69..278547b2 100644 --- a/compressed-tokens/guides/merge-compressed-token-accounts.mdx +++ b/compressed-tokens/guides/merge-compressed-token-accounts.mdx @@ -24,7 +24,7 @@ State trees where compressed account's are stored, are append only. `mergeTokenA const transactionSignature = await mergeTokenAccounts( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression owner, ); ``` @@ -44,7 +44,7 @@ const transactionSignature = await mergeTokenAccounts( Before we merge compressed accounts, we need * Multiple compressed token accounts of the same mint owned by the same wallet, and -* an SPL mint with a token pool for compression. This token pool can be created for new SPL mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or added to existing SPL mints via [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). +* an SPL mint with an SPL interface. Create one for new mints via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or for existing mints via [`createSplInterface()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). diff --git a/compressed-tokens/guides/mint-compressed-tokens.mdx b/compressed-tokens/guides/mint-compressed-tokens.mdx index 9ff7323a..fe5b0fa4 100644 --- a/compressed-tokens/guides/mint-compressed-tokens.mdx +++ b/compressed-tokens/guides/mint-compressed-tokens.mdx @@ -1,7 +1,6 @@ --- title: Mint Compressed Tokens -description: "Mint tokens to compressed token accounts for recipients and increases a mint's token supply. Only the mint authority can perform this operation. -" +description: "Mint tokens to compressed token accounts for recipients and increases a mint's token supply. Only the mint authority can perform this operation." keywords: ["mint compressed tokens on solana", "scalable token minting"] --- @@ -15,7 +14,7 @@ import InstructionCode from '/snippets/code-snippets/compressed-token/mint-to/in const transactionSignature = await mintTo( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression recipient, // recipient address (toPubkey parameter) payer, // mint authority amount, @@ -46,30 +45,30 @@ const transactionSignature = await mintTo( # Troubleshooting - + ```typescript -// Error message: "TokenPool not found. Please create a compressed token -// pool for mint: [ADDRESS] via createTokenPool(). +// Error: SPL interface not found for this mint. Create a compressed token +// SPL interface PDA for mint: [ADDRESS] via createSplInterface(). ``` -The mint does no have a token pool for compression. Ensure you created the mint using `createMint`. +The mint has no SPL Interface PDA. Ensure you created the mint using `createMint` or call `createSplInterface()` for an existing mint. ```typescript -// Create mint with token pool for compression +// Create mint with SPL interface for compression import { createMint } from '@lightprotocol/compressed-token'; const { mint } = await createMint(rpc, payer, payer.publicKey, 9); ``` - + -The token pool info doesn't correspond to the mint address. Ensure you're fetching the correct pool: +The SPL interface info doesn't correspond to the mint address. Ensure you're fetching the correct interface: ```typescript -// Get the correct token pool for your mint +// Get SPL interface infos for your mint const tokenPoolInfo = await getTokenPoolInfos(rpc, mint); ``` @@ -114,7 +113,7 @@ const amounts = [ const transactionSignature = await mintTo( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression recipients, // array of recipients (toPubkey parameter) payer, // mint authority amounts, // array of amounts (amount parameter) @@ -134,7 +133,7 @@ import { approveAndMintTo } from '@lightprotocol/compressed-token'; const transactionSignature = await approveAndMintTo( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression recipient.publicKey, // recipient of minted tokens (toPubkey parameter) mintAuthority, // mint authority mintAmount, diff --git a/compressed-tokens/guides/transfer-compressed-tokens.mdx b/compressed-tokens/guides/transfer-compressed-tokens.mdx index 41720feb..3e10eb27 100644 --- a/compressed-tokens/guides/transfer-compressed-tokens.mdx +++ b/compressed-tokens/guides/transfer-compressed-tokens.mdx @@ -21,7 +21,7 @@ SPL token accounts can be compressed in the same transaction with `compress_or_d const transactionSignature = await transfer( rpc, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression amount, payer, recipient, // destination address (toAddress parameter) diff --git a/light-token/cookbook/create-ata.mdx b/light-token/cookbook/create-ata.mdx index 736fc4aa..fc52f275 100644 --- a/light-token/cookbook/create-ata.mdx +++ b/light-token/cookbook/create-ata.mdx @@ -5,8 +5,6 @@ description: Client and program guide to create associated Light Token accounts. keywords: ["associated token account on solana", "create ata for solana tokens", "rent free ata on solana", "rent free accounts on solana"] --- ---- - import TokenCreateATAAccountsList from "/snippets/accounts-list/light-token-create-ata-accounts-list.mdx"; import TokenConfigureRent from "/snippets/light-token-configure-rent.mdx"; import CompressibleRentExplained from "/snippets/compressible-rent-explained.mdx"; @@ -54,7 +52,7 @@ Compare to SPL: Find the source code - [here](https://github.com/Lightprotocol/light-protocol/blob/0c4e2417b2df2d564721b89e18d1aad3665120e7/js/compressed-token/src/v3/actions/create-ata-interface.ts). + [here](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/create-ata-interface.ts). diff --git a/light-token/cookbook/load-ata.mdx b/light-token/cookbook/load-ata.mdx index 0f20c3e7..57a63441 100644 --- a/light-token/cookbook/load-ata.mdx +++ b/light-token/cookbook/load-ata.mdx @@ -5,8 +5,6 @@ description: Unify token balances from compressed tokens (cold Light Tokens), SP keywords: ["load ata on solana", "get token balance for wallets"] --- ---- - import FullSetup from "/snippets/setup/full-setup.mdx"; import ActionCode from "/snippets/code-snippets/light-token/load-ata/action.mdx"; import InstructionCode from "/snippets/code-snippets/light-token/load-ata/instruction.mdx"; @@ -21,7 +19,7 @@ import InstructionCode from "/snippets/code-snippets/light-token/load-ata/instru 3. Creates the ATA if it doesn't exist -Find the source code [here](https://github.com/Lightprotocol/light-protocol/blob/0c4e2417b2df2d564721b89e18d1aad3665120e7/js/compressed-token/src/v3/actions/load-ata.ts). +Find the source code [here](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/load-ata.ts). diff --git a/light-token/cookbook/transfer-interface.mdx b/light-token/cookbook/transfer-interface.mdx index 7d55c284..a315c4c1 100644 --- a/light-token/cookbook/transfer-interface.mdx +++ b/light-token/cookbook/transfer-interface.mdx @@ -4,8 +4,6 @@ description: Program and client guide for transfers between Light Token and SPL keywords: ["transfer tokens on solana", "token transfer on solana", "interface methods on solana", "spl transfer for developers"] --- ---- - import TransferInterfaceIntro from "/snippets/light-token-guides/transfer-interface-intro.mdx"; import TokenClientPrerequisites from "/snippets/light-token-guides/light-token-client-prerequisites.mdx"; import TokenTsClientPrerequisites from "/snippets/light-token-guides/light-token-ts-client-prerequisites.mdx"; @@ -74,7 +72,7 @@ Compare to SPL: Find the source code - [here](https://github.com/Lightprotocol/light-protocol/blob/0c4e2417b2df2d564721b89e18d1aad3665120e7/js/compressed-token/src/v3/actions/transfer-interface.ts). + [here](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/transfer-interface.ts). diff --git a/light-token/toolkits/for-payments.mdx b/light-token/toolkits/for-payments.mdx index 5877d295..bc1cae9b 100644 --- a/light-token/toolkits/for-payments.mdx +++ b/light-token/toolkits/for-payments.mdx @@ -9,7 +9,7 @@ import { CodeCompare } from "/snippets/jsx/code-compare.jsx"; import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; 1. The light-token API matches the SPL-token API almost entirely, and extends their functionality to include the light token program in addition to the SPL-token and Token-2022 programs. -2. Your users receive the same stablecoin, just stored more efficiently. +2. Your users use the same stablecoins, just stored more efficiently. | Creation Cost | SPL | light-token | | :---------------- | :------------------ | :------------------- | @@ -27,19 +27,14 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; - **Get/Create ATA** + **Receive** getOrCreateAssociatedTokenAccount() - getOrCreateAtaInterface() - - - **Derive ATA** - getAssociatedTokenAddress() - getAssociatedTokenAddressInterface() + createLoadAtaInstructions() **Transfer** - transferChecked() - transferInterface() + createTransferInstruction() + createTransferInterfaceInstructions() **Get Balance** @@ -54,18 +49,18 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; **Wrap from SPL** N/A - wrap() + createWrapInstruction() **Unwrap to SPL** N/A - unwrap() + createUnwrapInstructions() / unwrap() - Find full code examples + Find full runnable code examples [here](https://github.com/Lightprotocol/examples-light-token/tree/main/toolkits/payments-and-wallets). @@ -73,114 +68,112 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; +Snippets below assume `rpc`, `payer`, `mint`, `owner`, `recipient`, and `amount` are defined. +See the [full examples](https://github.com/Lightprotocol/examples-light-token/tree/main/toolkits/payments-and-wallets) for runnable setup. + ```typescript import { createRpc } from "@lightprotocol/stateless.js"; import { - getOrCreateAtaInterface, - getAtaInterface, - getAssociatedTokenAddressInterface, + createLoadAtaInstructions, + loadAta, + createTransferInterfaceInstructions, transferInterface, - wrap, + createUnwrapInstructions, unwrap, + getAssociatedTokenAddressInterface, + getAtaInterface, + wrap, } from "@lightprotocol/compressed-token/unified"; const rpc = createRpc(RPC_ENDPOINT); ``` -### Receive Payments +### One-time: Register an Existing SPL Mint + +For existing SPL mints (e.g. USDC), register the SPL interface once. This creates the omnibus PDA that holds SPL tokens when wrapped to light-token. -Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-and-receive.ts). +Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/register-spl-mint.ts). - - +Check if the interface already exists: ```typescript -import { Transaction } from "@solana/web3.js"; -import { - createAssociatedTokenAccountInterfaceIdempotentInstruction, - createLoadAtaInstructions, - getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token/unified"; -import { LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; - -const ata = getAssociatedTokenAddressInterface(mint, recipient); +import { getSplInterfaceInfos } from "@lightprotocol/compressed-token"; -const tx = new Transaction().add( - createAssociatedTokenAccountInterfaceIdempotentInstruction( - payer.publicKey, - ata, - recipient, - mint, - LIGHT_TOKEN_PROGRAM_ID - ), - ...(await createLoadAtaInstructions( - rpc, - ata, - recipient, - mint, - payer.publicKey - )) -); +try { + const infos = await getSplInterfaceInfos(rpc, mint); + const exists = infos.some((i) => i.isInitialized); + console.log("Interface exists:", exists); +} catch { + console.log("No interface registered for this mint."); +} ``` - +Register: + + + ```typescript -import { - createAssociatedTokenAccountInstruction, - getAssociatedTokenAddressSync, -} from "@solana/spl-token"; +import { Transaction, sendAndConfirmTransaction } from "@solana/web3.js"; +import { LightTokenProgram } from "@lightprotocol/compressed-token"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; -const ata = getAssociatedTokenAddressSync(mint, recipient); +const ix = await LightTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint, + tokenProgramId: TOKEN_PROGRAM_ID, +}); -const tx = new Transaction().add( - createAssociatedTokenAccountInstruction(payer.publicKey, ata, recipient, mint) -); +const tx = new Transaction().add(ix); +await sendAndConfirmTransaction(rpc, tx, [payer]); ``` - - + ```typescript -import { getOrCreateAtaInterface } from "@lightprotocol/compressed-token/unified"; +import { createSplInterface } from "@lightprotocol/compressed-token"; -const ata = await getOrCreateAtaInterface(rpc, payer, mint, recipient); -// Share ata.parsed.address with sender - -console.log(ata.parsed.amount); +await createSplInterface(rpc, payer, mint); ``` - + + + + + +Use `createMintInterface` with `TOKEN_PROGRAM_ID` to create a new SPL mint and register the interface in one transaction: ```typescript -import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token"; +import { createMintInterface } from "@lightprotocol/compressed-token/unified"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; -const ata = await getOrCreateAssociatedTokenAccount( - connection, - payer, - mint, - recipient +const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, undefined, undefined, TOKEN_PROGRAM_ID ); -// Share ata.address with sender - -console.log(ata.amount); ``` - - + +**About loading**: Light tokens reduce account rent ~200x by auto-compressing inactive +accounts. Before any action, the SDK detects compressed state and adds +instructions to load it back on-chain. This almost always fits in a single +atomic transaction with your regular transfer. APIs return `TransactionInstruction[][]` so the same +loop handles the rare multi-transaction case automatically. + -### Send Payments +### Receive Payments -Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-and-receive.ts). +Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/receive.ts). +Load creates the associated token account (ATA) if needed and loads any compressed state into it. Share the ATA address with the sender. + @@ -188,86 +181,159 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- import { Transaction } from "@solana/web3.js"; import { createLoadAtaInstructions, - createTransferInterfaceInstruction, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token/unified"; -const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); +const ata = getAssociatedTokenAddressInterface(mint, recipient); -const tx = new Transaction().add( - ...(await createLoadAtaInstructions( - rpc, - sourceAta, - owner.publicKey, - mint, - payer.publicKey - )), - createTransferInterfaceInstruction( - sourceAta, - destinationAta, - owner.publicKey, - amount - ) +// Returns TransactionInstruction[][]. +// Each inner array is one transaction. +// Almost always returns just one. +const instructions = await createLoadAtaInstructions( + rpc, + ata, + recipient, + mint, + payer.publicKey ); + +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + + // sign and send ... +} ``` -To ensure your recipient's ATA exists, prepend an idempotent creation instruction: + + ```typescript -import { Transaction } from "@solana/web3.js"; import { - createAssociatedTokenAccountInterfaceIdempotentInstruction, - createLoadAtaInstructions, - createTransferInterfaceInstruction, + loadAta, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token/unified"; -import { LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; -const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); +const ata = getAssociatedTokenAddressInterface(mint, recipient); -const tx = new Transaction().add( - createAssociatedTokenAccountInterfaceIdempotentInstruction( - payer.publicKey, - destinationAta, - recipient, - mint, - LIGHT_TOKEN_PROGRAM_ID - ), - ...(await createLoadAtaInstructions( - rpc, - sourceAta, - owner.publicKey, - mint, - payer.publicKey - )), - createTransferInterfaceInstruction( - sourceAta, - destinationAta, - owner.publicKey, - amount - ) -); +const sig = await loadAta(rpc, ata, recipient, mint, payer); +if (sig) console.log("Loaded:", sig); ``` + + + ```typescript import { + createAssociatedTokenAccountInstruction, getAssociatedTokenAddressSync, - createTransferInstruction, + getOrCreateAssociatedTokenAccount, } from "@solana/spl-token"; -const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressSync(mint, recipient); +const ata = getAssociatedTokenAddressSync(mint, recipient); +// Instruction: const tx = new Transaction().add( - createTransferInstruction(sourceAta, destinationAta, owner.publicKey, amount) + createAssociatedTokenAccountInstruction(payer.publicKey, ata, recipient, mint) +); + +// Action: +const ata = await getOrCreateAssociatedTokenAccount( + connection, payer, mint, recipient +); +``` + + + +### Send Payments + + +Find a full code example: [instruction](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-instruction.ts) | [action](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-action.ts). + + + + + +```typescript +import { Transaction } from "@solana/web3.js"; +import { createTransferInterfaceInstructions } from "@lightprotocol/compressed-token/unified"; + +// Returns TransactionInstruction[][]. +// Each inner array is one transaction. +// Almost always returns just one. +const instructions = await createTransferInterfaceInstructions( + rpc, + payer.publicKey, + mint, + amount, + owner.publicKey, + recipient ); + +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + + // sign and send ... +} ``` -With idempotent ATA creation: +Your app logic may require you to create a single sign request for your user. Here's how to do this: + + + +```typescript +const transactions = instructions.map((ixs) => new Transaction().add(...ixs)); + +// One approval for all +const signed = await wallet.signAllTransactions(transactions); + +for (const tx of signed) { + // send... + await sendAndConfirmTransaction(rpc, tx); +} +``` + + + +While almost always you will have only one transfer transaction, you can +optimize sending in the rare cases where you have multiple transactions. +parallelize the loads, confirm them, and then send the transfer instruction +after. + + +```typescript +import { + createTransferInterfaceInstructions, + sliceLast, +} from "@lightprotocol/compressed-token/unified"; + +const instructions = await createTransferInterfaceInstructions( + rpc, + payer.publicKey, + mint, + amount, + owner.publicKey, + recipient +); +const { rest: loadInstructions, last: transferInstructions } = sliceLast(instructions); +// empty = nothing to load, will no-op. +await Promise.all( + loadInstructions.map((ixs) => { + const tx = new Transaction().add(...ixs); + tx.sign(payer, owner); + return sendAndConfirmTransaction(rpc, tx); + }) +); + +const transferTx = new Transaction().add(...transferInstructions); +transferTx.sign(payer, owner); +await sendAndConfirmTransaction(rpc, transferTx); +``` + + + + ```typescript import { @@ -281,10 +347,7 @@ const destinationAta = getAssociatedTokenAddressSync(mint, recipient); const tx = new Transaction().add( createAssociatedTokenAccountIdempotentInstruction( - payer.publicKey, - destinationAta, - recipient, - mint + payer.publicKey, destinationAta, recipient, mint ), createTransferInstruction(sourceAta, destinationAta, owner.publicKey, amount) ); @@ -293,7 +356,7 @@ const tx = new Transaction().add( - + ```typescript import { @@ -302,42 +365,9 @@ import { } from "@lightprotocol/compressed-token/unified"; const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); - -await transferInterface( - payer, - sourceAta, - mint, - destinationAta, - owner, - amount -); -``` - -To ensure your recipient's ATA exists before transferring: - -```typescript -import { - getOrCreateAtaInterface, - transferInterface, - getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token/unified"; - -// Ensure recipient ATA exists (creates if needed) -await getOrCreateAtaInterface(rpc, payer, mint, recipient); -// Then transfer -const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); -await transferInterface( - rpc, - payer, - sourceAta, - mint, - destinationAta, - owner, - amount -); +// Handles loading, creates recipient ATA, transfers. +await transferInterface(rpc, payer, sourceAta, mint, recipient, owner, amount); ``` @@ -349,21 +379,11 @@ import { transfer, } from "@solana/spl-token"; -// Ensure recipient ATA exists await getOrCreateAssociatedTokenAccount(connection, payer, mint, recipient); -// Then transfer const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey); const destinationAta = getAssociatedTokenAddressSync(mint, recipient); -await transfer( - connection, - payer, - sourceAta, - destinationAta, - owner, - amount, - decimals -); +await transfer(connection, payer, sourceAta, destinationAta, owner, amount); ``` @@ -410,7 +430,9 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- ```typescript const result = await rpc.getSignaturesForOwnerInterface(owner); -console.log(result.signatures); // All signatures +console.log(result.signatures); // Merged + deduplicated +console.log(result.solana); // On-chain txs only +console.log(result.compressed); // Compressed txs only ``` Use `getSignaturesForAddressInterface(address)` if you want address-specific rather than owner-wide history. @@ -457,13 +479,14 @@ const tx = new Transaction().add( mint, amount, splInterfaceInfo, - decimals + decimals, + payer.publicKey ) ); ``` - + ```typescript import { getAssociatedTokenAddressSync } from "@solana/spl-token"; @@ -472,9 +495,7 @@ import { getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token/unified"; -// SPL ATA with tokens to wrap const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -// light-token ATA destination const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); await wrap(rpc, payer, splAta, tokenAta, owner, mint, amount); @@ -485,10 +506,8 @@ await wrap(rpc, payer, splAta, tokenAta, owner, mint, amount); ### Unwrap to SPL -You can compose with applications that do not yet support the light-token -standard by unwrapping your tokens. - Unwrap moves the token balance from a light-token account to a SPL-token account. +Use this to compose with applications that do not yet support light-token. Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/unwrap.ts). @@ -500,46 +519,33 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- ```typescript import { Transaction } from "@solana/web3.js"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; -import { - createLoadAtaInstructions, - createUnwrapInstruction, - getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token/unified"; -import { getSplInterfaceInfos } from "@lightprotocol/compressed-token"; +import { createUnwrapInstructions } from "@lightprotocol/compressed-token/unified"; -const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint); -const splInterfaceInfo = splInterfaceInfos.find((i) => i.isInitialized); - -const tx = new Transaction().add( - ...(await createLoadAtaInstructions( - rpc, - tokenAta, - owner.publicKey, - mint, - payer.publicKey - )), - createUnwrapInstruction( - tokenAta, - splAta, - owner.publicKey, - mint, - amount, - splInterfaceInfo, - decimals - ) +// Each inner array = one transaction. Handles loading + unwrapping together. +const instructions = await createUnwrapInstructions( + rpc, + splAta, + owner.publicKey, + mint, + amount, + payer.publicKey ); + +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer, owner]); +} ``` - + ```typescript import { getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { unwrap } from "@lightprotocol/compressed-token/unified"; -// SPL ATA must exist const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); await unwrap(rpc, payer, splAta, owner, mint, amount); diff --git a/light-token/toolkits/for-wallets.mdx b/light-token/toolkits/for-wallets.mdx index 173b8470..99fac62f 100644 --- a/light-token/toolkits/for-wallets.mdx +++ b/light-token/toolkits/for-wallets.mdx @@ -27,19 +27,14 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; - **Get/Create ATA** + **Receive** getOrCreateAssociatedTokenAccount() - getOrCreateAtaInterface() - - - **Derive ATA** - getAssociatedTokenAddress() - getAssociatedTokenAddressInterface() + createLoadAtaInstructions() / loadAta() **Transfer** - transferChecked() - transferInterface() + createTransferInstruction() + createTransferInterfaceInstructions() / transferInterface() **Get Balance** @@ -54,18 +49,18 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; **Wrap from SPL** N/A - wrap() + wrap() / createWrapInstruction() **Unwrap to SPL** N/A - unwrap() + createUnwrapInstructions() / unwrap() - Find full code examples + Find full runnable code examples [here](https://github.com/Lightprotocol/examples-light-token/tree/main/toolkits/payments-and-wallets). @@ -73,117 +68,118 @@ import ToolkitsSetup from "/snippets/setup/toolkits-setup.mdx"; +Snippets below assume `rpc`, `payer`, `mint`, `owner`, `recipient`, and `amount` are defined. +See the [full examples](https://github.com/Lightprotocol/examples-light-token/tree/main/toolkits/payments-and-wallets) for runnable setup. + ```typescript import { createRpc } from "@lightprotocol/stateless.js"; import { - getOrCreateAtaInterface, - getAtaInterface, - getAssociatedTokenAddressInterface, + createLoadAtaInstructions, + loadAta, + createTransferInterfaceInstructions, transferInterface, - wrap, + createUnwrapInstructions, unwrap, -} from "@lightprotocol/compressed-token"; + getAssociatedTokenAddressInterface, + getAtaInterface, + wrap, +} from "@lightprotocol/compressed-token/unified"; const rpc = createRpc(RPC_ENDPOINT); ``` + +**About loading**: Light tokens reduce account rent ~200x by auto-compressing inactive +accounts. Before any action, the SDK detects compressed state and adds +instructions to load it back on-chain. This almost always fits in a single +atomic transaction with your regular transfer. APIs return `TransactionInstruction[][]` so the same +loop handles the rare multi-transaction case automatically. + + ### Receive Payments -Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-and-receive.ts). +Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/receive.ts). +Load creates the associated token account (ATA) if needed and loads any compressed state into it. Share the ATA address with the sender. + + ```typescript import { Transaction } from "@solana/web3.js"; import { - createAssociatedTokenAccountInterfaceIdempotentInstruction, createLoadAtaInstructions, getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token"; -import { LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; +} from "@lightprotocol/compressed-token/unified"; const ata = getAssociatedTokenAddressInterface(mint, recipient); -const tx = new Transaction().add( - createAssociatedTokenAccountInterfaceIdempotentInstruction( - payer.publicKey, - ata, - recipient, - mint, - LIGHT_TOKEN_PROGRAM_ID - ), - ...(await createLoadAtaInstructions( - rpc, - ata, - recipient, - mint, - payer.publicKey - )) +// Returns TransactionInstruction[][]. +// Each inner array is one transaction. +// Almost always returns just one. +const instructions = await createLoadAtaInstructions( + rpc, + ata, + recipient, + mint, + payer.publicKey ); +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer]); +} ``` - + + ```typescript import { - createAssociatedTokenAccountInstruction, - getAssociatedTokenAddressSync, -} from "@solana/spl-token"; + loadAta, + getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-token/unified"; -const ata = getAssociatedTokenAddressSync(mint, recipient); +const ata = getAssociatedTokenAddressInterface(mint, recipient); -const tx = new Transaction().add( - createAssociatedTokenAccountInstruction( - payer.publicKey, - ata, - recipient, - mint - ) -); +const sig = await loadAta(rpc, ata, recipient, mint, payer); +if (sig) console.log("Loaded:", sig); ``` - - - -```typescript -import { getOrCreateAtaInterface } from "@lightprotocol/compressed-token"; - -const ata = await getOrCreateAtaInterface(rpc, payer, mint, recipient); -// Share ata.parsed.address with sender - -console.log(ata.parsed.amount); -``` + ```typescript -import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token"; +import { + createAssociatedTokenAccountInstruction, + getAssociatedTokenAddressSync, + getOrCreateAssociatedTokenAccount, +} from "@solana/spl-token"; -const ata = await getOrCreateAssociatedTokenAccount( - connection, - payer, - mint, - recipient +const ata = getAssociatedTokenAddressSync(mint, recipient); + +// Instruction: +const tx = new Transaction().add( + createAssociatedTokenAccountInstruction(payer.publicKey, ata, recipient, mint) ); -// Share ata.address with sender -console.log(ata.amount); +// Action: +const ata = await getOrCreateAssociatedTokenAccount( + connection, payer, mint, recipient +); ``` - - - ### Send Payments -Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-and-receive.ts). +Find a full code example: [instruction](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-instruction.ts) | [action](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send-action.ts). @@ -191,30 +187,22 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- ```typescript import { Transaction } from "@solana/web3.js"; -import { - createLoadAtaInstructions, - createTransferInterfaceInstruction, - getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token"; +import { createTransferInterfaceInstructions } from "@lightprotocol/compressed-token/unified"; -const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); - -const tx = new Transaction().add( - ...(await createLoadAtaInstructions( - rpc, - sourceAta, - owner.publicKey, - mint, - payer.publicKey - )), - createTransferInterfaceInstruction( - sourceAta, - destinationAta, - owner.publicKey, - amount - ) +// Each inner array = one transaction. Usually just one. +const instructions = await createTransferInterfaceInstructions( + rpc, + payer.publicKey, + mint, + amount, + owner.publicKey, + recipient ); + +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer, owner]); +} ``` @@ -222,6 +210,7 @@ const tx = new Transaction().add( ```typescript import { getAssociatedTokenAddressSync, + createAssociatedTokenAccountIdempotentInstruction, createTransferInstruction, } from "@solana/spl-token"; @@ -229,6 +218,9 @@ const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey); const destinationAta = getAssociatedTokenAddressSync(mint, recipient); const tx = new Transaction().add( + createAssociatedTokenAccountIdempotentInstruction( + payer.publicKey, destinationAta, recipient, mint + ), createTransferInstruction(sourceAta, destinationAta, owner.publicKey, amount) ); ``` @@ -236,85 +228,34 @@ const tx = new Transaction().add( - + ```typescript import { getAssociatedTokenAddressInterface, transferInterface, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); -await transferInterface( - rpc, - payer, - sourceAta, - mint, - destinationAta, - owner, - amount -); -``` - -To ensure your recipient's ATA exists you can prepend an idempotent creation instruction in the same atomic transaction: - -```typescript -import { - getAssociatedTokenAddressInterface, - createAssociatedTokenAccountInterfaceIdempotentInstruction, -} from "@lightprotocol/compressed-token"; -import { LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; - -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); -const createAtaIx = createAssociatedTokenAccountInterfaceIdempotentInstruction( - payer.publicKey, - destinationAta, - recipient, - mint, - LIGHT_TOKEN_PROGRAM_ID -); - -new Transaction().add(createAtaIx, transferIx); +// Handles loading, creates recipient ATA, transfers. +await transferInterface(rpc, payer, sourceAta, mint, recipient, owner, amount); ``` -```typescript -import { transfer } from "@solana/spl-token"; - -const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressSync(mint, recipient); - -await transfer( - connection, - payer, - sourceAta, - destinationAta, - owner, - amount, - decimals -); -``` - -With idempotent ATA creation: - ```typescript import { getAssociatedTokenAddressSync, - createAssociatedTokenAccountIdempotentInstruction, + getOrCreateAssociatedTokenAccount, + transfer, } from "@solana/spl-token"; -const destinationAta = getAssociatedTokenAddressSync(mint, recipient); -const createAtaIx = createAssociatedTokenAccountIdempotentInstruction( - payer.publicKey, - destinationAta, - recipient, - mint -); +await getOrCreateAssociatedTokenAccount(connection, payer, mint, recipient); -new Transaction().add(createAtaIx, transferIx); +const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey); +const destinationAta = getAssociatedTokenAddressSync(mint, recipient); +await transfer(connection, payer, sourceAta, destinationAta, owner, amount); ``` @@ -332,7 +273,7 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- import { getAssociatedTokenAddressInterface, getAtaInterface, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; const ata = getAssociatedTokenAddressInterface(mint, owner); const account = await getAtaInterface(rpc, ata, owner, mint); @@ -361,9 +302,9 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- ```typescript const result = await rpc.getSignaturesForOwnerInterface(owner); -console.log(result.signatures); -console.log(result.solana); -console.log(result.compressed); +console.log(result.signatures); // Merged + deduplicated +console.log(result.solana); // On-chain txs only +console.log(result.compressed); // Compressed txs only ``` Use `getSignaturesForAddressInterface(address)` if you want address-specific rather than owner-wide history. @@ -393,8 +334,8 @@ import { getAssociatedTokenAddressSync } from "@solana/spl-token"; import { createWrapInstruction, getAssociatedTokenAddressInterface, - getSplInterfaceInfos, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; +import { getSplInterfaceInfos } from "@lightprotocol/compressed-token"; const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); @@ -410,24 +351,23 @@ const tx = new Transaction().add( mint, amount, splInterfaceInfo, - decimals + decimals, + payer.publicKey ) ); ``` - + ```typescript import { getAssociatedTokenAddressSync } from "@solana/spl-token"; import { wrap, getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; -// SPL ATA with tokens to wrap const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -// light-token ATA destination const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); await wrap(rpc, payer, splAta, tokenAta, owner, mint, amount); @@ -438,10 +378,8 @@ await wrap(rpc, payer, splAta, tokenAta, owner, mint, amount); ### Unwrap to SPL -You can compose with applications that do not yet support the light-token -standard by unwrapping your tokens. - Unwrap moves the token balance from a light-token account to a SPL-token account. +Use this to compose with applications that do not yet support light-token. Find a full code example [here](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/unwrap.ts). @@ -453,46 +391,33 @@ Find a full code example [here](https://github.com/Lightprotocol/examples-light- ```typescript import { Transaction } from "@solana/web3.js"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; -import { - createLoadAtaInstructions, - createUnwrapInstruction, - getAssociatedTokenAddressInterface, - getSplInterfaceInfos, -} from "@lightprotocol/compressed-token"; +import { createUnwrapInstructions } from "@lightprotocol/compressed-token/unified"; -const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); -const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint); -const splInterfaceInfo = splInterfaceInfos.find((i) => i.isInitialized); - -const tx = new Transaction().add( - ...(await createLoadAtaInstructions( - rpc, - tokenAta, - owner.publicKey, - mint, - payer.publicKey - )), - createUnwrapInstruction( - tokenAta, - splAta, - owner.publicKey, - mint, - amount, - splInterfaceInfo, - decimals - ) +// Each inner array = one transaction. Handles loading + unwrapping together. +const instructions = await createUnwrapInstructions( + rpc, + splAta, + owner.publicKey, + mint, + amount, + payer.publicKey ); + +for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer, owner]); +} ``` - + ```typescript import { getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { unwrap } from "@lightprotocol/compressed-token/unified"; -// SPL ATA must exist const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey); await unwrap(rpc, payer, splAta, owner, mint, amount); diff --git a/quickstart.mdx b/quickstart.mdx index 7ec41a29..f02837fa 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -20,7 +20,7 @@ import FullSetup from "/snippets/setup/full-setup.mdx"; ```typescript // 1. Load wallet and connect to Localnet -// 2. Create SPL mint with token pool for compression via createMint() +// 2. Create SPL mint with SPL interface via createMint() // 3. Mint compressed tokens to recipient account via mintTo() // 4. Verify compressed token balance via getCompressedTokenAccountsByOwner @@ -43,8 +43,8 @@ const connection = createRpc(RPC_ENDPOINT, COMPRESSION_ENDPOINT, PROVER_ENDPOINT const main = async () => { try { - // Step 2: Create SPL mint with token pool for compression - console.log("\nCreating SPL mint with token pool for compression"); + // Step 2: Create SPL mint with SPL interface + console.log("\nCreating SPL mint with SPL interface for compression"); const { mint, transactionSignature } = await createMint( connection, payer, @@ -63,7 +63,7 @@ const main = async () => { const mintToTxId = await mintTo( connection, payer, - mint, // SPL mint with token pool for compression + mint, // SPL mint with SPL interface for compression payer.publicKey, // recipient.publicKey payer, // mintAuthority mintAmount @@ -77,7 +77,7 @@ const main = async () => { // Step 4: Verify compressed token balance via getCompressedTokenAccountsByOwner const tokenAccounts = await connection.getCompressedTokenAccountsByOwner( payer.publicKey, - { mint } // SPL mint with token pool for compression + { mint } // SPL mint with SPL interface for compression ); } catch (error: any) { console.error("Error:", error.message); diff --git a/references/terminology.mdx b/references/terminology.mdx index aad5f15d..f97ab783 100644 --- a/references/terminology.mdx +++ b/references/terminology.mdx @@ -56,11 +56,11 @@ A 32-byte identifier uniquely that represents a compressed account's state, stor An SPL token mint uniquely represents a token on the Solana network and stores global metadata about the token, including `mint_authority`, `supply`, and `decimals`. -SPL tokens can be compressed if the mint has a token pool account set up. Anyone can create a token pool PDA for any given SPL mint. +SPL tokens can be compressed if the mint has an SPL Interface PDA set up. Anyone can create an SPL interface for any given SPL mint. -## Token Pool Account +## SPL Interface (omnibus account) -SPL token account that holds SPL tokens corresponding to compressed tokens in circulation. Tokens are deposited during compression and withdrawn during decompression, owned by the Light Token Program's CPI authority PDA. +An SPL token account (the SPL Interface PDA) that holds SPL tokens corresponding to compressed tokens in circulation. Tokens are deposited during compression and withdrawn during decompression; the account is owned by the Light Token Program's CPI authority PDA. ## Concurrency @@ -106,7 +106,7 @@ A call from one [program](https://solana.com/docs/core/transactions#onchain-prog ## Decompression -The process of converting a compressed to a regular Solana account. SPL tokens are withdrawn from the token pool to an Associated Token Account and compressed token accounts are invalidated. +The process of converting a compressed to a regular Solana account. SPL tokens are withdrawn from the SPL Interface PDA to an Associated Token Account and compressed token accounts are invalidated. ## Forester node / Forester diff --git a/snippets/code-samples/code-compare-snippets.jsx b/snippets/code-samples/code-compare-snippets.jsx index 6087a889..27af888b 100644 --- a/snippets/code-samples/code-compare-snippets.jsx +++ b/snippets/code-samples/code-compare-snippets.jsx @@ -92,14 +92,14 @@ export const splTransferCode = [ ].join("\n"); export const lightTransferCode = [ - 'import { transferInterface } from "@lightprotocol/compressed-token";', + 'import { transferInterface } from "@lightprotocol/compressed-token/unified";', "", "const tx = await transferInterface(", " rpc,", " payer,", " sourceAta,", " mint,", - " destinationAta,", + " recipient,", " owner,", " amount", ");", diff --git a/snippets/code-samples/code-compare-snippets.ts b/snippets/code-samples/code-compare-snippets.ts index 3ed0ea8e..3b3d7cad 100644 --- a/snippets/code-samples/code-compare-snippets.ts +++ b/snippets/code-samples/code-compare-snippets.ts @@ -101,15 +101,14 @@ export const splTransferCode = [ ].join("\n"); export const lightTransferCode = [ - "// light-token transfer", - 'import { transferInterface } from "@lightprotocol/compressed-token";', + 'import { transferInterface } from "@lightprotocol/compressed-token/unified";', "", "const tx = await transferInterface(", " rpc,", " payer,", " sourceAta,", " mint,", - " destinationAta,", + " recipient,", " owner,", " amount", ");", diff --git a/snippets/code-snippets/compressed-token/create-token-pool/action.mdx b/snippets/code-snippets/compressed-token/create-token-pool/action.mdx index 486e74d0..55975443 100644 --- a/snippets/code-snippets/compressed-token/create-token-pool/action.mdx +++ b/snippets/code-snippets/compressed-token/create-token-pool/action.mdx @@ -2,7 +2,7 @@ import "dotenv/config"; import { Keypair, PublicKey } from "@solana/web3.js"; import { createRpc } from "@lightprotocol/stateless.js"; -import { createTokenPool } from "@lightprotocol/compressed-token"; +import { createSplInterface } from "@lightprotocol/compressed-token"; import { createMint as createSplMint, TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { homedir } from "os"; import { readFileSync } from "fs"; @@ -27,8 +27,8 @@ const payer = Keypair.fromSecretKey( const mintKeypair = Keypair.generate(); await createSplMint(rpc, payer, payer.publicKey, null, 9, mintKeypair, undefined, TOKEN_PROGRAM_ID); - // Create token pool for existing mint - const tx = await createTokenPool(rpc, payer, mintKeypair.publicKey); + // Create SPL interface for existing mint + const tx = await createSplInterface(rpc, payer, mintKeypair.publicKey); console.log("Mint:", mintKeypair.publicKey.toBase58()); console.log("Tx:", tx); diff --git a/snippets/code-snippets/light-token/create-ata/instruction.mdx b/snippets/code-snippets/light-token/create-ata/instruction.mdx index ec0a5285..c507ff05 100644 --- a/snippets/code-snippets/light-token/create-ata/instruction.mdx +++ b/snippets/code-snippets/light-token/create-ata/instruction.mdx @@ -5,7 +5,7 @@ import { Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; -import { createRpc, CTOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; +import { createRpc, LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js"; import { createMintInterface, createAssociatedTokenAccountInterfaceInstruction, @@ -40,7 +40,7 @@ const payer = Keypair.fromSecretKey( associatedToken, owner.publicKey, mint, - CTOKEN_PROGRAM_ID, + LIGHT_TOKEN_PROGRAM_ID, ); const tx = new Transaction().add(ix); diff --git a/snippets/code-snippets/light-token/create-spl-mint/action.mdx b/snippets/code-snippets/light-token/create-spl-mint/action.mdx index 1002dfee..0f0c2413 100644 --- a/snippets/code-snippets/light-token/create-spl-mint/action.mdx +++ b/snippets/code-snippets/light-token/create-spl-mint/action.mdx @@ -20,7 +20,7 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // Creates SPL mint + SPL interface pda (token pool) in one transaction + // Creates SPL mint + SPL Interface PDA in one transaction const mintKeypair = Keypair.generate(); const { mint, transactionSignature } = await createMintInterface( rpc, diff --git a/snippets/code-snippets/light-token/create-spl-mint/instruction.mdx b/snippets/code-snippets/light-token/create-spl-mint/instruction.mdx index 64278570..6c69e1e7 100644 --- a/snippets/code-snippets/light-token/create-spl-mint/instruction.mdx +++ b/snippets/code-snippets/light-token/create-spl-mint/instruction.mdx @@ -7,7 +7,7 @@ import { sendAndConfirmTransaction, } from "@solana/web3.js"; import { createRpc } from "@lightprotocol/stateless.js"; -import { CompressedTokenProgram } from "@lightprotocol/compressed-token"; +import { LightTokenProgram } from "@lightprotocol/compressed-token"; import { MINT_SIZE, TOKEN_PROGRAM_ID, @@ -53,8 +53,8 @@ const payer = Keypair.fromSecretKey( TOKEN_PROGRAM_ID ); - // Instruction 3: Create SPL interface pda (token pool, enables compression of the SPL mint's tokens) - const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({ + // Instruction 3: Create SPL Interface PDA (enables compression for this mint) + const createSplInterfaceIx = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: mintKeypair.publicKey, tokenProgramId: TOKEN_PROGRAM_ID, @@ -63,7 +63,7 @@ const payer = Keypair.fromSecretKey( const tx = new Transaction().add( createMintAccountIx, initializeMintIx, - createTokenPoolIx + createSplInterfaceIx ); const signature = await sendAndConfirmTransaction(rpc, tx, [ diff --git a/snippets/code-snippets/light-token/create-t22-mint/instruction.mdx b/snippets/code-snippets/light-token/create-t22-mint/instruction.mdx index 8706a109..f61f4661 100644 --- a/snippets/code-snippets/light-token/create-t22-mint/instruction.mdx +++ b/snippets/code-snippets/light-token/create-t22-mint/instruction.mdx @@ -7,7 +7,7 @@ import { sendAndConfirmTransaction, } from "@solana/web3.js"; import { createRpc } from "@lightprotocol/stateless.js"; -import { CompressedTokenProgram } from "@lightprotocol/compressed-token"; +import { LightTokenProgram } from "@lightprotocol/compressed-token"; import { MINT_SIZE, TOKEN_2022_PROGRAM_ID, @@ -56,7 +56,7 @@ const payer = Keypair.fromSecretKey( // Instruction 3: Create SPL interface PDA // Holds Token-2022 tokens when wrapped to light-token - const createSplInterfaceIx = await CompressedTokenProgram.createTokenPool({ + const createSplInterfaceIx = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: mintKeypair.publicKey, tokenProgramId: TOKEN_2022_PROGRAM_ID, diff --git a/snippets/code-snippets/light-token/create-token-pool/instruction.mdx b/snippets/code-snippets/light-token/create-token-pool/instruction.mdx index e184a2b2..55385a00 100644 --- a/snippets/code-snippets/light-token/create-token-pool/instruction.mdx +++ b/snippets/code-snippets/light-token/create-token-pool/instruction.mdx @@ -7,7 +7,7 @@ import { sendAndConfirmTransaction, } from "@solana/web3.js"; import { createRpc } from "@lightprotocol/stateless.js"; -import { CompressedTokenProgram } from "@lightprotocol/compressed-token"; +import { LightTokenProgram } from "@lightprotocol/compressed-token"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { homedir } from "os"; import { readFileSync } from "fs"; @@ -27,7 +27,7 @@ const payer = Keypair.fromSecretKey( (async function () { const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); - const ix = await CompressedTokenProgram.createTokenPool({ + const ix = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: existingMint, tokenProgramId: TOKEN_PROGRAM_ID, diff --git a/snippets/code-snippets/light-token/load-ata/action.mdx b/snippets/code-snippets/light-token/load-ata/action.mdx index f0b97591..919ef14c 100644 --- a/snippets/code-snippets/light-token/load-ata/action.mdx +++ b/snippets/code-snippets/light-token/load-ata/action.mdx @@ -1,13 +1,13 @@ ```typescript import "dotenv/config"; import { Keypair } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { - createMint, - mintTo, + createMintInterface, + mintToCompressed, loadAta, getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; import { homedir } from "os"; import { readFileSync } from "fs"; @@ -25,8 +25,10 @@ const payer = Keypair.fromSecretKey( (async function () { // Setup: Get compressed tokens (cold storage) - const { mint } = await createMint(rpc, payer, payer.publicKey, 9); - await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000)); + const { mint } = await createMintInterface(rpc, payer, payer, null, 9); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); // Load compressed tokens to hot balance const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); diff --git a/snippets/code-snippets/light-token/load-ata/instruction.mdx b/snippets/code-snippets/light-token/load-ata/instruction.mdx index 4cf75957..7d10f34e 100644 --- a/snippets/code-snippets/light-token/load-ata/instruction.mdx +++ b/snippets/code-snippets/light-token/load-ata/instruction.mdx @@ -11,7 +11,7 @@ import { mintToCompressed, createLoadAtaInstructions, getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token"; +} from "@lightprotocol/compressed-token/unified"; import { homedir } from "os"; import { readFileSync } from "fs"; @@ -39,8 +39,8 @@ const payer = Keypair.fromSecretKey( payer.publicKey, ); - // Load compressed tokens to light associated token account (hot balance) - const ixs = await createLoadAtaInstructions( + // Load compressed tokens to light associated token account (hot balance). Usually one tx. Empty = noop. + const instructions = await createLoadAtaInstructions( rpc, lightTokenAta, payer.publicKey, @@ -48,11 +48,13 @@ const payer = Keypair.fromSecretKey( payer.publicKey, ); - if (ixs.length === 0) return console.log("Nothing to load"); + if (instructions.length === 0) return console.log("Nothing to load"); - const blockhash = await rpc.getLatestBlockhash(); - const tx = buildAndSignTx(ixs, payer, blockhash.blockhash); - const signature = await sendAndConfirmTx(rpc, tx); - console.log("Tx:", signature); + for (const ixs of instructions) { + const { blockhash } = await rpc.getLatestBlockhash(); + const tx = buildAndSignTx(ixs, payer, blockhash); + const sig = await sendAndConfirmTx(rpc, tx); + console.log("Tx:", sig); + } })(); ``` diff --git a/snippets/code-snippets/light-token/transfer-interface/action.mdx b/snippets/code-snippets/light-token/transfer-interface/action.mdx index 6344c775..46e33578 100644 --- a/snippets/code-snippets/light-token/transfer-interface/action.mdx +++ b/snippets/code-snippets/light-token/transfer-interface/action.mdx @@ -33,10 +33,9 @@ const payer = Keypair.fromSecretKey( await mintToInterface(rpc, payer, mint, senderAta, payer, 1_000_000_000); const recipient = Keypair.generate(); - await createAtaInterface(rpc, payer, mint, recipient.publicKey); - const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); - const tx = await transferInterface(rpc, payer, senderAta, mint, recipientAta, sender, 500_000_000); + // destination is a wallet pubkey; the action creates the recipient ATA. + const tx = await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, sender, 500_000_000); console.log("Tx:", tx); })(); diff --git a/snippets/code-snippets/light-token/transfer-interface/anchor-program/full-example.mdx b/snippets/code-snippets/light-token/transfer-interface/anchor-program/full-example.mdx index 0179a04f..1f9ba0fd 100644 --- a/snippets/code-snippets/light-token/transfer-interface/anchor-program/full-example.mdx +++ b/snippets/code-snippets/light-token/transfer-interface/anchor-program/full-example.mdx @@ -189,7 +189,7 @@ async fn test_transfer_spl_to_light() { .await .unwrap(); - // 2. Create SPL token pool (spl_interface_pda) + // 2. Create SPL Interface PDA let create_pool_ix = CreateSplInterfacePda::new(payer.pubkey(), mint, spl_token::ID, false).instruction(); diff --git a/snippets/code-snippets/light-token/transfer-interface/instruction.mdx b/snippets/code-snippets/light-token/transfer-interface/instruction.mdx index 20d076fb..cbebec35 100644 --- a/snippets/code-snippets/light-token/transfer-interface/instruction.mdx +++ b/snippets/code-snippets/light-token/transfer-interface/instruction.mdx @@ -11,7 +11,7 @@ import { createMintInterface, createAtaInterface, mintToInterface, - createTransferInterfaceInstruction, + createLightTokenTransferInstruction, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token"; import { homedir } from "os"; @@ -47,8 +47,8 @@ const payer = Keypair.fromSecretKey( recipient.publicKey, ); - // Transfer tokens between light-token associate token accounts - const ix = createTransferInterfaceInstruction( + // Transfer tokens between light-token associated token accounts + const ix = createLightTokenTransferInstruction( senderAta, recipientAta, sender.publicKey, diff --git a/snippets/code-snippets/light-token/unwrap/instruction.mdx b/snippets/code-snippets/light-token/unwrap/instruction.mdx index 38689df2..5f38a5b3 100644 --- a/snippets/code-snippets/light-token/unwrap/instruction.mdx +++ b/snippets/code-snippets/light-token/unwrap/instruction.mdx @@ -1,25 +1,24 @@ ```typescript import "dotenv/config"; -import { Keypair, ComputeBudgetProgram, Transaction, sendAndConfirmTransaction } from "@solana/web3.js"; +import { + Keypair, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; import { createRpc, bn } from "@lightprotocol/stateless.js"; import { - createMint, - mintTo, - loadAta, - getAssociatedTokenAddressInterface, - getSplInterfaceInfos, -} from "@lightprotocol/compressed-token"; -import { createUnwrapInstruction } from "@lightprotocol/compressed-token/unified"; + createMintInterface, + mintToCompressed, + createUnwrapInstructions, +} from "@lightprotocol/compressed-token/unified"; import { createAssociatedTokenAccount } from "@solana/spl-token"; import { homedir } from "os"; import { readFileSync } from "fs"; // devnet: -// const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`; +const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY}`; const rpc = createRpc(RPC_URL); -// localnet: -// const rpc = createRpc(); - +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) @@ -27,13 +26,10 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // Setup: Get compressed tokens (cold storage) - const { mint } = await createMint(rpc, payer, payer.publicKey, 9); - await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000)); - - // Load compressed tokens to hot balance, then create unwrap instruction - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); - await loadAta(rpc, lightTokenAta, payer, mint, payer); + const { mint } = await createMintInterface(rpc, payer, payer, null, 9); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); const splAta = await createAssociatedTokenAccount( rpc, @@ -42,30 +38,20 @@ const payer = Keypair.fromSecretKey( payer.publicKey ); - const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint); - const splInterfaceInfo = splInterfaceInfos.find( - (info) => info.isInitialized - ); - - if (!splInterfaceInfo) throw new Error("No SPL interface found"); - - const ix = createUnwrapInstruction( - lightTokenAta, + // Returns TransactionInstruction[][]. Each inner array is one txn. + // Handles loading cold state + unwrapping in one go. + const instructions = await createUnwrapInstructions( + rpc, splAta, payer.publicKey, mint, - bn(500), - splInterfaceInfo, - 9, // decimals - must match the mint decimals + 500n, payer.publicKey ); - const tx = new Transaction().add( - ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }), - ix - ); - const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); - - console.log("Tx:", signature); + for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer]); + } })(); ``` diff --git a/snippets/code-snippets/privy/compress/nodejs.mdx b/snippets/code-snippets/privy/compress/nodejs.mdx index 978c51c4..41e41a3f 100644 --- a/snippets/code-snippets/privy/compress/nodejs.mdx +++ b/snippets/code-snippets/privy/compress/nodejs.mdx @@ -4,7 +4,7 @@ import {PrivyClient} from '@privy-io/node'; import {createRpc, bn, selectStateTreeInfo} from '@lightprotocol/stateless.js'; import {PublicKey, Transaction, ComputeBudgetProgram} from '@solana/web3.js'; import {getAssociatedTokenAddressSync, getAccount} from '@solana/spl-token'; -import {CompressedTokenProgram, getTokenPoolInfos, selectTokenPoolInfo} from '@lightprotocol/compressed-token'; +import {LightTokenProgram, getTokenPoolInfos, selectTokenPoolInfo} from '@lightprotocol/compressed-token'; const compressTokens = async ( fromAddress: string, @@ -34,14 +34,14 @@ const compressTokens = async ( } // Get state tree to store compressed tokens - // Get token pool info. Stores SPL tokens in interface PDA when compressed. + // Get SPL interface info. SPL tokens are stored in the interface PDA when compressed. const stateTreeInfos = await connection.getStateTreeInfos(); const selectedTreeInfo = selectStateTreeInfo(stateTreeInfos); const tokenPoolInfos = await getTokenPoolInfos(connection, mintPubkey); const tokenPoolInfo = selectTokenPoolInfo(tokenPoolInfos); // Create compress instruction - const instruction = await CompressedTokenProgram.compress({ + const instruction = await LightTokenProgram.compress({ payer: fromPubkey, owner: fromPubkey, source: ownerAta, diff --git a/snippets/code-snippets/privy/compress/react.mdx b/snippets/code-snippets/privy/compress/react.mdx index 029bd9fa..5adfc1e4 100644 --- a/snippets/code-snippets/privy/compress/react.mdx +++ b/snippets/code-snippets/privy/compress/react.mdx @@ -3,7 +3,7 @@ import { useState } from 'react'; import { PublicKey, Transaction, ComputeBudgetProgram } from '@solana/web3.js'; import { getAssociatedTokenAddressSync, getAccount } from '@solana/spl-token'; import { bn, createRpc, selectStateTreeInfo } from '@lightprotocol/stateless.js'; -import { CompressedTokenProgram, getTokenPoolInfos, selectTokenPoolInfo } from '@lightprotocol/compressed-token'; +import { LightTokenProgram, getTokenPoolInfos, selectTokenPoolInfo } from '@lightprotocol/compressed-token'; import type { ConnectedStandardSolanaWallet } from '@privy-io/js-sdk-core'; import type { SignTransactionResult } from '@privy-io/react-auth/solana'; @@ -52,14 +52,14 @@ export function useCompress() { } // Get state tree to store compressed tokens - // Get token pool info. Stores SPL tokens in interface PDA when compressed. + // Get SPL interface info. SPL tokens are stored in the interface PDA when compressed. const stateTreeInfos = await rpc.getStateTreeInfos(); const selectedTreeInfo = selectStateTreeInfo(stateTreeInfos); const tokenPoolInfos = await getTokenPoolInfos(rpc, mintPubkey); const tokenPoolInfo = selectTokenPoolInfo(tokenPoolInfos); // Create compress instruction - const instruction = await CompressedTokenProgram.compress({ + const instruction = await LightTokenProgram.compress({ payer: ownerPubkey, owner: ownerPubkey, source: ownerAta, diff --git a/snippets/code-snippets/privy/decompress/react.mdx b/snippets/code-snippets/privy/decompress/react.mdx index 2ea96fc8..193761e8 100644 --- a/snippets/code-snippets/privy/decompress/react.mdx +++ b/snippets/code-snippets/privy/decompress/react.mdx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { PublicKey, Transaction, ComputeBudgetProgram } from '@solana/web3.js'; import { getAssociatedTokenAddressSync, createAssociatedTokenAccountInstruction, getAccount, TokenAccountNotFoundError } from '@solana/spl-token'; -import { CompressedTokenProgram, selectMinCompressedTokenAccountsForTransfer, getSplInterfaceInfos, selectSplInterfaceInfosForDecompression } from '@lightprotocol/compressed-token'; +import { LightTokenProgram, selectMinCompressedTokenAccountsForTransfer, getSplInterfaceInfos, selectSplInterfaceInfosForDecompression } from '@lightprotocol/compressed-token'; import { bn, createRpc } from '@lightprotocol/stateless.js'; import type { ConnectedStandardSolanaWallet } from '@privy-io/js-sdk-core'; import type { SignTransactionResult } from '@privy-io/react-auth/solana'; @@ -56,7 +56,7 @@ export function useDecompress() { throw new Error('Insufficient compressed balance'); } - // Get validity proof and token pool info + // Get validity proof and SPL interface info const proof = await rpc.getValidityProof( inputAccounts.map((account) => bn(account.compressedAccount.hash)) ); @@ -82,7 +82,7 @@ export function useDecompress() { } // Build decompress instruction - const decompressIx = await CompressedTokenProgram.decompress({ + const decompressIx = await LightTokenProgram.decompress({ payer: owner, inputCompressedTokenAccounts: inputAccounts, toAddress: destinationAta, diff --git a/snippets/code-snippets/privy/transfer/nodejs.mdx b/snippets/code-snippets/privy/transfer/nodejs.mdx index 17820e87..0d4134b8 100644 --- a/snippets/code-snippets/privy/transfer/nodejs.mdx +++ b/snippets/code-snippets/privy/transfer/nodejs.mdx @@ -3,7 +3,7 @@ import 'dotenv/config'; import {PrivyClient} from '@privy-io/node'; import {createRpc, bn} from '@lightprotocol/stateless.js'; import {PublicKey, Transaction, ComputeBudgetProgram} from '@solana/web3.js'; -import {CompressedTokenProgram, selectMinCompressedTokenAccountsForTransfer} from '@lightprotocol/compressed-token'; +import {LightTokenProgram, selectMinCompressedTokenAccountsForTransfer} from '@lightprotocol/compressed-token'; const transferCompressedTokens = async ( fromAddress: string, @@ -42,7 +42,7 @@ const transferCompressedTokens = async ( const proof = await connection.getValidityProof(inputAccounts.map(account => bn(account.compressedAccount.hash))); // Create transfer instruction - const instruction = await CompressedTokenProgram.transfer({ + const instruction = await LightTokenProgram.transfer({ payer: fromPubkey, inputCompressedTokenAccounts: inputAccounts, toAddress: toPubkey, diff --git a/snippets/code-snippets/privy/transfer/react.mdx b/snippets/code-snippets/privy/transfer/react.mdx index 73bdbeed..c532013b 100644 --- a/snippets/code-snippets/privy/transfer/react.mdx +++ b/snippets/code-snippets/privy/transfer/react.mdx @@ -1,7 +1,7 @@ ```typescript import { useState } from 'react'; import { PublicKey, Transaction, ComputeBudgetProgram } from '@solana/web3.js'; -import { CompressedTokenProgram, selectMinCompressedTokenAccountsForTransfer } from '@lightprotocol/compressed-token'; +import { LightTokenProgram, selectMinCompressedTokenAccountsForTransfer } from '@lightprotocol/compressed-token'; import { bn, createRpc } from '@lightprotocol/stateless.js'; import type { ConnectedStandardSolanaWallet } from '@privy-io/js-sdk-core'; import type { SignTransactionResult } from '@privy-io/react-auth/solana'; @@ -60,7 +60,7 @@ export function useTransfer() { ); // Build transfer instruction - const transferIx = await CompressedTokenProgram.transfer({ + const transferIx = await LightTokenProgram.transfer({ payer: owner, inputCompressedTokenAccounts: inputAccounts, toAddress: recipient, diff --git a/snippets/overview-tables/compressed-tokens-guides-table.mdx b/snippets/overview-tables/compressed-tokens-guides-table.mdx index a9997b8c..4e5d2458 100644 --- a/snippets/overview-tables/compressed-tokens-guides-table.mdx +++ b/snippets/overview-tables/compressed-tokens-guides-table.mdx @@ -5,7 +5,7 @@ | [Transfer Compressed Tokens](/compressed-tokens/guides/transfer-compressed-tokens) | Move compressed tokens between compressed accounts | | [Decompress and Compress Tokens](/compressed-tokens/guides/compress-decompress) | Convert SPL tokens between regular and compressed format | | [Compress Complete SPL Token Accounts](/compressed-tokens/guides/compress-spl-token-account) | Compress complete SPL token accounts and reclaim rent afterwards | -| [Create a Mint with Token Pool for Compression](/compressed-tokens/guides/create-mint-with-token-pool) | Create new SPL mint with token pool for compression | -| [Create Token Pools for Mint Accounts](/compressed-tokens/guides/add-token-pools-to-mint-accounts) | Create token pool for compression for existing SPL mints | +| [Create a mint with SPL interface](/compressed-tokens/guides/create-mint-with-token-pool) | Create new SPL mint with SPL Interface PDA for compression | +| [Create SPL interface for existing mints](/compressed-tokens/guides/add-token-pools-to-mint-accounts) | Create SPL Interface PDA (omnibus account) for existing SPL mints | | [Merge Compressed Accounts](/compressed-tokens/guides/merge-compressed-token-accounts) | Consolidate multiple compressed accounts of the same mint into one | | [Approve and Revoke Delegate Authority](/compressed-tokens/guides/delegate) | Approve or revoke delegates for compressed token accounts | diff --git a/snippets/setup/compressed-tokens-mint-prereq.mdx b/snippets/setup/compressed-tokens-mint-prereq.mdx index a45998ff..6d55f472 100644 --- a/snippets/setup/compressed-tokens-mint-prereq.mdx +++ b/snippets/setup/compressed-tokens-mint-prereq.mdx @@ -1,5 +1,5 @@ -Make sure the SPL mint has a token pool for compression.
The script creates this token pool for you. +The SPL mint must have an SPL Interface PDA for compression.
The script creates it for you. -For development, you can create a new mint with token pool via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or add a token pool to an existing mint via [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts). +For development, create a new mint with SPL interface via [`createMint()`](/compressed-tokens/guides/create-mint-with-token-pool) or add an SPL interface to an existing mint via [`createSplInterface()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts).