Skip to main content
  1. The light-token API matches the SPL-token API almost entirely, and extends their functionality to include the light token program in addition to the SPL-token and Token-2022 programs.
  2. Your users receive the same stablecoin, just stored more efficiently.
Creation CostSPLlight-token
Token Account~2,000,000 lamports~11,000 lamports

What you will implement

SPLLight
Get/Create ATAgetOrCreateAssociatedTokenAccount()getOrCreateAtaInterface()
Derive ATAgetAssociatedTokenAddress()getAssociatedTokenAddressInterface()
TransfertransferChecked()transferInterface()
Get BalancegetAccount()getAtaInterface()
Tx HistorygetSignaturesForAddress()rpc.getSignaturesForOwnerInterface()
Entry from SPLN/Awrap()
Exit to SPLN/Aunwrap()
Find full code examples here.

Setup

import { createRpc } from "@lightprotocol/stateless.js";

import {
  getOrCreateAtaInterface,
  getAtaInterface,
  getAssociatedTokenAddressInterface,
  transferInterface,
  wrap,
  unwrap,
} from "@lightprotocol/compressed-token/unified";

const rpc = createRpc(RPC_ENDPOINT);

Receive Payments

import { getOrCreateAtaInterface } from "@lightprotocol/compressed-token/unified";

const ata = await getOrCreateAtaInterface(rpc, payer, mint, recipient);
// Share ata.parsed.address with sender

console.log(ata.parsed.amount);
import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token";

const ata = await getOrCreateAssociatedTokenAccount(
  connection,
  payer,
  mint,
  recipient
);
// Share ata.address with sender

console.log(ata.amount);

Send Payments

import {
  getAssociatedTokenAddressInterface,
  transferInterface,
} from "@lightprotocol/compressed-token/unified";

const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressInterface(mint, recipient);

await transferInterface(
  rpc,
  payer,
  sourceAta,
  mint,
  destinationAta,
  owner,
  amount
);
To ensure your recipient’s ATA exists before transferring:
import {
  getOrCreateAtaInterface,
  transferInterface,
  getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";

// Ensure recipient ATA exists (creates if needed)
await getOrCreateAtaInterface(rpc, payer, mint, recipient);

// Then transfer
const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressInterface(mint, recipient);
await transferInterface(
  rpc,
  payer,
  sourceAta,
  mint,
  destinationAta,
  owner,
  amount
);
import {
  getAssociatedTokenAddressSync,
  getOrCreateAssociatedTokenAccount,
  transfer,
} from "@solana/spl-token";

// Ensure recipient ATA exists
await getOrCreateAssociatedTokenAccount(connection, payer, mint, recipient);

// Then transfer
const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressSync(mint, recipient);
await transfer(
  connection,
  payer,
  sourceAta,
  destinationAta,
  owner,
  amount,
  decimals
);

Show Balance

import {
  getAssociatedTokenAddressInterface,
  getAtaInterface,
} from "@lightprotocol/compressed-token/unified";

const ata = getAssociatedTokenAddressInterface(mint, owner);
const account = await getAtaInterface(rpc, ata, owner, mint);

console.log(account.parsed.amount);
import { getAccount } from "@solana/spl-token";

const account = await getAccount(connection, ata);

console.log(account.amount);

Transaction History

const result = await rpc.getSignaturesForOwnerInterface(owner);

console.log(result.signatures); // All signatures
Use getSignaturesForAddressInterface(address) if you want address-specific rather than owner-wide history.
const signatures = await connection.getSignaturesForAddress(ata);

Wrap from SPL

When users deposit from a CEX or legacy integration:
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import {
  wrap,
  getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";

// SPL ATA with tokens to wrap
const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
// c-token ATA destination
const ctokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);

await wrap(rpc, payer, splAta, ctokenAta, owner, mint, amount);

Unwrap to SPL

When users need SPL tokens (CEX withdrawal, legacy integration):
import { getAssociatedTokenAddressSync } from "@solana/spl-token";

// SPL ATA must exist
const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);

await unwrap(rpc, payer, splAta, owner, mint, amount);