Airdrop Compressed Tokens
Note:
You must use an RPC that supports Light Protocol such as Helius
import { Keypair, PublicKey, ComputeBudgetProgram } from "@solana/web3.js";
import { CompressedTokenProgram, getTokenPoolInfos, selectTokenPoolInfo } from "@lightprotocol/compressed-token";
import { bn, buildAndSignTx, calculateComputeUnitPrice, createRpc, dedupeSigner, Rpc, selectStateTreeInfo, sendAndConfirmTx } from "@lightprotocol/stateless.js";
import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token";
import dotenv from "dotenv";
import bs58 from "bs58";
dotenv.config();
const RPC_ENDPOINT = process.env.RPC_ENDPOINT;
const MINT_ADDRESS = new PublicKey(process.env.MINT_ADDRESS!);
const PAYER_KEYPAIR = Keypair.fromSecretKey(
bs58.decode(process.env.PAYER_KEYPAIR!)
);
const airdropTokens = async () => {
const connection: Rpc = createRpc(RPC_ENDPOINT);
const mintAddress = MINT_ADDRESS;
const payer = PAYER_KEYPAIR;
const owner = payer;
/// Select a new tree for each transaction.
const activeStateTrees = await connection.getStateTreeInfos();
const treeInfo = selectStateTreeInfo(activeStateTrees);
/// Select a tokenpool info
const infos = await getTokenPoolInfos(connection, mintAddress);
const info = selectTokenPoolInfo(infos);
const sourceTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
payer,
mintAddress,
payer.publicKey
);
// // generate 10 addresses
// const addys = Array.from({ length: 10 }, () => {
// const keypair = Keypair.generate();
// return keypair.publicKey.toBase58();
// });
// Airdrop to example recipient
// 1 recipient = 120_000 CU
// 5 recipients = 170_000 CU
const airDropAddresses = ["FrRyCkdjwdcGqk2DGkuivkj2XP1RxzuZaDDvMLejoYEU",
"FUCww3SgAmqiP4CswfgY2r2Nsf6PPzARrXraEnGCn4Ln",
"GaxVqiQyJKQDRu6H4pfy9V6Xq19pHGr6HQKDQDv911Y4",
"HMWjaP76iq5izGBSSbj24w73RuDjk8DDqrrQFNW1pik6",
"GBG3sHLdrZ3bMHH9m6hQWNRgcUk1TR1GAJuBQKDirK7s",
"HmxFDNWwoK7dSBCEJCxZ8sBDVZQSvMrJWQN2n8dX7A7o",
"K1xwRg3v9VBhdZztuZAHkwyabyU7Aw223MF3gEHfbJu",
"k6srnidubpAEsFn3RoQ6hwP36QzXugN4rGT2V6hcGdU",
"LvWtTA3tDip1icurv5xdLMm5rFo7hhALxeVCgww7kdc",
"MTSLZDJppGh6xUcnrSSbSQE5fgbvCtQ496MqgQTv8c1",
"oQVkFBxgoWrwiRTrP45rVCzCEAeHw5ou9PXk5SMs6PZ",
"XxrnkCw4pKEGVhYZPCbmoYHjYDSPaC9a3c2RSWcxpCj",
].map(
(address) => new PublicKey(address)
);
const amount = bn(50_000_000);
const instructions = [];
instructions.push(
ComputeBudgetProgram.setComputeUnitLimit({ units: 120_000 }),
ComputeBudgetProgram.setComputeUnitPrice({
// Replace this with a dynamic priority_fee based on network conditions.
microLamports: calculateComputeUnitPrice(20_000, 120_000),
})
);
const compressInstruction = await CompressedTokenProgram.compress({
payer: payer.publicKey,
owner: owner.publicKey,
source: sourceTokenAccount.address,
toAddress: airDropAddresses,
amount: airDropAddresses.map(() => amount),
mint: mintAddress,
tokenPoolInfo: info,
outputStateTreeInfo: treeInfo,
});
instructions.push(compressInstruction);
const additionalSigners = dedupeSigner(payer, [owner]);
const { blockhash } = await connection.getLatestBlockhash();
const tx = buildAndSignTx(instructions, payer, blockhash, additionalSigners);
const txId = await sendAndConfirmTx(connection, tx);
console.log(`txId: ${txId}`);
}
airdropTokens();