From cf608162e2b68d447c1c61442bc5bcc6a3ef0685 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 07:23:28 +0000 Subject: [PATCH 1/8] upd js --- .../comparison-spl-light.md | 85 +++++++++---------- toolkits/payments-and-wallets/get-balance.ts | 14 +-- toolkits/payments-and-wallets/get-history.ts | 12 +-- .../payments-and-wallets/send-and-receive.ts | 12 +-- .../actions/transfer-interface.ts | 13 +-- .../instructions/transfer-interface.ts | 16 ++-- 6 files changed, 74 insertions(+), 78 deletions(-) diff --git a/toolkits/payments-and-wallets/comparison-spl-light.md b/toolkits/payments-and-wallets/comparison-spl-light.md index 113dffad..ed0a7ef4 100644 --- a/toolkits/payments-and-wallets/comparison-spl-light.md +++ b/toolkits/payments-and-wallets/comparison-spl-light.md @@ -46,7 +46,7 @@ const ata = await getOrCreateAssociatedTokenAccount( connection, payer, mint, - recipient, + recipient ); // Share ata.address with sender @@ -70,8 +70,8 @@ const tx = new Transaction().add( payer.publicKey, ata, recipient, - mint, - ), + mint + ) ); ``` @@ -102,15 +102,15 @@ const tx = new Transaction().add( ata, recipient, mint, - LIGHT_TOKEN_PROGRAM_ID, + LIGHT_TOKEN_PROGRAM_ID ), ...(await createLoadAtaInstructions( rpc, ata, recipient, mint, - payer.publicKey, - )), + payer.publicKey + )) ); ``` @@ -134,7 +134,7 @@ await transfer( destinationAta, owner, amount, - decimals, + decimals ); ``` @@ -156,8 +156,8 @@ const tx = new Transaction().add( sourceAta, destinationAta, owner.publicKey, - amount, - ), + amount + ) ); ``` @@ -165,46 +165,41 @@ const tx = new Transaction().add( ```typescript const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey); -const destinationAta = getAssociatedTokenAddressInterface(mint, recipient); -await transferInterface( - rpc, - payer, - sourceAta, - mint, - destinationAta, - owner, - amount, -); +await transferInterface(rpc, payer, sourceAta, mint, recipient, owner, amount); ``` -**Light:** +**Light (instruction-level):** ```typescript +import { Transaction, sendAndConfirmTransaction } from "@solana/web3.js"; import { - createLoadAtaInstructions, - createTransferInterfaceInstruction, - getAssociatedTokenAddressInterface, + createTransferInterfaceInstructions, + sliceLast, } 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, - ), +const batches = await createTransferInterfaceInstructions( + rpc, + payer.publicKey, + mint, + amount, + owner.publicKey, + recipient +); +const { rest: loadBatches, last: transferBatch } = sliceLast(batches); + +await Promise.all( + loadBatches.map((batch) => + sendAndConfirmTransaction(rpc, new Transaction().add(...batch), [ + payer, + owner, + ]) + ) ); +await sendAndConfirmTransaction(rpc, new Transaction().add(...transferBatch), [ + payer, + owner, +]); ``` To ensure your recipient's ATA exists you can prepend an idempotent creation instruction in the same atomic transaction: @@ -222,7 +217,7 @@ const createAtaIx = createAssociatedTokenAccountIdempotentInstruction( payer.publicKey, destinationAta, recipient, - mint, + mint ); new Transaction().add(createAtaIx, transferIx); @@ -243,7 +238,7 @@ const createAtaIx = createAssociatedTokenAccountInterfaceIdempotentInstruction( destinationAta, recipient, mint, - LIGHT_TOKEN_PROGRAM_ID, + LIGHT_TOKEN_PROGRAM_ID ); new Transaction().add(createAtaIx, transferIx); @@ -342,7 +337,7 @@ const tx = new Transaction().add( lightTokenAta, owner.publicKey, mint, - payer.publicKey, + payer.publicKey )), createUnwrapInstruction( lightTokenAta, @@ -350,7 +345,7 @@ const tx = new Transaction().add( owner.publicKey, mint, amount, - splInterfaceInfo, - ), + splInterfaceInfo + ) ); ``` diff --git a/toolkits/payments-and-wallets/get-balance.ts b/toolkits/payments-and-wallets/get-balance.ts index d125c6f3..0bc1fa20 100644 --- a/toolkits/payments-and-wallets/get-balance.ts +++ b/toolkits/payments-and-wallets/get-balance.ts @@ -19,8 +19,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -32,7 +32,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - payer, + payer ); // 3. Mint to payer's ATA @@ -44,7 +44,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - recipient, + recipient ); // 5. Transfer from payer to recipient @@ -53,9 +53,9 @@ const payer = Keypair.fromSecretKey( payer, sourceAta.address, mint, - recipientAta.address, + recipient.publicKey, payer, - bn(100), + bn(100) ); // 6. Get recipient's balance after transfer @@ -63,7 +63,7 @@ const payer = Keypair.fromSecretKey( rpc, recipientAta.address, recipient.publicKey, - mint, + mint ); console.log("Recipient's balance:", account.amount); })(); diff --git a/toolkits/payments-and-wallets/get-history.ts b/toolkits/payments-and-wallets/get-history.ts index 5bb1ae7a..3517c9a4 100644 --- a/toolkits/payments-and-wallets/get-history.ts +++ b/toolkits/payments-and-wallets/get-history.ts @@ -18,8 +18,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -31,7 +31,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - payer, + payer ); // 3. Mint to payer's ATA @@ -43,7 +43,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - recipient, + recipient ); // 5. Transfer from payer to recipient @@ -52,9 +52,9 @@ const payer = Keypair.fromSecretKey( payer, sourceAta.address, mint, - recipientAta.address, + recipient.publicKey, payer, - bn(100), + bn(100) ); // 6. Get transaction history diff --git a/toolkits/payments-and-wallets/send-and-receive.ts b/toolkits/payments-and-wallets/send-and-receive.ts index 43d410f6..bba65fae 100644 --- a/toolkits/payments-and-wallets/send-and-receive.ts +++ b/toolkits/payments-and-wallets/send-and-receive.ts @@ -18,8 +18,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -31,7 +31,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - payer, + payer ); // 3. Mint to payer's ATA @@ -43,7 +43,7 @@ const payer = Keypair.fromSecretKey( rpc, payer, mint, - recipient, + recipient ); // 5. Transfer from payer to recipient @@ -52,9 +52,9 @@ const payer = Keypair.fromSecretKey( payer, sourceAta.address, mint, - recipientAta.address, + recipient.publicKey, payer, - bn(100), + bn(100) ); console.log("Tx:", txId); diff --git a/typescript-client/actions/transfer-interface.ts b/typescript-client/actions/transfer-interface.ts index 7c3bf569..71bce5b3 100644 --- a/typescript-client/actions/transfer-interface.ts +++ b/typescript-client/actions/transfer-interface.ts @@ -19,8 +19,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -30,7 +30,7 @@ const payer = Keypair.fromSecretKey( await createAtaInterface(rpc, payer, mint, sender.publicKey); const senderAta = getAssociatedTokenAddressInterface( mint, - sender.publicKey, + sender.publicKey ); await mintToInterface(rpc, payer, mint, senderAta, payer, 1_000_000_000); @@ -38,18 +38,19 @@ const payer = Keypair.fromSecretKey( await createAtaInterface(rpc, payer, mint, recipient.publicKey); const recipientAta = getAssociatedTokenAddressInterface( mint, - recipient.publicKey, + recipient.publicKey ); // Transfer tokens between light-token associated token accounts + // destination is recipient wallet; transferInterface creates recipient ATA idempotently const tx = await transferInterface( rpc, payer, senderAta, mint, - recipientAta, + recipient.publicKey, sender, - 500_000_000, + 500_000_000 ); console.log("Tx:", tx); diff --git a/typescript-client/instructions/transfer-interface.ts b/typescript-client/instructions/transfer-interface.ts index d1a07d92..53245965 100644 --- a/typescript-client/instructions/transfer-interface.ts +++ b/typescript-client/instructions/transfer-interface.ts @@ -1,7 +1,6 @@ import "dotenv/config"; import { Keypair, - ComputeBudgetProgram, Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; @@ -10,7 +9,7 @@ import { createMintInterface, createAtaInterface, mintToInterface, - createTransferInterfaceInstruction, + createLightTokenTransferInstruction, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token"; import { homedir } from "os"; @@ -24,8 +23,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -35,7 +34,7 @@ const payer = Keypair.fromSecretKey( await createAtaInterface(rpc, payer, mint, sender.publicKey); const senderAta = getAssociatedTokenAddressInterface( mint, - sender.publicKey, + sender.publicKey ); await mintToInterface(rpc, payer, mint, senderAta, payer, 1_000_000_000); @@ -43,15 +42,16 @@ const payer = Keypair.fromSecretKey( await createAtaInterface(rpc, payer, mint, recipient.publicKey); const recipientAta = getAssociatedTokenAddressInterface( mint, - recipient.publicKey, + recipient.publicKey ); // Transfer tokens between light-token associate token accounts - const ix = createTransferInterfaceInstruction( + // Hot sender only; for cold balance use createTransferInterfaceInstructions + sliceLast + const ix = createLightTokenTransferInstruction( senderAta, recipientAta, sender.publicKey, - 500_000_000, + 500_000_000 ); const tx = new Transaction().add(ix); From 90c7d723af51993b676ca20a50655fbdc8d9f98e Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 14:32:53 +0000 Subject: [PATCH 2/8] bump to use spl interface --- .../instructions/create-spl-interface.ts | 6 ++--- .../instructions/create-spl-mint.ts | 24 ++++++++++--------- .../instructions/create-t22-mint.ts | 24 ++++++++++--------- .../instructions/create-token-pool.ts | 6 ++--- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/typescript-client/instructions/create-spl-interface.ts b/typescript-client/instructions/create-spl-interface.ts index 8fee304c..99e90e36 100644 --- a/typescript-client/instructions/create-spl-interface.ts +++ b/typescript-client/instructions/create-spl-interface.ts @@ -19,15 +19,15 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); // Register SPL interface PDA to enable interop with Light Tokens - const ix = await CompressedTokenProgram.createTokenPool({ + const ix = await CompressedTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: existingMint, tokenProgramId: TOKEN_PROGRAM_ID, diff --git a/typescript-client/instructions/create-spl-mint.ts b/typescript-client/instructions/create-spl-mint.ts index e906f5c4..4cf107a5 100644 --- a/typescript-client/instructions/create-spl-mint.ts +++ b/typescript-client/instructions/create-spl-mint.ts @@ -23,8 +23,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -32,8 +32,9 @@ const payer = Keypair.fromSecretKey( const decimals = 9; // Get rent for mint account - const rentExemptBalance = - await rpc.getMinimumBalanceForRentExemption(MINT_SIZE); + const rentExemptBalance = await rpc.getMinimumBalanceForRentExemption( + MINT_SIZE + ); // Instruction 1: Create mint account const createMintAccountIx = SystemProgram.createAccount({ @@ -50,21 +51,22 @@ const payer = Keypair.fromSecretKey( decimals, payer.publicKey, // mint authority null, // freeze authority - TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID ); // Instruction 3: Create SPL interface PDA // Holds SPL tokens when wrapped to light-token - const createSplInterfaceIx = await CompressedTokenProgram.createTokenPool({ - feePayer: payer.publicKey, - mint: mintKeypair.publicKey, - tokenProgramId: TOKEN_PROGRAM_ID, - }); + const createSplInterfaceIx = + await CompressedTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint: mintKeypair.publicKey, + tokenProgramId: TOKEN_PROGRAM_ID, + }); const tx = new Transaction().add( createMintAccountIx, initializeMintIx, - createSplInterfaceIx, + createSplInterfaceIx ); const signature = await sendAndConfirmTransaction(rpc, tx, [ diff --git a/typescript-client/instructions/create-t22-mint.ts b/typescript-client/instructions/create-t22-mint.ts index 0bcdd24b..c0875ea3 100644 --- a/typescript-client/instructions/create-t22-mint.ts +++ b/typescript-client/instructions/create-t22-mint.ts @@ -23,8 +23,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -32,8 +32,9 @@ const payer = Keypair.fromSecretKey( const decimals = 9; // Get rent for mint account - const rentExemptBalance = - await rpc.getMinimumBalanceForRentExemption(MINT_SIZE); + const rentExemptBalance = await rpc.getMinimumBalanceForRentExemption( + MINT_SIZE + ); // Instruction 1: Create mint account const createMintAccountIx = SystemProgram.createAccount({ @@ -50,21 +51,22 @@ const payer = Keypair.fromSecretKey( decimals, payer.publicKey, // mint authority null, // freeze authority - TOKEN_2022_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID ); // Instruction 3: Create SPL interface PDA // Holds Token-2022 tokens when wrapped to light-token - const createSplInterfaceIx = await CompressedTokenProgram.createTokenPool({ - feePayer: payer.publicKey, - mint: mintKeypair.publicKey, - tokenProgramId: TOKEN_2022_PROGRAM_ID, - }); + const createSplInterfaceIx = + await CompressedTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint: mintKeypair.publicKey, + tokenProgramId: TOKEN_2022_PROGRAM_ID, + }); const tx = new Transaction().add( createMintAccountIx, initializeMintIx, - createSplInterfaceIx, + createSplInterfaceIx ); const signature = await sendAndConfirmTransaction(rpc, tx, [ diff --git a/typescript-client/instructions/create-token-pool.ts b/typescript-client/instructions/create-token-pool.ts index a0bcdf70..4ce66798 100644 --- a/typescript-client/instructions/create-token-pool.ts +++ b/typescript-client/instructions/create-token-pool.ts @@ -19,14 +19,14 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); - const ix = await CompressedTokenProgram.createTokenPool({ + const ix = await CompressedTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: existingMint, tokenProgramId: TOKEN_PROGRAM_ID, From c71d200c531d27f625735a20c79086e7830a9409 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 17:35:23 +0000 Subject: [PATCH 3/8] update --- .../comparison-spl-light.md | 40 ++++------ toolkits/payments-and-wallets/package.json | 4 + toolkits/payments-and-wallets/receive.ts | 78 +++++++++++++++++++ .../payments-and-wallets/register-spl-mint.ts | 43 ++++++++++ toolkits/payments-and-wallets/send-action.ts | 72 +++++++++++++++++ .../payments-and-wallets/send-instruction.ts | 75 ++++++++++++++++++ .../instructions/create-spl-interface.ts | 4 +- .../instructions/create-spl-mint.ts | 13 ++-- .../instructions/create-t22-mint.ts | 13 ++-- .../instructions/create-token-pool.ts | 4 +- typescript-client/instructions/unwrap.ts | 50 +++++------- 11 files changed, 322 insertions(+), 74 deletions(-) create mode 100644 toolkits/payments-and-wallets/receive.ts create mode 100644 toolkits/payments-and-wallets/register-spl-mint.ts create mode 100644 toolkits/payments-and-wallets/send-action.ts create mode 100644 toolkits/payments-and-wallets/send-instruction.ts diff --git a/toolkits/payments-and-wallets/comparison-spl-light.md b/toolkits/payments-and-wallets/comparison-spl-light.md index ed0a7ef4..f1f4493f 100644 --- a/toolkits/payments-and-wallets/comparison-spl-light.md +++ b/toolkits/payments-and-wallets/comparison-spl-light.md @@ -318,34 +318,22 @@ await unwrap(rpc, payer, splAta, owner, mint, amount); ```typescript 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 lightTokenAta = 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, - lightTokenAta, - owner.publicKey, - mint, - payer.publicKey - )), - createUnwrapInstruction( - lightTokenAta, - splAta, - owner.publicKey, - mint, - amount, - splInterfaceInfo - ) +// Handles loading cold state + unwrapping in one go. +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]); +} ``` diff --git a/toolkits/payments-and-wallets/package.json b/toolkits/payments-and-wallets/package.json index c9b42949..2c06afc3 100644 --- a/toolkits/payments-and-wallets/package.json +++ b/toolkits/payments-and-wallets/package.json @@ -4,6 +4,10 @@ "description": "Light Token Payments Toolkit Examples", "type": "module", "scripts": { + "register-spl-mint": "tsx register-spl-mint.ts", + "receive": "tsx receive.ts", + "send-instruction": "tsx send-instruction.ts", + "send-action": "tsx send-action.ts", "send-and-receive": "tsx send-and-receive.ts", "get-balance": "tsx get-balance.ts", "get-history": "tsx get-history.ts", diff --git a/toolkits/payments-and-wallets/receive.ts b/toolkits/payments-and-wallets/receive.ts new file mode 100644 index 00000000..66fa87c6 --- /dev/null +++ b/toolkits/payments-and-wallets/receive.ts @@ -0,0 +1,78 @@ +import "dotenv/config"; +import { + Keypair, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; +import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { + createMintInterface, + mintToInterface, + getOrCreateAtaInterface, + createLoadAtaInstructions, + getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-token/unified"; +import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); +// localnet: +const rpc = createRpc(); + +const payer = Keypair.fromSecretKey( + new Uint8Array( + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) +); + +(async function () { + // Setup: Create SPL mint with interface, fund an ATA + const { mint } = await createMintInterface( + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID + ); + const { parsed: sourceAta } = await getOrCreateAtaInterface( + rpc, + payer, + mint, + payer + ); + await mintToInterface( + rpc, + payer, + mint, + sourceAta.address, + payer, + bn(1_000_000) + ); + + // Receive: Load creates the ATA if needed and pulls any cold state to hot. + const recipient = Keypair.generate(); + const ata = getAssociatedTokenAddressInterface(mint, recipient.publicKey); + + // Returns TransactionInstruction[][]. Each inner array is one txn. + // Almost always one. Empty = noop. + const instructions = await createLoadAtaInstructions( + rpc, + ata, + recipient.publicKey, + mint, + payer.publicKey + ); + + for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + await sendAndConfirmTransaction(rpc, tx, [payer]); + } + + console.log("Recipient ATA:", ata.toBase58()); +})(); diff --git a/toolkits/payments-and-wallets/register-spl-mint.ts b/toolkits/payments-and-wallets/register-spl-mint.ts new file mode 100644 index 00000000..7309a9e2 --- /dev/null +++ b/toolkits/payments-and-wallets/register-spl-mint.ts @@ -0,0 +1,43 @@ +import "dotenv/config"; +import { + Keypair, + PublicKey, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; +import { createRpc } from "@lightprotocol/stateless.js"; +import { LightTokenProgram } from "@lightprotocol/compressed-token"; +import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); +// localnet: +const rpc = createRpc(); + +const payer = Keypair.fromSecretKey( + new Uint8Array( + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) +); + +(async function () { + // Replace with your existing SPL mint (e.g. USDC) + const mint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); + + // One-time: Register the SPL interface PDA for this mint. + // This creates the omnibus account that holds SPL tokens when wrapped to light-token. + const ix = await LightTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint, + tokenProgramId: TOKEN_PROGRAM_ID, + }); + + const tx = new Transaction().add(ix); + const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); + + console.log("Mint:", mint.toBase58()); + console.log("Tx:", signature); +})(); diff --git a/toolkits/payments-and-wallets/send-action.ts b/toolkits/payments-and-wallets/send-action.ts new file mode 100644 index 00000000..47b67360 --- /dev/null +++ b/toolkits/payments-and-wallets/send-action.ts @@ -0,0 +1,72 @@ +import "dotenv/config"; +import { Keypair } from "@solana/web3.js"; +import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { + createMintInterface, + mintToInterface, + getOrCreateAtaInterface, + getAssociatedTokenAddressInterface, + transferInterface, +} from "@lightprotocol/compressed-token/unified"; +import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); +// localnet: +const rpc = createRpc(); + +const payer = Keypair.fromSecretKey( + new Uint8Array( + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) +); + +(async function () { + // Setup: Create SPL mint with interface, fund an ATA + const { mint } = await createMintInterface( + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID + ); + const { parsed: sourceAta } = await getOrCreateAtaInterface( + rpc, + payer, + mint, + payer + ); + await mintToInterface( + rpc, + payer, + mint, + sourceAta.address, + payer, + bn(1_000_000) + ); + + const recipient = Keypair.generate(); + const sourceAtaAddress = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); + + // Loads cold balances, creates recipient ATA, transfers. + const sig = await transferInterface( + rpc, + payer, + sourceAtaAddress, + mint, + recipient.publicKey, + payer, + bn(100) + ); + + console.log("Tx:", sig); +})(); diff --git a/toolkits/payments-and-wallets/send-instruction.ts b/toolkits/payments-and-wallets/send-instruction.ts new file mode 100644 index 00000000..f369f1d7 --- /dev/null +++ b/toolkits/payments-and-wallets/send-instruction.ts @@ -0,0 +1,75 @@ +import "dotenv/config"; +import { + Keypair, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; +import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { + createMintInterface, + mintToInterface, + getOrCreateAtaInterface, + createTransferInterfaceInstructions, +} from "@lightprotocol/compressed-token/unified"; +import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); +// localnet: +const rpc = createRpc(); + +const payer = Keypair.fromSecretKey( + new Uint8Array( + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) +); + +(async function () { + // Setup: Create SPL mint with interface, fund an ATA + const { mint } = await createMintInterface( + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID + ); + const { parsed: sourceAta } = await getOrCreateAtaInterface( + rpc, + payer, + mint, + payer + ); + await mintToInterface( + rpc, + payer, + mint, + sourceAta.address, + payer, + bn(1_000_000) + ); + + const recipient = Keypair.generate(); + + // Returns TransactionInstruction[][]. Each inner array is one txn. + // Almost always this returns one atomic transaction. + const instructions = await createTransferInterfaceInstructions( + rpc, + payer.publicKey, + mint, + bn(100), + payer.publicKey, + recipient.publicKey + ); + + for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + const sig = await sendAndConfirmTransaction(rpc, tx, [payer]); + console.log("Tx:", sig); + } +})(); diff --git a/typescript-client/instructions/create-spl-interface.ts b/typescript-client/instructions/create-spl-interface.ts index 99e90e36..7a6736dd 100644 --- a/typescript-client/instructions/create-spl-interface.ts +++ b/typescript-client/instructions/create-spl-interface.ts @@ -6,7 +6,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( const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); // Register SPL interface PDA to enable interop with Light Tokens - const ix = await CompressedTokenProgram.createSplInterface({ + const ix = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: existingMint, tokenProgramId: TOKEN_PROGRAM_ID, diff --git a/typescript-client/instructions/create-spl-mint.ts b/typescript-client/instructions/create-spl-mint.ts index 4cf107a5..9a8e68f9 100644 --- a/typescript-client/instructions/create-spl-mint.ts +++ b/typescript-client/instructions/create-spl-mint.ts @@ -6,7 +6,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, @@ -56,12 +56,11 @@ const payer = Keypair.fromSecretKey( // Instruction 3: Create SPL interface PDA // Holds SPL tokens when wrapped to light-token - const createSplInterfaceIx = - await CompressedTokenProgram.createSplInterface({ - feePayer: payer.publicKey, - mint: mintKeypair.publicKey, - tokenProgramId: TOKEN_PROGRAM_ID, - }); + const createSplInterfaceIx = await LightTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint: mintKeypair.publicKey, + tokenProgramId: TOKEN_PROGRAM_ID, + }); const tx = new Transaction().add( createMintAccountIx, diff --git a/typescript-client/instructions/create-t22-mint.ts b/typescript-client/instructions/create-t22-mint.ts index c0875ea3..10bf770f 100644 --- a/typescript-client/instructions/create-t22-mint.ts +++ b/typescript-client/instructions/create-t22-mint.ts @@ -6,7 +6,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,12 +56,11 @@ const payer = Keypair.fromSecretKey( // Instruction 3: Create SPL interface PDA // Holds Token-2022 tokens when wrapped to light-token - const createSplInterfaceIx = - await CompressedTokenProgram.createSplInterface({ - feePayer: payer.publicKey, - mint: mintKeypair.publicKey, - tokenProgramId: TOKEN_2022_PROGRAM_ID, - }); + const createSplInterfaceIx = await LightTokenProgram.createSplInterface({ + feePayer: payer.publicKey, + mint: mintKeypair.publicKey, + tokenProgramId: TOKEN_2022_PROGRAM_ID, + }); const tx = new Transaction().add( createMintAccountIx, diff --git a/typescript-client/instructions/create-token-pool.ts b/typescript-client/instructions/create-token-pool.ts index 4ce66798..7f375705 100644 --- a/typescript-client/instructions/create-token-pool.ts +++ b/typescript-client/instructions/create-token-pool.ts @@ -6,7 +6,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"; @@ -26,7 +26,7 @@ const payer = Keypair.fromSecretKey( (async function () { const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS"); - const ix = await CompressedTokenProgram.createSplInterface({ + const ix = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint: existingMint, tokenProgramId: TOKEN_PROGRAM_ID, diff --git a/typescript-client/instructions/unwrap.ts b/typescript-client/instructions/unwrap.ts index 9a9598f1..342f3338 100644 --- a/typescript-client/instructions/unwrap.ts +++ b/typescript-client/instructions/unwrap.ts @@ -1,7 +1,6 @@ import "dotenv/config"; import { Keypair, - ComputeBudgetProgram, Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; @@ -11,9 +10,8 @@ import { createAtaInterface, mintToInterface, getAssociatedTokenAddressInterface, - getSplInterfaceInfos, -} from "@lightprotocol/compressed-token"; -import { createUnwrapInstruction } from "@lightprotocol/compressed-token/unified"; + createUnwrapInstructions, +} from "@lightprotocol/compressed-token/unified"; import { createAssociatedTokenAccount, TOKEN_2022_PROGRAM_ID, @@ -29,52 +27,44 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // Setup: Create and mint tokens to light-token associated token account const { mint } = await createMintInterface(rpc, payer, payer, null, 9); await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const destination = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await mintToInterface(rpc, payer, mint, destination, payer, 1000); - // Unwrap light-token to SPL associated token account - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); - + // Create destination SPL ATA const splAta = await createAssociatedTokenAccount( rpc, payer, mint, payer.publicKey, undefined, - TOKEN_2022_PROGRAM_ID, - ); - - const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint); - const splInterfaceInfo = splInterfaceInfos.find( - (info) => info.isInitialized, + TOKEN_2022_PROGRAM_ID ); - 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, 500, - splInterfaceInfo, - 9, // decimals - must match the mint decimals - payer.publicKey, - ); - - const tx = new Transaction().add( - ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }), - ix, + payer.publicKey ); - const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); - console.log("Tx:", signature); + for (const ixs of instructions) { + const tx = new Transaction().add(...ixs); + const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); + console.log("Tx:", signature); + } })(); From ffba3b8f758994307d5e025f8bdad73cf8d65dee Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 18:38:36 +0000 Subject: [PATCH 4/8] go --- .gitignore | 3 + package.json | 4 +- toolkits/payments-and-wallets/get-balance.ts | 69 ++++++++----------- toolkits/payments-and-wallets/get-history.ts | 63 +++++++---------- toolkits/payments-and-wallets/receive.ts | 67 ++++++++---------- .../payments-and-wallets/register-spl-mint.ts | 5 +- toolkits/payments-and-wallets/send-action.ts | 62 +++++++---------- .../payments-and-wallets/send-and-receive.ts | 57 ++++++++------- .../payments-and-wallets/send-instruction.ts | 45 ++++++------ toolkits/payments-and-wallets/unwrap.ts | 38 +++++----- toolkits/payments-and-wallets/wrap.ts | 45 +++++------- typescript-client/package.json | 4 +- 12 files changed, 203 insertions(+), 259 deletions(-) diff --git a/.gitignore b/.gitignore index 02a57608..8563720b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ cli/accounts README.html README_files/ + +**/.surfpool +.surfpool \ No newline at end of file diff --git a/package.json b/package.json index 841373f0..8cac5cec 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "toolkit:payments": "npm run -w toolkits/payments-and-wallets" }, "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.5", - "@lightprotocol/stateless.js": "^0.23.0-beta.5", + "@lightprotocol/compressed-token": "^0.23.0-beta.6", + "@lightprotocol/stateless.js": "^0.23.0-beta.6", "@solana/spl-token": "^0.4.13", "@solana/web3.js": "1.98.4", "dotenv": "^16.5.0" diff --git a/toolkits/payments-and-wallets/get-balance.ts b/toolkits/payments-and-wallets/get-balance.ts index 0bc1fa20..35f62af5 100644 --- a/toolkits/payments-and-wallets/get-balance.ts +++ b/toolkits/payments-and-wallets/get-balance.ts @@ -1,20 +1,22 @@ import "dotenv/config"; import { Keypair } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { - getOrCreateAtaInterface, - transferInterface, createMintInterface, - mintToInterface, + createAtaInterface, + getAssociatedTokenAddressInterface, + transferInterface, getAtaInterface, -} from "@lightprotocol/compressed-token/unified"; +} from "@lightprotocol/compressed-token"; +import { wrap } from "@lightprotocol/compressed-token/unified"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -24,46 +26,33 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // 1. Create mint - const { mint } = await createMintInterface(rpc, payer, payer, null, 9); + // Setup: Create SPL mint, fund sender + const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, + ); - // 2. Create ATA for payer (source) - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1000); - // 3. Mint to payer's ATA - await mintToInterface(rpc, payer, mint, sourceAta.address, payer, bn(1000)); + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, senderAta, payer, mint, BigInt(1000)); - // 4. Create ATA for recipient + // Transfer to recipient const recipient = Keypair.generate(); - const { parsed: recipientAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - recipient - ); + await createAtaInterface(rpc, payer, mint, recipient.publicKey); + await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 100); - // 5. Transfer from payer to recipient - await transferInterface( - rpc, - payer, - sourceAta.address, - mint, - recipient.publicKey, - payer, - bn(100) - ); - - // 6. Get recipient's balance after transfer + // Get recipient's balance + const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); const { parsed: account } = await getAtaInterface( rpc, - recipientAta.address, + recipientAta, recipient.publicKey, - mint + mint, ); console.log("Recipient's balance:", account.amount); })(); diff --git a/toolkits/payments-and-wallets/get-history.ts b/toolkits/payments-and-wallets/get-history.ts index 3517c9a4..7703e070 100644 --- a/toolkits/payments-and-wallets/get-history.ts +++ b/toolkits/payments-and-wallets/get-history.ts @@ -1,19 +1,21 @@ import "dotenv/config"; import { Keypair } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { - getOrCreateAtaInterface, - transferInterface, createMintInterface, - mintToInterface, -} from "@lightprotocol/compressed-token/unified"; + createAtaInterface, + getAssociatedTokenAddressInterface, + transferInterface, +} from "@lightprotocol/compressed-token"; +import { wrap } from "@lightprotocol/compressed-token/unified"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -23,41 +25,26 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // 1. Create mint - const { mint } = await createMintInterface(rpc, payer, payer, null, 9); + // Setup: Create SPL mint, fund sender + const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, + ); - // 2. Create ATA for payer (source) - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1000); - // 3. Mint to payer's ATA - await mintToInterface(rpc, payer, mint, sourceAta.address, payer, bn(1000)); + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, senderAta, payer, mint, BigInt(1000)); - // 4. Create ATA for recipient + // Transfer to recipient const recipient = Keypair.generate(); - const { parsed: recipientAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - recipient - ); - - // 5. Transfer from payer to recipient - await transferInterface( - rpc, - payer, - sourceAta.address, - mint, - recipient.publicKey, - payer, - bn(100) - ); + await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 100); - // 6. Get transaction history + // Get transaction history const result = await rpc.getSignaturesForOwnerInterface(payer.publicKey); console.log("Signatures:", result.signatures.length); })(); diff --git a/toolkits/payments-and-wallets/receive.ts b/toolkits/payments-and-wallets/receive.ts index 66fa87c6..d6705b4f 100644 --- a/toolkits/payments-and-wallets/receive.ts +++ b/toolkits/payments-and-wallets/receive.ts @@ -4,22 +4,23 @@ import { Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { createMintInterface, - mintToInterface, - getOrCreateAtaInterface, - createLoadAtaInstructions, + createAtaInterface, getAssociatedTokenAddressInterface, -} from "@lightprotocol/compressed-token/unified"; -import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; + transferInterface, + createLoadAtaInstructions, +} from "@lightprotocol/compressed-token"; +import { wrap } from "@lightprotocol/compressed-token/unified"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -29,44 +30,36 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // Setup: Create SPL mint with interface, fund an ATA + // --- Setup: create SPL mint, fund sender, transfer to recipient --- const { mint } = await createMintInterface( - rpc, - payer, - payer, - null, - 9, - undefined, - undefined, - TOKEN_PROGRAM_ID - ); - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, ); - await mintToInterface( - rpc, - payer, - mint, - sourceAta.address, - payer, - bn(1_000_000) + + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); + + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, senderAta, payer, mint, BigInt(1_000_000)); - // Receive: Load creates the ATA if needed and pulls any cold state to hot. + // Transfer to a fresh recipient so they have cold tokens const recipient = Keypair.generate(); - const ata = getAssociatedTokenAddressInterface(mint, recipient.publicKey); + await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 500); + + // --- Receive: load creates ATA if needed + pulls cold state to hot --- + const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); // Returns TransactionInstruction[][]. Each inner array is one txn. // Almost always one. Empty = noop. const instructions = await createLoadAtaInstructions( rpc, - ata, + recipientAta, recipient.publicKey, mint, - payer.publicKey + payer.publicKey, ); for (const ixs of instructions) { @@ -74,5 +67,5 @@ const payer = Keypair.fromSecretKey( await sendAndConfirmTransaction(rpc, tx, [payer]); } - console.log("Recipient ATA:", ata.toBase58()); + console.log("Recipient ATA:", recipientAta.toBase58()); })(); diff --git a/toolkits/payments-and-wallets/register-spl-mint.ts b/toolkits/payments-and-wallets/register-spl-mint.ts index 7309a9e2..bb1f362b 100644 --- a/toolkits/payments-and-wallets/register-spl-mint.ts +++ b/toolkits/payments-and-wallets/register-spl-mint.ts @@ -11,10 +11,6 @@ import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -29,6 +25,7 @@ const payer = Keypair.fromSecretKey( // One-time: Register the SPL interface PDA for this mint. // This creates the omnibus account that holds SPL tokens when wrapped to light-token. + // Note: createMintInterface(... TOKEN_PROGRAM_ID) does this automatically for new mints. const ix = await LightTokenProgram.createSplInterface({ feePayer: payer.publicKey, mint, diff --git a/toolkits/payments-and-wallets/send-action.ts b/toolkits/payments-and-wallets/send-action.ts index 47b67360..531142a0 100644 --- a/toolkits/payments-and-wallets/send-action.ts +++ b/toolkits/payments-and-wallets/send-action.ts @@ -1,21 +1,23 @@ import "dotenv/config"; import { Keypair } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { createMintInterface, - mintToInterface, - getOrCreateAtaInterface, + createAtaInterface, getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-token"; +import { transferInterface, + wrap, } from "@lightprotocol/compressed-token/unified"; -import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -25,47 +27,33 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // Setup: Create SPL mint with interface, fund an ATA + // Setup: Create SPL mint (auto-registers SPL interface PDA) const { mint } = await createMintInterface( - rpc, - payer, - payer, - null, - 9, - undefined, - undefined, - TOKEN_PROGRAM_ID - ); - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, ); - await mintToInterface( - rpc, - payer, - mint, - sourceAta.address, - payer, - bn(1_000_000) + + // Fund payer with SPL tokens, then wrap into c-token ATA + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const cTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, cTokenAta, payer, mint, BigInt(1_000_000)); + // --- Transfer (action-level) --- const recipient = Keypair.generate(); - const sourceAtaAddress = getAssociatedTokenAddressInterface( - mint, - payer.publicKey - ); - // Loads cold balances, creates recipient ATA, transfers. + // Handles loading cold balances, creates recipient ATA, transfers. const sig = await transferInterface( rpc, payer, - sourceAtaAddress, + cTokenAta, mint, recipient.publicKey, payer, - bn(100) + 100, ); console.log("Tx:", sig); diff --git a/toolkits/payments-and-wallets/send-and-receive.ts b/toolkits/payments-and-wallets/send-and-receive.ts index bba65fae..5490b808 100644 --- a/toolkits/payments-and-wallets/send-and-receive.ts +++ b/toolkits/payments-and-wallets/send-and-receive.ts @@ -1,19 +1,21 @@ import "dotenv/config"; import { Keypair } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { - getOrCreateAtaInterface, - transferInterface, createMintInterface, - mintToInterface, -} from "@lightprotocol/compressed-token/unified"; + createAtaInterface, + getAssociatedTokenAddressInterface, + transferInterface, +} from "@lightprotocol/compressed-token"; +import { wrap } from "@lightprotocol/compressed-token/unified"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -23,38 +25,33 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // 1. Create mint - const { mint } = await createMintInterface(rpc, payer, payer, null, 9); + // 1. Create SPL mint (includes SPL interface PDA registration) + const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, + ); - // 2. Create ATA for payer (source) - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer + // 2. Fund payer with SPL tokens + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); - // 3. Mint to payer's ATA - await mintToInterface(rpc, payer, mint, sourceAta.address, payer, bn(1000)); + // 3. Create c-token ATA and wrap SPL tokens into it + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, senderAta, payer, mint, BigInt(1_000_000)); - // 4. Create ATA for recipient + // 4. Transfer from payer to recipient const recipient = Keypair.generate(); - const { parsed: recipientAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - recipient - ); - - // 5. Transfer from payer to recipient const txId = await transferInterface( rpc, payer, - sourceAta.address, + senderAta, mint, recipient.publicKey, payer, - bn(100) + 100, ); console.log("Tx:", txId); diff --git a/toolkits/payments-and-wallets/send-instruction.ts b/toolkits/payments-and-wallets/send-instruction.ts index f369f1d7..a7dd5d48 100644 --- a/toolkits/payments-and-wallets/send-instruction.ts +++ b/toolkits/payments-and-wallets/send-instruction.ts @@ -4,21 +4,24 @@ import { Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; -import { createRpc, bn } from "@lightprotocol/stateless.js"; +import { createRpc } from "@lightprotocol/stateless.js"; import { createMintInterface, - mintToInterface, - getOrCreateAtaInterface, + createAtaInterface, + getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-token"; +import { createTransferInterfaceInstructions, + wrap, } from "@lightprotocol/compressed-token/unified"; -import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; +import { + TOKEN_PROGRAM_ID, + createAssociatedTokenAccount, + mintTo, +} 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -28,7 +31,7 @@ const payer = Keypair.fromSecretKey( ); (async function () { - // Setup: Create SPL mint with interface, fund an ATA + // Setup: Create SPL mint (includes SPL interface PDA registration) const { mint } = await createMintInterface( rpc, payer, @@ -39,20 +42,22 @@ const payer = Keypair.fromSecretKey( undefined, TOKEN_PROGRAM_ID ); - const { parsed: sourceAta } = await getOrCreateAtaInterface( - rpc, - payer, - mint, - payer - ); - await mintToInterface( + + // Fund payer with SPL tokens + const splAta = await createAssociatedTokenAccount( rpc, payer, mint, - sourceAta.address, - payer, - bn(1_000_000) + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); + await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); + + // Create c-token ATA and wrap SPL tokens into it + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const cTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, cTokenAta, payer, mint, BigInt(1_000_000)); const recipient = Keypair.generate(); @@ -62,7 +67,7 @@ const payer = Keypair.fromSecretKey( rpc, payer.publicKey, mint, - bn(100), + 100, payer.publicKey, recipient.publicKey ); diff --git a/toolkits/payments-and-wallets/unwrap.ts b/toolkits/payments-and-wallets/unwrap.ts index 5bba7b66..3c2ad929 100644 --- a/toolkits/payments-and-wallets/unwrap.ts +++ b/toolkits/payments-and-wallets/unwrap.ts @@ -4,24 +4,17 @@ import { createRpc } from "@lightprotocol/stateless.js"; import { createMintInterface, createAtaInterface, - mintToInterface, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token"; +import { wrap, unwrap } from "@lightprotocol/compressed-token/unified"; import { - unwrap, - getOrCreateAtaInterface, -} from "@lightprotocol/compressed-token/unified"; -import { + TOKEN_PROGRAM_ID, createAssociatedTokenAccount, - TOKEN_2022_PROGRAM_ID, + mintTo, } 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -31,21 +24,24 @@ const payer = Keypair.fromSecretKey( ); (async function () { - const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); - await mintToInterface(rpc, payer, mint, destination, payer, 1000); - await getOrCreateAtaInterface(rpc, payer, mint, payer); + // 1. Create SPL mint (includes SPL interface PDA registration) + const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, + ); + // 2. Create SPL ATA and mint tokens const splAta = await createAssociatedTokenAccount( - rpc, - payer, - mint, - payer.publicKey, - undefined, - TOKEN_2022_PROGRAM_ID, + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); + await mintTo(rpc, payer, mint, splAta, payer, 1000); + + // 3. Create c-token ATA and wrap all SPL tokens into it + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, BigInt(1000)); + // 4. Unwrap: move tokens back from light-token to SPL ATA const tx = await unwrap(rpc, payer, splAta, payer, mint, 500); console.log("Tx:", tx); diff --git a/toolkits/payments-and-wallets/wrap.ts b/toolkits/payments-and-wallets/wrap.ts index e3c8440b..4418876d 100644 --- a/toolkits/payments-and-wallets/wrap.ts +++ b/toolkits/payments-and-wallets/wrap.ts @@ -4,25 +4,17 @@ import { createRpc } from "@lightprotocol/stateless.js"; import { createMintInterface, createAtaInterface, - mintToInterface, - decompressInterface, getAssociatedTokenAddressInterface, } from "@lightprotocol/compressed-token"; +import { wrap } from "@lightprotocol/compressed-token/unified"; import { - wrap, - createAtaInterfaceIdempotent, -} from "@lightprotocol/compressed-token/unified"; -import { + TOKEN_PROGRAM_ID, createAssociatedTokenAccount, - TOKEN_2022_PROGRAM_ID, + mintTo, } 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 = createRpc(RPC_URL); -// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -32,27 +24,24 @@ const payer = Keypair.fromSecretKey( ); (async function () { - const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); - await mintToInterface(rpc, payer, mint, destination, payer, 1000); - const splAta = await createAssociatedTokenAccount( - rpc, - payer, - mint, - payer.publicKey, - undefined, - TOKEN_2022_PROGRAM_ID, + // 1. Create SPL mint (includes SPL interface PDA registration) + const { mint } = await createMintInterface( + rpc, payer, payer, null, 9, + undefined, undefined, TOKEN_PROGRAM_ID, ); - await decompressInterface(rpc, payer, payer, mint, 1000); - const lightTokenAta = getAssociatedTokenAddressInterface( - mint, - payer.publicKey, + // 2. Create SPL ATA and mint tokens + const splAta = await createAssociatedTokenAccount( + rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, ); - await createAtaInterfaceIdempotent(rpc, payer, mint, payer.publicKey); + await mintTo(rpc, payer, mint, splAta, payer, 1000); + + // 3. Create c-token ATA + await createAtaInterface(rpc, payer, mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); - const tx = await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, 500); + // 4. Wrap: move SPL tokens into the light-token system + const tx = await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, BigInt(500)); console.log("Tx:", tx); })(); diff --git a/typescript-client/package.json b/typescript-client/package.json index 83977500..1e8b4e22 100644 --- a/typescript-client/package.json +++ b/typescript-client/package.json @@ -4,8 +4,8 @@ "type": "module", "description": "Working examples for light-token operations on Solana devnet", "dependencies": { - "@lightprotocol/compressed-token": "beta", - "@lightprotocol/stateless.js": "beta", + "@lightprotocol/compressed-token": "^0.23.0-beta.6", + "@lightprotocol/stateless.js": "^0.23.0-beta.6", "@solana/web3.js": "^1.98.0", "dotenv": "^16.0.0" }, From b05de09d82a3dbb858c30f67178418111de474b3 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 18:47:16 +0000 Subject: [PATCH 5/8] use beta in ci --- .github/workflows/typescript-tests.yml | 158 ++++++++++++------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/.github/workflows/typescript-tests.yml b/.github/workflows/typescript-tests.yml index e1f99bf3..f0add760 100644 --- a/.github/workflows/typescript-tests.yml +++ b/.github/workflows/typescript-tests.yml @@ -1,88 +1,88 @@ name: TypeScript on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened] - branches: - - main + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + branches: + - main concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: - SOLANA_CLI_VERSION: "2.1.21" - NODE_VERSION: "22" + SOLANA_CLI_VERSION: "2.1.21" + NODE_VERSION: "22" jobs: - typescript-tests: - name: TypeScript Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Cache Solana CLI tools - uses: actions/cache@v4 - with: - path: | - ~/.cache/solana/ - ~/.local/share/solana/ - key: solana-cli-${{ runner.os }}-${{ env.SOLANA_CLI_VERSION }} - - - name: Install Solana CLI tools - run: | - sh -c "$(curl -sSfL https://release.anza.xyz/v${{ env.SOLANA_CLI_VERSION }}/install)" - echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH - - - name: Install Light CLI - run: npm install -g @lightprotocol/zk-compression-cli@alpha - - - name: Install Rust (for Photon) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - cache: false - - - name: Cache Photon indexer - id: cache-photon - uses: actions/cache@v4 - with: - path: ~/.cargo/bin/photon - key: photon-${{ runner.os }}-ac7df6c388db847b7693a7a1cb766a7c9d7809b5 - - - name: Install Photon indexer - if: steps.cache-photon.outputs.cache-hit != 'true' - run: cargo install --git https://github.com/lightprotocol/photon.git --rev ac7df6c388db847b7693a7a1cb766a7c9d7809b5 --locked - env: - RUSTFLAGS: "-A dead-code" - - - name: Generate keypair - run: solana-keygen new --no-bip39-passphrase - - - name: Install dependencies - working-directory: typescript-client - run: npm install - - - name: Start test validator - run: | - light test-validator & - for i in $(seq 1 60); do - curl -s http://127.0.0.1:8784/health && break - sleep 2 - done - - - name: Run actions - working-directory: typescript-client - run: npm run test:actions - - - name: Run instructions - working-directory: typescript-client - run: npm run test:instructions + typescript-tests: + name: TypeScript Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Cache Solana CLI tools + uses: actions/cache@v4 + with: + path: | + ~/.cache/solana/ + ~/.local/share/solana/ + key: solana-cli-${{ runner.os }}-${{ env.SOLANA_CLI_VERSION }} + + - name: Install Solana CLI tools + run: | + sh -c "$(curl -sSfL https://release.anza.xyz/v${{ env.SOLANA_CLI_VERSION }}/install)" + echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH + + - name: Install Light CLI + run: npm install -g @lightprotocol/zk-compression-cli@beta + + - name: Install Rust (for Photon) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + cache: false + + - name: Cache Photon indexer + id: cache-photon + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/photon + key: photon-${{ runner.os }}-ac7df6c388db847b7693a7a1cb766a7c9d7809b5 + + - name: Install Photon indexer + if: steps.cache-photon.outputs.cache-hit != 'true' + run: cargo install --git https://github.com/lightprotocol/photon.git --rev ac7df6c388db847b7693a7a1cb766a7c9d7809b5 --locked + env: + RUSTFLAGS: "-A dead-code" + + - name: Generate keypair + run: solana-keygen new --no-bip39-passphrase + + - name: Install dependencies + working-directory: typescript-client + run: npm install + + - name: Start test validator + run: | + light test-validator & + for i in $(seq 1 60); do + curl -s http://127.0.0.1:8784/health && break + sleep 2 + done + + - name: Run actions + working-directory: typescript-client + run: npm run test:actions + + - name: Run instructions + working-directory: typescript-client + run: npm run test:instructions From 352b886538a24699b32b73178aefc42bc89ea710 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 19:19:46 +0000 Subject: [PATCH 6/8] fix --- toolkits/payments-and-wallets/get-balance.ts | 38 ++++++++++++++--- toolkits/payments-and-wallets/get-history.ts | 31 ++++++++++++-- toolkits/payments-and-wallets/receive.ts | 38 ++++++++++++++--- .../payments-and-wallets/register-spl-mint.ts | 4 ++ toolkits/payments-and-wallets/send-action.ts | 26 +++++++++--- .../payments-and-wallets/send-and-receive.ts | 25 ++++++++--- .../payments-and-wallets/send-instruction.ts | 6 ++- toolkits/payments-and-wallets/unwrap.ts | 32 ++++++++++---- toolkits/payments-and-wallets/wrap.ts | 42 +++++++++++++++---- 9 files changed, 199 insertions(+), 43 deletions(-) diff --git a/toolkits/payments-and-wallets/get-balance.ts b/toolkits/payments-and-wallets/get-balance.ts index 35f62af5..daa27a30 100644 --- a/toolkits/payments-and-wallets/get-balance.ts +++ b/toolkits/payments-and-wallets/get-balance.ts @@ -17,6 +17,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -28,12 +32,23 @@ const payer = Keypair.fromSecretKey( (async function () { // Setup: Create SPL mint, fund sender const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1000); @@ -44,15 +59,26 @@ const payer = Keypair.fromSecretKey( // Transfer to recipient const recipient = Keypair.generate(); await createAtaInterface(rpc, payer, mint, recipient.publicKey); - await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 100); + await transferInterface( + rpc, + payer, + senderAta, + mint, + recipient.publicKey, + payer, + 100 + ); // Get recipient's balance - const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); + const recipientAta = getAssociatedTokenAddressInterface( + mint, + recipient.publicKey + ); const { parsed: account } = await getAtaInterface( rpc, recipientAta, recipient.publicKey, - mint, + mint ); console.log("Recipient's balance:", account.amount); })(); diff --git a/toolkits/payments-and-wallets/get-history.ts b/toolkits/payments-and-wallets/get-history.ts index 7703e070..d404dd14 100644 --- a/toolkits/payments-and-wallets/get-history.ts +++ b/toolkits/payments-and-wallets/get-history.ts @@ -16,6 +16,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -27,12 +31,23 @@ const payer = Keypair.fromSecretKey( (async function () { // Setup: Create SPL mint, fund sender const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1000); @@ -42,7 +57,15 @@ const payer = Keypair.fromSecretKey( // Transfer to recipient const recipient = Keypair.generate(); - await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 100); + await transferInterface( + rpc, + payer, + senderAta, + mint, + recipient.publicKey, + payer, + 100 + ); // Get transaction history const result = await rpc.getSignaturesForOwnerInterface(payer.publicKey); diff --git a/toolkits/payments-and-wallets/receive.ts b/toolkits/payments-and-wallets/receive.ts index d6705b4f..1f871e84 100644 --- a/toolkits/payments-and-wallets/receive.ts +++ b/toolkits/payments-and-wallets/receive.ts @@ -21,6 +21,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -32,12 +36,23 @@ const payer = Keypair.fromSecretKey( (async function () { // --- Setup: create SPL mint, fund sender, transfer to recipient --- const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); @@ -47,10 +62,21 @@ const payer = Keypair.fromSecretKey( // Transfer to a fresh recipient so they have cold tokens const recipient = Keypair.generate(); - await transferInterface(rpc, payer, senderAta, mint, recipient.publicKey, payer, 500); + await transferInterface( + rpc, + payer, + senderAta, + mint, + recipient.publicKey, + payer, + 500 + ); // --- Receive: load creates ATA if needed + pulls cold state to hot --- - const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); + const recipientAta = getAssociatedTokenAddressInterface( + mint, + recipient.publicKey + ); // Returns TransactionInstruction[][]. Each inner array is one txn. // Almost always one. Empty = noop. @@ -59,7 +85,7 @@ const payer = Keypair.fromSecretKey( recipientAta, recipient.publicKey, mint, - payer.publicKey, + payer.publicKey ); for (const ixs of instructions) { diff --git a/toolkits/payments-and-wallets/register-spl-mint.ts b/toolkits/payments-and-wallets/register-spl-mint.ts index bb1f362b..492f0538 100644 --- a/toolkits/payments-and-wallets/register-spl-mint.ts +++ b/toolkits/payments-and-wallets/register-spl-mint.ts @@ -11,6 +11,10 @@ import { TOKEN_PROGRAM_ID } 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( diff --git a/toolkits/payments-and-wallets/send-action.ts b/toolkits/payments-and-wallets/send-action.ts index 531142a0..d98566cb 100644 --- a/toolkits/payments-and-wallets/send-action.ts +++ b/toolkits/payments-and-wallets/send-action.ts @@ -18,6 +18,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -29,20 +33,30 @@ const payer = Keypair.fromSecretKey( (async function () { // Setup: Create SPL mint (auto-registers SPL interface PDA) const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); - // Fund payer with SPL tokens, then wrap into c-token ATA + // Fund payer with SPL tokens, then wrap into light-token ATA const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); await createAtaInterface(rpc, payer, mint, payer.publicKey); const cTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); await wrap(rpc, payer, splAta, cTokenAta, payer, mint, BigInt(1_000_000)); - // --- Transfer (action-level) --- const recipient = Keypair.generate(); // Handles loading cold balances, creates recipient ATA, transfers. @@ -53,7 +67,7 @@ const payer = Keypair.fromSecretKey( mint, recipient.publicKey, payer, - 100, + 100 ); console.log("Tx:", sig); diff --git a/toolkits/payments-and-wallets/send-and-receive.ts b/toolkits/payments-and-wallets/send-and-receive.ts index 5490b808..9f726f2d 100644 --- a/toolkits/payments-and-wallets/send-and-receive.ts +++ b/toolkits/payments-and-wallets/send-and-receive.ts @@ -16,6 +16,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -27,17 +31,28 @@ const payer = Keypair.fromSecretKey( (async function () { // 1. Create SPL mint (includes SPL interface PDA registration) const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); // 2. Fund payer with SPL tokens const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); - // 3. Create c-token ATA and wrap SPL tokens into it + // 3. Create light-token ATA and wrap SPL tokens into it await createAtaInterface(rpc, payer, mint, payer.publicKey); const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); await wrap(rpc, payer, splAta, senderAta, payer, mint, BigInt(1_000_000)); @@ -51,7 +66,7 @@ const payer = Keypair.fromSecretKey( mint, recipient.publicKey, payer, - 100, + 100 ); console.log("Tx:", txId); diff --git a/toolkits/payments-and-wallets/send-instruction.ts b/toolkits/payments-and-wallets/send-instruction.ts index a7dd5d48..0a0633aa 100644 --- a/toolkits/payments-and-wallets/send-instruction.ts +++ b/toolkits/payments-and-wallets/send-instruction.ts @@ -22,6 +22,10 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( @@ -54,7 +58,7 @@ const payer = Keypair.fromSecretKey( ); await mintTo(rpc, payer, mint, splAta, payer, 1_000_000); - // Create c-token ATA and wrap SPL tokens into it + // Create light-token ATA and wrap SPL tokens into it await createAtaInterface(rpc, payer, mint, payer.publicKey); const cTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); await wrap(rpc, payer, splAta, cTokenAta, payer, mint, BigInt(1_000_000)); diff --git a/toolkits/payments-and-wallets/unwrap.ts b/toolkits/payments-and-wallets/unwrap.ts index 3c2ad929..8a9b7401 100644 --- a/toolkits/payments-and-wallets/unwrap.ts +++ b/toolkits/payments-and-wallets/unwrap.ts @@ -15,30 +15,48 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // 1. Create SPL mint (includes SPL interface PDA registration) const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); // 2. Create SPL ATA and mint tokens const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1000); - // 3. Create c-token ATA and wrap all SPL tokens into it + // 3. Create light-token ATA and wrap all SPL tokens into it await createAtaInterface(rpc, payer, mint, payer.publicKey); - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, BigInt(1000)); // 4. Unwrap: move tokens back from light-token to SPL ATA diff --git a/toolkits/payments-and-wallets/wrap.ts b/toolkits/payments-and-wallets/wrap.ts index 4418876d..a64ef1a2 100644 --- a/toolkits/payments-and-wallets/wrap.ts +++ b/toolkits/payments-and-wallets/wrap.ts @@ -15,33 +15,59 @@ import { 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 = createRpc(RPC_URL); +// localnet: const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // 1. Create SPL mint (includes SPL interface PDA registration) const { mint } = await createMintInterface( - rpc, payer, payer, null, 9, - undefined, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + payer, + null, + 9, + undefined, + undefined, + TOKEN_PROGRAM_ID ); // 2. Create SPL ATA and mint tokens const splAta = await createAssociatedTokenAccount( - rpc, payer, mint, payer.publicKey, undefined, TOKEN_PROGRAM_ID, + rpc, + payer, + mint, + payer.publicKey, + undefined, + TOKEN_PROGRAM_ID ); await mintTo(rpc, payer, mint, splAta, payer, 1000); - // 3. Create c-token ATA + // 3. Create light-token ATA await createAtaInterface(rpc, payer, mint, payer.publicKey); - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); // 4. Wrap: move SPL tokens into the light-token system - const tx = await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, BigInt(500)); + const tx = await wrap( + rpc, + payer, + splAta, + lightTokenAta, + payer, + mint, + BigInt(500) + ); console.log("Tx:", tx); })(); From 58113e7d5db3f38e8de1963ab01933f5a03d0936 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 19:30:49 +0000 Subject: [PATCH 7/8] fix --- package.json | 4 ++-- toolkits/payments-and-wallets/package.json | 4 ++++ .../create-ata-explicit-rent-sponsor.ts | 14 +++++++------- typescript-client/actions/create-ata.ts | 4 ++-- typescript-client/actions/create-mint.ts | 10 +++++++--- .../actions/create-spl-interface.ts | 4 ++-- typescript-client/actions/create-spl-mint.ts | 6 +++--- typescript-client/actions/create-t22-mint.ts | 6 +++--- typescript-client/actions/delegate-approve.ts | 17 ++++++----------- typescript-client/actions/delegate-revoke.ts | 10 ++++++---- typescript-client/actions/load-ata.ts | 13 +++++++++---- typescript-client/actions/mint-to.ts | 8 ++++---- typescript-client/actions/unwrap.ts | 11 +++++++---- typescript-client/actions/wrap.ts | 16 +++++++++++----- typescript-client/instructions/create-ata.ts | 8 ++++---- typescript-client/instructions/create-mint.ts | 14 +++++++------- typescript-client/instructions/load-ata.ts | 12 +++++++----- typescript-client/instructions/mint-to.ts | 12 ++++++------ typescript-client/instructions/wrap.ts | 19 +++++++++++-------- typescript-client/package.json | 4 ++-- 20 files changed, 110 insertions(+), 86 deletions(-) diff --git a/package.json b/package.json index 8cac5cec..3b376072 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "toolkit:payments": "npm run -w toolkits/payments-and-wallets" }, "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.6", - "@lightprotocol/stateless.js": "^0.23.0-beta.6", + "@lightprotocol/compressed-token": "^0.23.0-beta.7", + "@lightprotocol/stateless.js": "^0.23.0-beta.7", "@solana/spl-token": "^0.4.13", "@solana/web3.js": "1.98.4", "dotenv": "^16.5.0" diff --git a/toolkits/payments-and-wallets/package.json b/toolkits/payments-and-wallets/package.json index 2c06afc3..c656edee 100644 --- a/toolkits/payments-and-wallets/package.json +++ b/toolkits/payments-and-wallets/package.json @@ -13,5 +13,9 @@ "get-history": "tsx get-history.ts", "wrap": "tsx wrap.ts", "unwrap": "tsx unwrap.ts" + }, + "dependencies": { + "@lightprotocol/compressed-token": "^0.23.0-beta.7", + "@lightprotocol/stateless.js": "^0.23.0-beta.7" } } diff --git a/typescript-client/actions/create-ata-explicit-rent-sponsor.ts b/typescript-client/actions/create-ata-explicit-rent-sponsor.ts index f91d951b..1c89cfab 100644 --- a/typescript-client/actions/create-ata-explicit-rent-sponsor.ts +++ b/typescript-client/actions/create-ata-explicit-rent-sponsor.ts @@ -15,10 +15,10 @@ import { homedir } from "os"; import { readFileSync } from "fs"; const LIGHT_TOKEN_CONFIG = new PublicKey( - "ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg", + "ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg" ); const LIGHT_TOKEN_RENT_SPONSOR = new PublicKey( - "r18WwUxfG8kQ69bQPAB2jV6zGNKy3GosFGctjQoV4ti", + "r18WwUxfG8kQ69bQPAB2jV6zGNKy3GosFGctjQoV4ti" ); const DEFAULT_COMPRESSIBLE_CONFIG = { @@ -37,8 +37,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -48,7 +48,7 @@ const payer = Keypair.fromSecretKey( const owner = Keypair.generate(); const associatedToken = getAssociatedTokenAddressInterface( mint, - owner.publicKey, + owner.publicKey ); const ix = createAssociatedTokenAccountInterfaceInstruction( @@ -62,7 +62,7 @@ const payer = Keypair.fromSecretKey( compressibleConfig: DEFAULT_COMPRESSIBLE_CONFIG, configAccount: LIGHT_TOKEN_CONFIG, rentPayerPda: LIGHT_TOKEN_RENT_SPONSOR, - }, + } ); const { blockhash } = await rpc.getLatestBlockhash(); @@ -70,7 +70,7 @@ const payer = Keypair.fromSecretKey( [ComputeBudgetProgram.setComputeUnitLimit({ units: 50_000 }), ix], payer, blockhash, - [], + [] ); const signature = await sendAndConfirmTx(rpc, tx); diff --git a/typescript-client/actions/create-ata.ts b/typescript-client/actions/create-ata.ts index 53c46ad5..6c61cad9 100644 --- a/typescript-client/actions/create-ata.ts +++ b/typescript-client/actions/create-ata.ts @@ -16,8 +16,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { diff --git a/typescript-client/actions/create-mint.ts b/typescript-client/actions/create-mint.ts index d03db4c3..75171ca5 100644 --- a/typescript-client/actions/create-mint.ts +++ b/typescript-client/actions/create-mint.ts @@ -16,8 +16,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -30,7 +30,11 @@ const payer = Keypair.fromSecretKey( undefined, // keypair undefined, // confirmOptions (default) undefined, // programId (CTOKEN_PROGRAM_ID) - createTokenMetadata("Example Token", "EXT", "https://example.com/metadata.json"), + createTokenMetadata( + "Example Token", + "EXT", + "https://example.com/metadata.json" + ) ); console.log("Mint:", mint.toBase58()); diff --git a/typescript-client/actions/create-spl-interface.ts b/typescript-client/actions/create-spl-interface.ts index b515aa7e..e0ccdb3b 100644 --- a/typescript-client/actions/create-spl-interface.ts +++ b/typescript-client/actions/create-spl-interface.ts @@ -13,8 +13,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { diff --git a/typescript-client/actions/create-spl-mint.ts b/typescript-client/actions/create-spl-mint.ts index dcfcbfc1..1bd261fc 100644 --- a/typescript-client/actions/create-spl-mint.ts +++ b/typescript-client/actions/create-spl-mint.ts @@ -14,8 +14,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -30,7 +30,7 @@ const payer = Keypair.fromSecretKey( 9, mintKeypair, undefined, - TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID ); console.log("Mint:", mint.toBase58()); diff --git a/typescript-client/actions/create-t22-mint.ts b/typescript-client/actions/create-t22-mint.ts index 737d48df..2bd7d11d 100644 --- a/typescript-client/actions/create-t22-mint.ts +++ b/typescript-client/actions/create-t22-mint.ts @@ -14,8 +14,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -30,7 +30,7 @@ const payer = Keypair.fromSecretKey( 9, mintKeypair, undefined, - TOKEN_2022_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID ); console.log("Mint:", mint.toBase58()); diff --git a/typescript-client/actions/delegate-approve.ts b/typescript-client/actions/delegate-approve.ts index 929e77e0..bb0c59d6 100644 --- a/typescript-client/actions/delegate-approve.ts +++ b/typescript-client/actions/delegate-approve.ts @@ -17,23 +17,18 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await mintToCompressed(rpc, payer, mint, payer, [{ recipient: payer.publicKey, amount: 1000n }]); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); const delegate = Keypair.generate(); - const tx = await approve( - rpc, - payer, - mint, - 500, - payer, - delegate.publicKey, - ); + const tx = await approve(rpc, payer, mint, 500, payer, delegate.publicKey); console.log("Tx:", tx); })(); diff --git a/typescript-client/actions/delegate-revoke.ts b/typescript-client/actions/delegate-revoke.ts index 102b3a22..7eb3d068 100644 --- a/typescript-client/actions/delegate-revoke.ts +++ b/typescript-client/actions/delegate-revoke.ts @@ -18,20 +18,22 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await mintToCompressed(rpc, payer, mint, payer, [{ recipient: payer.publicKey, amount: 1000n }]); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); const delegate = Keypair.generate(); await approve(rpc, payer, mint, 500, payer, delegate.publicKey); const delegatedAccounts = await rpc.getCompressedTokenAccountsByDelegate( delegate.publicKey, - { mint }, + { mint } ); const tx = await revoke(rpc, payer, delegatedAccounts.items, payer); diff --git a/typescript-client/actions/load-ata.ts b/typescript-client/actions/load-ata.ts index 80a50bdb..ab68756b 100644 --- a/typescript-client/actions/load-ata.ts +++ b/typescript-client/actions/load-ata.ts @@ -18,8 +18,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -27,10 +27,15 @@ const payer = Keypair.fromSecretKey( // as compressed tokens (cold storage) // Setup: Get compressed tokens in light-token associated token account const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await mintToCompressed(rpc, payer, mint, payer, [{ recipient: payer.publicKey, amount: 1000n }]); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); // Load compressed tokens to light associated token account (hot balance) - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); const tx = await loadAta(rpc, lightTokenAta, payer, mint, payer); console.log("Tx:", tx); diff --git a/typescript-client/actions/mint-to.ts b/typescript-client/actions/mint-to.ts index 09a67175..8fcfff94 100644 --- a/typescript-client/actions/mint-to.ts +++ b/typescript-client/actions/mint-to.ts @@ -18,8 +18,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -30,7 +30,7 @@ const payer = Keypair.fromSecretKey( const destination = getAssociatedTokenAddressInterface( mint, - recipient.publicKey, + recipient.publicKey ); const tx = await mintToInterface( rpc, @@ -38,7 +38,7 @@ const payer = Keypair.fromSecretKey( mint, destination, payer, - 1_000_000_000, + 1_000_000_000 ); console.log("Tx:", tx); diff --git a/typescript-client/actions/unwrap.ts b/typescript-client/actions/unwrap.ts index 83ac7f46..2900f471 100644 --- a/typescript-client/actions/unwrap.ts +++ b/typescript-client/actions/unwrap.ts @@ -23,15 +23,18 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // Setup: Create and mint tokens to light-token associated token account const { mint } = await createMintInterface(rpc, payer, payer, null, 9); await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const destination = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await mintToInterface(rpc, payer, mint, destination, payer, 1000); // Unwrap light-token to SPL associated token account @@ -41,7 +44,7 @@ const payer = Keypair.fromSecretKey( mint, payer.publicKey, undefined, - TOKEN_2022_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID ); const tx = await unwrap(rpc, payer, splAta, payer, mint, 500); diff --git a/typescript-client/actions/wrap.ts b/typescript-client/actions/wrap.ts index 59aa690d..83cf4873 100644 --- a/typescript-client/actions/wrap.ts +++ b/typescript-client/actions/wrap.ts @@ -25,15 +25,18 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // Setup: Get SPL tokens (needed to wrap) const { mint } = await createMintInterface(rpc, payer, payer, null, 9); await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const destination = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await mintToInterface(rpc, payer, mint, destination, payer, 1000); const splAta = await createAssociatedTokenAccount( rpc, @@ -41,12 +44,15 @@ const payer = Keypair.fromSecretKey( mint, payer.publicKey, undefined, - TOKEN_2022_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID ); await decompressInterface(rpc, payer, payer, mint, 1000); // Wrap SPL tokens to light-token associated token account - const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const lightTokenAta = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await createAtaInterfaceIdempotent(rpc, payer, mint, payer.publicKey); const tx = await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, 500); diff --git a/typescript-client/instructions/create-ata.ts b/typescript-client/instructions/create-ata.ts index ff2009ce..55966d8e 100644 --- a/typescript-client/instructions/create-ata.ts +++ b/typescript-client/instructions/create-ata.ts @@ -21,8 +21,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -31,7 +31,7 @@ const payer = Keypair.fromSecretKey( const owner = Keypair.generate(); const associatedToken = getAssociatedTokenAddressInterface( mint, - owner.publicKey, + owner.publicKey ); const ix = createAssociatedTokenAccountInterfaceInstruction( @@ -39,7 +39,7 @@ const payer = Keypair.fromSecretKey( associatedToken, owner.publicKey, mint, - CTOKEN_PROGRAM_ID, + CTOKEN_PROGRAM_ID ); const tx = new Transaction().add(ix); diff --git a/typescript-client/instructions/create-mint.ts b/typescript-client/instructions/create-mint.ts index 48dec81c..f1250aff 100644 --- a/typescript-client/instructions/create-mint.ts +++ b/typescript-client/instructions/create-mint.ts @@ -24,7 +24,7 @@ const COMPRESSED_MINT_SEED = Buffer.from("compressed_mint"); function findMintAddress(mintSigner: PublicKey): [PublicKey, number] { return PublicKey.findProgramAddressSync( [COMPRESSED_MINT_SEED, mintSigner.toBuffer()], - CTOKEN_PROGRAM_ID, + CTOKEN_PROGRAM_ID ); } @@ -36,8 +36,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -48,7 +48,7 @@ const payer = Keypair.fromSecretKey( const validityProof = await rpc.getValidityProofV2( [], - [{ address: mintPda.toBytes(), treeInfo: addressTreeInfo }], + [{ address: mintPda.toBytes(), treeInfo: addressTreeInfo }] ); const ix = createMintInstruction( @@ -63,13 +63,13 @@ const payer = Keypair.fromSecretKey( createTokenMetadata( "Example Token", "EXT", - "https://example.com/metadata.json", - ), + "https://example.com/metadata.json" + ) ); const tx = new Transaction().add( ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), - ix, + ix ); const signature = await sendAndConfirmTransaction(rpc, tx, [ payer, diff --git a/typescript-client/instructions/load-ata.ts b/typescript-client/instructions/load-ata.ts index b3be00d2..6e6c2529 100644 --- a/typescript-client/instructions/load-ata.ts +++ b/typescript-client/instructions/load-ata.ts @@ -22,8 +22,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -31,11 +31,13 @@ const payer = Keypair.fromSecretKey( // as compressed tokens (cold storage) // Setup: Get compressed tokens in light-token associated token account const { mint } = await createMintInterface(rpc, payer, payer, null, 9); - await mintToCompressed(rpc, payer, mint, payer, [{ recipient: payer.publicKey, amount: 1000n }]); + await mintToCompressed(rpc, payer, mint, payer, [ + { recipient: payer.publicKey, amount: 1000n }, + ]); const lightTokenAta = getAssociatedTokenAddressInterface( mint, - payer.publicKey, + payer.publicKey ); // Load compressed tokens to light associated token account (hot balance) @@ -44,7 +46,7 @@ const payer = Keypair.fromSecretKey( lightTokenAta, payer.publicKey, mint, - payer.publicKey, + payer.publicKey ); if (ixs.length === 0) return console.log("Nothing to load"); diff --git a/typescript-client/instructions/mint-to.ts b/typescript-client/instructions/mint-to.ts index a8672748..c1d6f958 100644 --- a/typescript-client/instructions/mint-to.ts +++ b/typescript-client/instructions/mint-to.ts @@ -24,8 +24,8 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { @@ -35,7 +35,7 @@ const payer = Keypair.fromSecretKey( await createAtaInterface(rpc, payer, mint, recipient.publicKey); const destination = getAssociatedTokenAddressInterface( mint, - recipient.publicKey, + recipient.publicKey ); const mintInterface = await getMintInterface(rpc, mint); @@ -52,7 +52,7 @@ const payer = Keypair.fromSecretKey( }, ], [], - DerivationMode.compressible, + DerivationMode.compressible ); } @@ -62,12 +62,12 @@ const payer = Keypair.fromSecretKey( payer.publicKey, payer.publicKey, 1_000_000_000, - validityProof, + validityProof ); const tx = new Transaction().add( ComputeBudgetProgram.setComputeUnitLimit({ units: 500_000 }), - ix, + ix ); const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); diff --git a/typescript-client/instructions/wrap.ts b/typescript-client/instructions/wrap.ts index 4ba4763b..49eb70d7 100644 --- a/typescript-client/instructions/wrap.ts +++ b/typescript-client/instructions/wrap.ts @@ -31,15 +31,18 @@ const rpc = createRpc(); const payer = Keypair.fromSecretKey( new Uint8Array( - JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")), - ), + JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) + ) ); (async function () { // Setup: Get SPL tokens (needed to wrap) const { mint } = await createMintInterface(rpc, payer, payer, null, 9); await createAtaInterface(rpc, payer, mint, payer.publicKey); - const destination = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const destination = getAssociatedTokenAddressInterface( + mint, + payer.publicKey + ); await mintToInterface(rpc, payer, mint, destination, payer, 1000); const splAta = await createAssociatedTokenAccount( rpc, @@ -47,20 +50,20 @@ const payer = Keypair.fromSecretKey( mint, payer.publicKey, undefined, - TOKEN_2022_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID ); await decompressInterface(rpc, payer, payer, mint, 1000); // Create wrap instruction const lightTokenAta = getAssociatedTokenAddressInterface( mint, - payer.publicKey, + payer.publicKey ); await createAtaInterfaceIdempotent(rpc, payer, mint, payer.publicKey); const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint); const splInterfaceInfo = splInterfaceInfos.find( - (info) => info.isInitialized, + (info) => info.isInitialized ); if (!splInterfaceInfo) throw new Error("No SPL interface found"); @@ -73,12 +76,12 @@ const payer = Keypair.fromSecretKey( 500, splInterfaceInfo, 9, // decimals - must match the mint decimals - payer.publicKey, + payer.publicKey ); const tx = new Transaction().add( ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }), - ix, + ix ); const signature = await sendAndConfirmTransaction(rpc, tx, [payer]); diff --git a/typescript-client/package.json b/typescript-client/package.json index 1e8b4e22..18284041 100644 --- a/typescript-client/package.json +++ b/typescript-client/package.json @@ -4,8 +4,8 @@ "type": "module", "description": "Working examples for light-token operations on Solana devnet", "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.6", - "@lightprotocol/stateless.js": "^0.23.0-beta.6", + "@lightprotocol/compressed-token": "^0.23.0-beta.7", + "@lightprotocol/stateless.js": "^0.23.0-beta.7", "@solana/web3.js": "^1.98.0", "dotenv": "^16.0.0" }, From d0940f767397d40d9a4f42e5dbd64b3134bdbda7 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Fri, 13 Feb 2026 19:40:54 +0000 Subject: [PATCH 8/8] bump v --- package.json | 4 ++-- toolkits/payments-and-wallets/package.json | 4 ++-- typescript-client/package.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3b376072..0521691b 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "toolkit:payments": "npm run -w toolkits/payments-and-wallets" }, "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.7", - "@lightprotocol/stateless.js": "^0.23.0-beta.7", + "@lightprotocol/compressed-token": "^0.23.0-beta.8", + "@lightprotocol/stateless.js": "^0.23.0-beta.8", "@solana/spl-token": "^0.4.13", "@solana/web3.js": "1.98.4", "dotenv": "^16.5.0" diff --git a/toolkits/payments-and-wallets/package.json b/toolkits/payments-and-wallets/package.json index c656edee..17bf9602 100644 --- a/toolkits/payments-and-wallets/package.json +++ b/toolkits/payments-and-wallets/package.json @@ -15,7 +15,7 @@ "unwrap": "tsx unwrap.ts" }, "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.7", - "@lightprotocol/stateless.js": "^0.23.0-beta.7" + "@lightprotocol/compressed-token": "^0.23.0-beta.8", + "@lightprotocol/stateless.js": "^0.23.0-beta.8" } } diff --git a/typescript-client/package.json b/typescript-client/package.json index 18284041..ef070b42 100644 --- a/typescript-client/package.json +++ b/typescript-client/package.json @@ -4,8 +4,8 @@ "type": "module", "description": "Working examples for light-token operations on Solana devnet", "dependencies": { - "@lightprotocol/compressed-token": "^0.23.0-beta.7", - "@lightprotocol/stateless.js": "^0.23.0-beta.7", + "@lightprotocol/compressed-token": "^0.23.0-beta.8", + "@lightprotocol/stateless.js": "^0.23.0-beta.8", "@solana/web3.js": "^1.98.0", "dotenv": "^16.0.0" },