Skip to main content
  1. Share the associated token account address with the sender.
  2. We recommend to prepend a load instruction before. Load creates the associated token account if needed and loads any cold balance into it.
About loading: Light Token accounts reduce account rent ~200x by auto-compressing inactive accounts. Before any action, the SDK detects cold balances and adds instructions to load them. This almost always fits in a single atomic transaction with your regular transfer. APIs return TransactionInstruction[][] so the same loop handles the rare multi-transaction case automatically.
Use the payments agent skill to add light-token payment support to your project:
Add the marketplace and install:
/plugin marketplace add Lightprotocol/skills
/plugin install solana-rent-free-dev
For orchestration, install the general skill:
npx skills add https://zkcompression.com

Setup

npm install @lightprotocol/compressed-token@beta \
            @lightprotocol/stateless.js@beta
import { createRpc } from "@lightprotocol/stateless.js";

const rpc = createRpc(RPC_ENDPOINT);

Derive the associated token account address

Share this address with the sender so they know where to send tokens.
import { getAssociatedTokenAddressInterface } from "@lightprotocol/compressed-token/unified";

const ata = getAssociatedTokenAddressInterface(mint, recipient);

Load the associated token account

Find a full code example here.
import { Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
import {
  createLoadAtaInstructions,
  getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";

const ata = getAssociatedTokenAddressInterface(mint, recipient);

// Returns TransactionInstruction[][].
// Each inner array is one transaction.
// Almost always returns just one.
const instructions = await createLoadAtaInstructions(
  rpc,
  ata,
  recipient,
  mint,
  payer.publicKey
);

for (const ixs of instructions) {
  const tx = new Transaction().add(...ixs);
  await sendAndConfirmTransaction(rpc, tx, [payer]);
}
import {
  createAssociatedTokenAccountInstruction,
  getAssociatedTokenAddressSync,
  getOrCreateAssociatedTokenAccount,
} from "@solana/spl-token";

const ata = getAssociatedTokenAddressSync(mint, recipient);

// Instruction:
const tx = new Transaction().add(
  createAssociatedTokenAccountInstruction(payer.publicKey, ata, recipient, mint)
);

// Action:
const ata = await getOrCreateAssociatedTokenAccount(
  connection, payer, mint, recipient
);

Verify payments

Check balances and transaction history.

Gasless transactions

Abstract SOL fees so users never hold SOL.

Basic payment

Send a single token transfer.

Didn’t find what you were looking for?

Reach out! Telegram | email | Discord