Skip to main content

Delegation with Light Token works similar to SPL. When you approve a delegate, you’re authorizing a specific account to transfer tokens on your behalf:
  • Owner retains custody: You still own the tokens and can transfer or revoke at any time. Delegation is non-custodial.
  • Capped spending: The delegate can spend tokens up to the limit, but cannot access or drain the account beyond the approved amount.
  • Single delegate per account: Each token account can only have one active delegate. The owner can revoke at any time.
  • New approval replaces old: Approving a new delegate automatically revokes the previous one
SPLLight
Approveapprove()approveInterface()
Delegated Transfertransfer() (delegate signs)transferDelegatedInterface()
Revokerevoke()revokeInterface()
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

Use cases

Use caseHow delegation helps
SubscriptionsApprove a monthly cap. The service provider transfers the fee each period.
Recurring paymentsApprove a spending limit. The payment processor draws funds as needed.
Managed spendingA parent or admin approves a cap for a sub-account.
Agent walletsAn AI agent operates within a delegated spending limit.

Setup

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

const rpc = createRpc(RPC_ENDPOINT);

Approve a delegate

Grant a delegate permission to spend up to a capped amount:
import { approveInterface } from "@lightprotocol/compressed-token/unified";

const tx = await approveInterface(
  rpc,
  payer,
  senderAta,
  mint,
  delegate.publicKey,     // who gets permission
  500_000,                // amount cap
  owner                   // token owner (signs)
);

console.log("Approved:", tx);

Check delegation status

Check the delegation status of an account:
import { getAtaInterface } from "@lightprotocol/compressed-token";

const account = await getAtaInterface(rpc, senderAta, owner.publicKey, mint);

console.log("Delegate:", account.parsed.delegate?.toBase58() ?? "none");
console.log("Delegated amount:", account.parsed.delegatedAmount.toString());

Transfer as Delegate

Once approved, the delegate can transfer tokens on behalf of the owner. The delegate is the transaction authority. Only the delegate and fee payer sign; the owner’s signature is not required.transferDelegatedInterface takes a recipient wallet address and creates the recipient’s associated token account internally.
import { transferDelegatedInterface } from "@lightprotocol/compressed-token/unified";

const tx = await transferDelegatedInterface(
  rpc,
  payer,
  senderAta,
  mint,
  recipient.publicKey,   // recipient wallet (associated token account created internally)
  delegate,              // delegate authority (signer)
  owner.publicKey,       // owner (does not sign)
  200_000,               // must be within approved cap
);

console.log("Delegated transfer:", tx);
createTransferDelegatedInterfaceInstructions returns TransactionInstruction[][] for manual transaction control.
import {
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import { createTransferDelegatedInterfaceInstructions } from "@lightprotocol/compressed-token/unified";

const instructions = await createTransferDelegatedInterfaceInstructions(
  rpc,
  payer.publicKey,
  mint,
  200_000,
  delegate.publicKey,
  owner.publicKey,
  recipient.publicKey,
  9, // decimals
);

for (const ixs of instructions) {
  const tx = new Transaction().add(...ixs);
  await sendAndConfirmTransaction(rpc, tx, [payer, delegate]);
}

Revoke a delegate

Remove spending permission:
import { revokeInterface } from "@lightprotocol/compressed-token/unified";

const tx = await revokeInterface(rpc, payer, senderAta, mint, owner);

console.log("Revoked:", tx);

Basic payment

Send a single token transfer.

Gasless transactions

Separate the fee payer from the token owner.

Receive payments

Load cold accounts and share ATA address with the sender.

Didn’t find what you were looking for?

Reach out! Telegram | email | Discord