Documentation Index Fetch the complete documentation index at: https://luminouslabs-cc5545c6-indexing-tokens.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
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() Wrap from SPL N/A wrap() Unwrap to SPL N/A unwrap()
Find full code examples
here .
Setup
npm install @lightprotocol/compressed-token@beta \
@lightprotocol/stateless.js@beta
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
Find a full code example here .
Instruction
Action helper
import { Transaction } from "@solana/web3.js" ;
import {
createAssociatedTokenAccountInterfaceIdempotentInstruction ,
createLoadAtaInstructions ,
getAssociatedTokenAddressInterface ,
} from "@lightprotocol/compressed-token/unified" ;
import { LIGHT_TOKEN_PROGRAM_ID } from "@lightprotocol/stateless.js" ;
const ata = getAssociatedTokenAddressInterface ( mint , recipient );
const tx = new Transaction (). add (
createAssociatedTokenAccountInterfaceIdempotentInstruction (
payer . publicKey ,
ata ,
recipient ,
mint ,
LIGHT_TOKEN_PROGRAM_ID
),
... ( await createLoadAtaInstructions (
rpc ,
ata ,
recipient ,
mint ,
payer . publicKey
))
);
import {
createAssociatedTokenAccountInstruction ,
getAssociatedTokenAddressSync ,
} from "@solana/spl-token" ;
const ata = getAssociatedTokenAddressSync ( mint , recipient );
const tx = new Transaction (). add (
createAssociatedTokenAccountInstruction ( payer . publicKey , ata , recipient , mint )
);
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
Find a full code example here .
Instruction
Action helper
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
)
);
To ensure your recipient’s ATA exists, prepend an idempotent creation instruction: import { Transaction } from "@solana/web3.js" ;
import {
createAssociatedTokenAccountInterfaceIdempotentInstruction ,
createLoadAtaInstructions ,
createTransferInterfaceInstruction ,
getAssociatedTokenAddressInterface ,
} from "@lightprotocol/compressed-token/unified" ;
import { LIGHT_TOKEN_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 ,
LIGHT_TOKEN_PROGRAM_ID
),
... ( await createLoadAtaInstructions (
rpc ,
sourceAta ,
owner . publicKey ,
mint ,
payer . publicKey
)),
createTransferInterfaceInstruction (
sourceAta ,
destinationAta ,
owner . publicKey ,
amount
)
);
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 )
);
With idempotent ATA creation: 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 )
);
import {
getAssociatedTokenAddressInterface ,
transferInterface ,
} from "@lightprotocol/compressed-token/unified" ;
const sourceAta = getAssociatedTokenAddressInterface ( mint , owner . publicKey );
const destinationAta = getAssociatedTokenAddressInterface ( mint , recipient );
await transferInterface (
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
Find a full code example here .
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
Find a full code example here .
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
Wrap tokens from SPL/Token-2022 accounts to light-token ATA.
Find a full code example here .
Instruction
Action helper
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 tokenAta = getAssociatedTokenAddressInterface ( mint , owner . publicKey );
const splInterfaceInfos = await getSplInterfaceInfos ( rpc , mint );
const splInterfaceInfo = splInterfaceInfos . find (( i ) => i . isInitialized );
const tx = new Transaction (). add (
createWrapInstruction (
splAta ,
tokenAta ,
owner . publicKey ,
mint ,
amount ,
splInterfaceInfo ,
decimals
)
);
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 );
// light-token ATA destination
const tokenAta = getAssociatedTokenAddressInterface ( mint , owner . publicKey );
await wrap ( rpc , payer , splAta , tokenAta , owner , mint , amount );
Unwrap to SPL
You can compose with applications that do not yet support the light-token
standard by unwrapping your tokens.
Unwrap moves the token balance from a light-token account to a SPL-token account.
Find a full code example here .
Instruction
Action helper
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 tokenAta = 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 ,
tokenAta ,
owner . publicKey ,
mint ,
payer . publicKey
)),
createUnwrapInstruction (
tokenAta ,
splAta ,
owner . publicKey ,
mint ,
amount ,
splInterfaceInfo ,
decimals
)
);
import { getAssociatedTokenAddressSync } from "@solana/spl-token" ;
// SPL ATA must exist
const splAta = getAssociatedTokenAddressSync ( mint , owner . publicKey );
await unwrap ( rpc , payer , splAta , owner , mint , amount );