// Mint compressed tokens - mints SPL tokens to pool, creates compressed token accounts
const transactionSignature = await mintTo(
rpc,
payer,
mint, // SPL mint with interface PDA for compression
recipient, // recipient address (toPubkey parameter)
payer, // mint authority
amount,
);
Get Started
Mint Compressed Tokens
Installation
Installation
- npm
- yarn
- pnpm
- SDK 2.0 (token-interface)
Install packages in your working directory:Install the CLI globally:
npm install @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/compressed-token@^0.23.0
npm install -g @lightprotocol/zk-compression-cli
Install packages in your working directory:Install the CLI globally:
yarn add @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/compressed-token@^0.23.0
yarn global add @lightprotocol/zk-compression-cli
Install packages in your working directory:Install the CLI globally:
pnpm add @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/compressed-token@^0.23.0
pnpm add -g @lightprotocol/zk-compression-cli
Install packages in your working directory:Install the CLI globally:
# npm
npm install @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/token-interface@^0.1.2
# yarn
yarn add @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/token-interface@^0.1.2
# pnpm
pnpm add @lightprotocol/stateless.js@^0.23.0 \
@lightprotocol/token-interface@^0.1.2
npm install -g @lightprotocol/zk-compression-cli
- Localnet
- Devnet
# start local test-validator in a separate terminal
light test-validator
In the code examples, use
createRpc() without arguments for localnet.Get an API key from Helius and add to
.env:.env
API_KEY=<your-helius-api-key>
In the code examples, use
createRpc(RPC_URL) with the devnet URL.- Action
- Instruction
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc } from "@lightprotocol/stateless.js";
import { createMint, mintTo } from "@lightprotocol/compressed-token";
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
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
// Mint compressed tokens
const recipient = Keypair.generate();
const tx = await mintTo(rpc, payer, mint, recipient.publicKey, payer, 1_000_000_000);
console.log("Mint:", mint.toBase58());
console.log("Recipient:", recipient.publicKey.toBase58());
console.log("Tx:", tx);
})();
import "dotenv/config";
import { Keypair, ComputeBudgetProgram, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
import { createRpc, bn, DerivationMode } from "@lightprotocol/stateless.js";
import {
createMintInterface,
createAtaInterface,
createMintToInterfaceInstruction,
getMintInterface,
getAssociatedTokenAddressInterface,
} from "@lightprotocol/compressed-token";
import { homedir } from "os";
import { readFileSync } from "fs";
// devnet:
const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
const rpc = createRpc(RPC_URL);
// localnet:
// const rpc = createRpc();
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
)
);
(async function () {
const { mint } = await createMintInterface(rpc, payer, payer, null, 9);
const recipient = Keypair.generate();
await createAtaInterface(rpc, payer, mint, recipient.publicKey);
const destination = getAssociatedTokenAddressInterface(mint, recipient.publicKey);
const mintInterface = await getMintInterface(rpc, mint);
let validityProof;
if (mintInterface.merkleContext) {
validityProof = await rpc.getValidityProofV2(
[
{
hash: bn(mintInterface.merkleContext.hash),
leafIndex: mintInterface.merkleContext.leafIndex,
treeInfo: mintInterface.merkleContext.treeInfo,
proveByIndex: mintInterface.merkleContext.proveByIndex,
},
],
[],
DerivationMode.compressible
);
}
const ix = createMintToInterfaceInstruction(
mintInterface,
destination,
payer.publicKey,
payer.publicKey,
1_000_000_000,
validityProof
);
const tx = new Transaction().add(
ComputeBudgetProgram.setComputeUnitLimit({ units: 500_000 }),
ix
);
const signature = await sendAndConfirmTransaction(rpc, tx, [payer]);
console.log("Mint:", mint.toBase58());
console.log("Tx:", signature);
})();
The SPL mint must have an SPL Interface PDA for compression.
The script creates it for you.For development, create a new mint with SPL interface via
The script creates it for you.For development, create a new mint with SPL interface via
createMint() or add an SPL interface to an existing mint via createSplInterface().Troubleshooting
TokenPool not found
TokenPool not found
// Error message: "TokenPool not found. Please create a compressed token
// pool for mint: [ADDRESS] via createTokenPool().
createMint.// Create mint with interface PDA for compression
import { createMint } from '@lightprotocol/compressed-token';
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
TokenPool mint does not match the provided mint
TokenPool mint does not match the provided mint
The interface PDA info doesn’t correspond to the mint address. Ensure you’re fetching the correct PDA:
// Get the correct interface PDA for your mint
const tokenPoolInfo = await getTokenPoolInfos(rpc, mint);
Amount and toPubkey arrays must have the same length
Amount and toPubkey arrays must have the same length
When minting to multiple recipients, ensure arrays are the same size.
// Wrong: Mismatched array lengths
const recipients = [addr1, addr2, addr3];
const amounts = [100, 200]; // Only 2 amounts for 3 recipients
// Correct: Same length arrays
const recipients = [addr1, addr2, addr3];
const amounts = [100, 200, 300]; // 3 amounts for 3 recipients
Advanced Configuration
Mint to Multiple Recipients
Mint to Multiple Recipients
// Mint different amounts to multiple recipients
const recipients = [
Keypair.generate().publicKey,
Keypair.generate().publicKey,
Keypair.generate().publicKey,
];
const amounts = [
1_000_000_000, // 1 token
2_000_000_000, // 2 tokens
500_000_000, // 0.5 tokens
];
const transactionSignature = await mintTo(
rpc,
payer,
mint, // SPL mint with interface PDA for compression
recipients, // array of recipients (toPubkey parameter)
payer, // mint authority
amounts, // array of amounts (amount parameter)
);
With Custom Mint Authority
With Custom Mint Authority
Mint tokens using a custom mint authority with
approveAndMintTo():import { approveAndMintTo } from '@lightprotocol/compressed-token';
// Mint tokens with a separate mint authority
const transactionSignature = await approveAndMintTo(
rpc,
payer,
mint, // SPL mint with interface PDA for compression
recipient.publicKey, // recipient of minted tokens (toPubkey parameter)
mintAuthority, // mint authority
mintAmount,
);