From a4a863380a0a30fa247046296d51505364fab24f Mon Sep 17 00:00:00 2001 From: tilo-14 Date: Sun, 1 Feb 2026 19:23:33 +0000 Subject: [PATCH 1/4] add indexing tokens warm-up examples Action and instruction examples showing detect cold + decompress + trade pattern for indexers. --- toolkits/indexing-tokens/package.json | 9 +++ toolkits/indexing-tokens/warm-up-action.ts | 56 ++++++++++++++ .../indexing-tokens/warm-up-instruction.ts | 76 +++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 toolkits/indexing-tokens/package.json create mode 100644 toolkits/indexing-tokens/warm-up-action.ts create mode 100644 toolkits/indexing-tokens/warm-up-instruction.ts diff --git a/toolkits/indexing-tokens/package.json b/toolkits/indexing-tokens/package.json new file mode 100644 index 0000000..ce2dee1 --- /dev/null +++ b/toolkits/indexing-tokens/package.json @@ -0,0 +1,9 @@ +{ + "name": "light-token-toolkit-indexing", + "version": "1.0.0", + "type": "module", + "scripts": { + "warm-up-action": "tsx warm-up-action.ts", + "warm-up-instruction": "tsx warm-up-instruction.ts" + } +} \ No newline at end of file diff --git a/toolkits/indexing-tokens/warm-up-action.ts b/toolkits/indexing-tokens/warm-up-action.ts new file mode 100644 index 0000000..de46e1d --- /dev/null +++ b/toolkits/indexing-tokens/warm-up-action.ts @@ -0,0 +1,56 @@ +import "dotenv/config"; +import { Keypair } from "@solana/web3.js"; +import { createRpc } from "@lightprotocol/stateless.js"; +import { + createMintInterface, + createAtaInterface, + mintToCompressed, + loadAta, + transferInterface, + getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-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 () { + // Inactive Light Tokens are cryptographically preserved on the Solana ledger + // 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 }]); + + const recipient = Keypair.generate(); + await createAtaInterface(rpc, payer, mint, recipient.publicKey); + + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); + + // Warm up: load compressed tokens to associated token account + // Returns null if already hot + await loadAta(rpc, senderAta, payer, mint, payer); + + // Transfer tokens from hot balance + const tx = await transferInterface( + rpc, + payer, + senderAta, + mint, + recipientAta, + payer, + 500n, + ); + + console.log("Tx:", tx); +})(); \ No newline at end of file diff --git a/toolkits/indexing-tokens/warm-up-instruction.ts b/toolkits/indexing-tokens/warm-up-instruction.ts new file mode 100644 index 0000000..0ebae28 --- /dev/null +++ b/toolkits/indexing-tokens/warm-up-instruction.ts @@ -0,0 +1,76 @@ +import "dotenv/config"; +import { Keypair } from "@solana/web3.js"; +import { + createRpc, + buildAndSignTx, + sendAndConfirmTx, +} from "@lightprotocol/stateless.js"; +import { + createMintInterface, + createAtaInterface, + mintToCompressed, + createLoadAtaInstructions, + createTransferInterfaceInstruction, + getAssociatedTokenAddressInterface, +} from "@lightprotocol/compressed-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 () { + // Inactive Light Tokens are cryptographically preserved on the Solana ledger + // 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 }]); + + const recipient = Keypair.generate(); + await createAtaInterface(rpc, payer, mint, recipient.publicKey); + + const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); + const recipientAta = getAssociatedTokenAddressInterface( + mint, + recipient.publicKey, + ); + + // Warm up: load compressed tokens (cold) to sender's hot balance + // Returns [] if already hot — safe to call unconditionally + const loadIxs = await createLoadAtaInstructions( + rpc, + senderAta, + payer.publicKey, + mint, + payer.publicKey, + ); + + if (loadIxs.length > 0) { + const blockhash = await rpc.getLatestBlockhash(); + const loadTx = buildAndSignTx(loadIxs, payer, blockhash.blockhash); + await sendAndConfirmTx(rpc, loadTx); + } + + // Trade: transfer from hot balance + const transferIx = createTransferInterfaceInstruction( + senderAta, + recipientAta, + payer.publicKey, + 500n, + ); + + const blockhash = await rpc.getLatestBlockhash(); + const tradeTx = buildAndSignTx([transferIx], payer, blockhash.blockhash); + const signature = await sendAndConfirmTx(rpc, tradeTx); + + console.log("Tx:", signature); +})(); \ No newline at end of file From 11e61affa5cd34eda7f72131d433f6347d089455 Mon Sep 17 00:00:00 2001 From: tilo-14 Date: Mon, 2 Feb 2026 12:52:51 +0000 Subject: [PATCH 2/4] Refactor comments for clarity in warm-up instruction --- toolkits/indexing-tokens/warm-up-instruction.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toolkits/indexing-tokens/warm-up-instruction.ts b/toolkits/indexing-tokens/warm-up-instruction.ts index 0ebae28..27f715b 100644 --- a/toolkits/indexing-tokens/warm-up-instruction.ts +++ b/toolkits/indexing-tokens/warm-up-instruction.ts @@ -44,8 +44,8 @@ const payer = Keypair.fromSecretKey( recipient.publicKey, ); - // Warm up: load compressed tokens (cold) to sender's hot balance - // Returns [] if already hot — safe to call unconditionally + // Warm up: load compressed tokens to sender's light-token associated token account + // (hot balance). Returns [] if already hot const loadIxs = await createLoadAtaInstructions( rpc, senderAta, @@ -60,7 +60,7 @@ const payer = Keypair.fromSecretKey( await sendAndConfirmTx(rpc, loadTx); } - // Trade: transfer from hot balance + // Transfer from hot balance const transferIx = createTransferInterfaceInstruction( senderAta, recipientAta, @@ -73,4 +73,4 @@ const payer = Keypair.fromSecretKey( const signature = await sendAndConfirmTx(rpc, tradeTx); console.log("Tx:", signature); -})(); \ No newline at end of file +})(); From 4be673fc5e5f086e06ab4eb430fae480615cc659 Mon Sep 17 00:00:00 2001 From: tilo-14 Date: Mon, 2 Feb 2026 12:54:27 +0000 Subject: [PATCH 3/4] Clarify comments for token loading and transfer --- toolkits/indexing-tokens/warm-up-action.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolkits/indexing-tokens/warm-up-action.ts b/toolkits/indexing-tokens/warm-up-action.ts index de46e1d..1ffef4e 100644 --- a/toolkits/indexing-tokens/warm-up-action.ts +++ b/toolkits/indexing-tokens/warm-up-action.ts @@ -37,11 +37,11 @@ const payer = Keypair.fromSecretKey( const senderAta = getAssociatedTokenAddressInterface(mint, payer.publicKey); const recipientAta = getAssociatedTokenAddressInterface(mint, recipient.publicKey); - // Warm up: load compressed tokens to associated token account + // Warm up: load compressed tokens to light-token associated token account (hot balance) // Returns null if already hot await loadAta(rpc, senderAta, payer, mint, payer); - // Transfer tokens from hot balance + // Transfer tokens const tx = await transferInterface( rpc, payer, @@ -53,4 +53,4 @@ const payer = Keypair.fromSecretKey( ); console.log("Tx:", tx); -})(); \ No newline at end of file +})(); From ac4e429fa699f0cc2c3305476e0955a8be59a1bc Mon Sep 17 00:00:00 2001 From: tilo-14 Date: Mon, 2 Feb 2026 12:54:59 +0000 Subject: [PATCH 4/4] Refactor comments for clarity in warm-up instruction --- toolkits/indexing-tokens/warm-up-instruction.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolkits/indexing-tokens/warm-up-instruction.ts b/toolkits/indexing-tokens/warm-up-instruction.ts index 27f715b..da216ff 100644 --- a/toolkits/indexing-tokens/warm-up-instruction.ts +++ b/toolkits/indexing-tokens/warm-up-instruction.ts @@ -44,8 +44,8 @@ const payer = Keypair.fromSecretKey( recipient.publicKey, ); - // Warm up: load compressed tokens to sender's light-token associated token account - // (hot balance). Returns [] if already hot + // Warm up: load compressed tokens to light-token associated token account (hot balance) + // Returns null if already hot const loadIxs = await createLoadAtaInstructions( rpc, senderAta, @@ -60,7 +60,7 @@ const payer = Keypair.fromSecretKey( await sendAndConfirmTx(rpc, loadTx); } - // Transfer from hot balance + // Transfer tokens const transferIx = createTransferInterfaceInstruction( senderAta, recipientAta,