Skip to main content

Documentation Index

Fetch the complete documentation index at: https://luminouslabs-cc5545c6-feat-add-zk.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The approve() and revoke() functions grant and remove delegate spending authority for compressed tokens. Only the token owner can perform these instructions.
// Approve delegate for spending up to the specified amount
const approveSignature = await approve(
    rpc,
    payer,
    mint, // SPL mint with token pool for compression
    amount,
    owner,
    delegate.publicKey, // delegate account
);

Get Started

1

Approve / Revoke Delegates

Install packages in your working directory:
npm install @lightprotocol/stateless.js@alpha \
            @lightprotocol/compressed-token@alpha
Install the CLI globally:
npm install -g @lightprotocol/zk-compression-cli@alpha
# start local test-validator in a separate terminal
light test-validator
In the code examples, use createRpc() without arguments for localnet.
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc } from "@lightprotocol/stateless.js";
import { createMint, mintTo, approve } from "@lightprotocol/compressed-token";
import BN from "bn.js";
import { homedir } from "os";
import { readFileSync } from "fs";

// devnet:
const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
// localnet:
// const RPC_URL = undefined;
const payer = Keypair.fromSecretKey(
    new Uint8Array(
        JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
    )
);

(async function () {
    // devnet:
    const rpc = createRpc(RPC_URL);
    // localnet:
    // const rpc = createRpc();

    // Setup: Create mint and mint tokens
    const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
    const owner = Keypair.generate();
    await mintTo(rpc, payer, mint, owner.publicKey, payer, 1_000_000_000);

    // Approve delegate
    const delegate = Keypair.generate();
    const tx = await approve(rpc, payer, mint, new BN(500_000_000), owner, delegate.publicKey);

    console.log("Mint:", mint.toBase58());
    console.log("Delegate:", delegate.publicKey.toBase58());
    console.log("Tx:", tx);
})();
Before we approve or revoke delegates, we need:
  • compressed token accounts to delegate or revoke delegation from, and
  • an SPL mint with a token pool for compression. This token pool can be created for new SPL mints via createMint() or added to existing SPL mints via createTokenPool().

Troubleshooting

Attempting to revoke non-delegated accounts.
/// Verify accounts are delegated before revocation.
const delegateAccounts = await rpc.getCompressedTokenAccountsByDelegate(
    delegate.publicKey,
    { mint }
);

if (delegateAccounts.items.length === 0) {
    console.log("No delegated accounts to revoke");
    return;
}

Advanced Configuration

const delegates = [
    Keypair.generate().publicKey,
    Keypair.generate().publicKey,
];

const amounts = [
    200_000_000, // 0.2 tokens to first delegate
    300_000_000, // 0.3 tokens to second delegate
];

// Approve each delegate
for (let i = 0; i < delegates.length; i++) {
    const approveTx = await approve(
        rpc,
        payer,
        mint,
        amounts[i],
        tokenOwner,
        delegates[i],
    );

    console.log(`Delegate ${i + 1} approved:`, approveTx);
}
const delegates = [
    new PublicKey("DELEGATE_1_ADDRESS"),
    new PublicKey("DELEGATE_2_ADDRESS"),
];

// Revoke each delegate
for (const delegate of delegates) {
    // Get delegated accounts for this delegate
    const delegateAccounts = await rpc.getCompressedTokenAccountsByDelegate(
        delegate,
        { mint }
    );

    if (delegateAccounts.items.length > 0) {
        const revokeTx = await revoke(
            rpc,
            payer,
            delegateAccounts.items,
            tokenOwner,
        );

        console.log(`Delegate ${delegate.toBase58()} revoked:`, revokeTx);
    }
}

Next Steps

Check out the advanced guides for airdrops, combining multiple instructions in one transaction, and client examples.