- 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.
- Your users receive the same stablecoin, just stored more efficiently.
| Creation Cost | SPL | light-token |
|---|---|---|
| Token Account | ~2,000,000 lamports | ~11,000 lamports |
What you will implement
| SPL | Light | |
|---|---|---|
| Get/Create ATA | getOrCreateAssociatedTokenAccount() | getOrCreateAtaInterface() |
| Derive ATA | getAssociatedTokenAddress() | getAssociatedTokenAddressInterface() |
| Transfer | transferChecked() | transferInterface() |
| Get Balance | getAccount() | getAtaInterface() |
| Tx History | getSignaturesForAddress() | rpc.getSignaturesForOwnerInterface() |
| Entry from SPL | N/A | wrap() |
| Exit to SPL | N/A | unwrap() |
Find full code examples
here.
Setup
Report incorrect code
Copy
Ask AI
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
- Action
- Instruction
Report incorrect code
Copy
Ask AI
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);
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token";
const ata = await getOrCreateAssociatedTokenAccount(
connection,
payer,
mint,
recipient
);
// Share ata.address with sender
console.log(ata.amount);
Report incorrect code
Copy
Ask AI
import { Transaction } from "@solana/web3.js";
import {
createAssociatedTokenAccountInterfaceIdempotentInstruction,
createLoadAtaInstructions,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";
import { CTOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js";
const ata = getAssociatedTokenAddressInterface(mint, recipient);
const tx = new Transaction().add(
createAssociatedTokenAccountInterfaceIdempotentInstruction(
payer.publicKey,
ata,
recipient,
mint,
CTOKEN_PROGRAM_ID
),
...(await createLoadAtaInstructions(
rpc,
ata,
recipient,
mint,
payer.publicKey
))
);
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
import {
createAssociatedTokenAccountInstruction,
getAssociatedTokenAddressSync,
} from "@solana/spl-token";
const ata = getAssociatedTokenAddressSync(mint, recipient);
const tx = new Transaction().add(
createAssociatedTokenAccountInstruction(payer.publicKey, ata, recipient, mint)
);
Send Payments
- Action
- Instruction
Report incorrect code
Copy
Ask AI
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
);
Report incorrect code
Copy
Ask AI
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
);
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
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
);
Report incorrect code
Copy
Ask AI
import { Transaction } from "@solana/web3.js";
import {
createLoadAtaInstructions,
createTransferInterfaceInstruction,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";
const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressInterface(mint, recipient);
const tx = new Transaction().add(
...(await createLoadAtaInstructions(
rpc,
sourceAta,
owner.publicKey,
mint,
payer.publicKey
)),
createTransferInterfaceInstruction(
sourceAta,
destinationAta,
owner.publicKey,
amount
)
);
Report incorrect code
Copy
Ask AI
import { Transaction } from "@solana/web3.js";
import {
createAssociatedTokenAccountInterfaceIdempotentInstruction,
createLoadAtaInstructions,
createTransferInterfaceInstruction,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";
import { CTOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js";
const sourceAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressInterface(mint, recipient);
const tx = new Transaction().add(
createAssociatedTokenAccountInterfaceIdempotentInstruction(
payer.publicKey,
destinationAta,
recipient,
mint,
CTOKEN_PROGRAM_ID
),
...(await createLoadAtaInstructions(
rpc,
sourceAta,
owner.publicKey,
mint,
payer.publicKey
)),
createTransferInterfaceInstruction(
sourceAta,
destinationAta,
owner.publicKey,
amount
)
);
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
import {
getAssociatedTokenAddressSync,
createTransferInstruction,
} from "@solana/spl-token";
const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressSync(mint, recipient);
const tx = new Transaction().add(
createTransferInstruction(sourceAta, destinationAta, owner.publicKey, amount)
);
Report incorrect code
Copy
Ask AI
import {
getAssociatedTokenAddressSync,
createAssociatedTokenAccountIdempotentInstruction,
createTransferInstruction,
} from "@solana/spl-token";
const sourceAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
const destinationAta = getAssociatedTokenAddressSync(mint, recipient);
const tx = new Transaction().add(
createAssociatedTokenAccountIdempotentInstruction(
payer.publicKey,
destinationAta,
recipient,
mint
),
createTransferInstruction(sourceAta, destinationAta, owner.publicKey, amount)
);
Show Balance
Report incorrect code
Copy
Ask AI
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);
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
import { getAccount } from "@solana/spl-token";
const account = await getAccount(connection, ata);
console.log(account.amount);
Transaction History
Report incorrect code
Copy
Ask AI
const result = await rpc.getSignaturesForOwnerInterface(owner);
console.log(result.signatures); // All signatures
getSignaturesForAddressInterface(address) if you want address-specific rather than owner-wide history.
Compare to SPL
Compare to SPL
Report incorrect code
Copy
Ask AI
const signatures = await connection.getSignaturesForAddress(ata);
Wrap from SPL
When users deposit from a CEX or legacy integration:- Action
- Instruction
Report incorrect code
Copy
Ask AI
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);
Report incorrect code
Copy
Ask AI
import { Transaction } from "@solana/web3.js";
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import {
createWrapInstruction,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";
import { getSplInterfaceInfos } from "@lightprotocol/compressed-token";
const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
const ctokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);
const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint);
const splInterfaceInfo = splInterfaceInfos.find((i) => i.isInitialized);
const tx = new Transaction().add(
createWrapInstruction(
splAta,
ctokenAta,
owner.publicKey,
mint,
amount,
splInterfaceInfo
)
);
Unwrap to SPL
When users need SPL tokens (CEX withdrawal, legacy integration):- Action
- Instruction
Report incorrect code
Copy
Ask AI
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
// SPL ATA must exist
const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
await unwrap(rpc, payer, splAta, owner, mint, amount);
Report incorrect code
Copy
Ask AI
import { Transaction } from "@solana/web3.js";
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import {
createLoadAtaInstructions,
createUnwrapInstruction,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token/unified";
import { getSplInterfaceInfos } from "@lightprotocol/compressed-token";
const ctokenAta = 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,
ctokenAta,
owner.publicKey,
mint,
payer.publicKey
)),
createUnwrapInstruction(
ctokenAta,
splAta,
owner.publicKey,
mint,
amount,
splInterfaceInfo
)
);