Client Integration
In this guide, we will go through the steps to set up a local development environment for building onchain integrations with Lockup using TypeScript and Anchor's IDL.
caution
The following code examples are for demonstration purposes only and are not production-ready. They are intended to provide guidance on how to interact with the MerkleInstant program.
Dependencies
Download Types
First, download the TypeScript types for the MerkleInstant program from the GitHub release:
curl -L -o sablier_merkle_instant.ts \
https://github.com/sablier-labs/solsab/releases/download/v1.0.0/sablier_merkle_instant.ts
Install NPM Packages
Install the required Solana and Anchor packages:
bun add @coral-xyz/anchor@0.31.1 @solana/web3.js@1.98.2 bn.js@5.2.2
Setup
Import the necessary modules and types:
import * as anchor from "@coral-xyz/anchor";
import { Connection, PublicKey, Keypair } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { SablierMerkleInstant } from "./sablier_merkle_instant"; // Path to your downloaded types
import BN from "bn.js";
Set up the Anchor provider and program instance:
// Create connection to Solana cluster
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
// Set up wallet (example using a keypair)
const wallet = new anchor.Wallet(yourKeypair);
// Create provider
const provider = new anchor.AnchorProvider(connection, wallet, {
commitment: "confirmed",
});
// Set the provider
anchor.setProvider(provider);
// Initialize the program (PROGRAM_ID is included in the types)
const program = new anchor.Program<SablierMerkleInstant>(
idl as SablierMerkleInstant, // Your IDL object
provider,
);
Craete an airdrop campaign
async function createAirdropCampaign() {
const creator = provider.wallet.publicKey;
// Some dummy parameters values
const merkleRoot = Array.from(Buffer.from("d52549cb072a1fcd052412fc80f678effe92aeeedccd1cae632c5c6e1de89379", "hex"));
const startTime = new BN(Math.floor(Date.now()));
// 30 days later
const expirationTime = startTime.add(new BN(24 * 60 * 60 * 30));
const ipfsCid = "bafkreiecpwdhvkmw4y6iihfndk7jhwjas3m5htm7nczovt6m37mucwgsrq";
const name = "My Airdrop Campaign";
// Total amount to be airdropped to all recipients
const aggregateAmount = new BN(10000 * 10 ** 6); // 10,000 tokens (assuming 6 decimals)
// Number of recipients
const recipientCount = 10;
const airdropTokenMint = new PublicKey("YOUR_TOKEN_MINT_HERE");
// Set a higher compute unit limit so that the transaction doesn't fail
const increaseCULimitIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 });
const txSignature = await merkleInstantProgram.methods
.createCampaign(merkleRoot, startTime, expirationTime, name, ipfsCid, aggregateAmount, recipientCount)
.signers([signerKeys])
.accounts({
airdropTokenMint,
airdropTokenProgram: TOKEN_PROGRAM_ID,
creator,
})
.preInstructions([increaseCULimitIx])
.rpc();
console.log("Airdrop campaign created successfully!");
console.log("Transaction signature:", txSignature);
}
Claim from an airdrop campaign
async function claimFromAirdropCampaign(campaign: PublicKey, merkleProof: number[][]) {
const claimer = provider.wallet.publicKey;
const recipient = claimer; // The recipient of the airdrop
// The index from the Merkle tree
const index = 1;
// Amount allocated to the recipient
const amount = new BN(1000 * 10 ** 6); // 1000 tokens (assuming 6 decimals)
// Chainlink program and feed addresses
const chainlinkProgram = new PublicKey("HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny");
const chainlinkSolUsdFeed = new PublicKey("99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR");
const airdropTokenMint = new PublicKey("YOUR_TOKEN_MINT_HERE");
const txSignature = await this.merkleInstant.methods
.claim(index, amount, merkleProof)
.accounts({
airdropTokenMint,
airdropTokenProgram: TOKEN_PROGRAM_ID,
campaign,
chainlinkProgram,
chainlinkSolUsdFeed,
claimer,
recipient,
})
.rpc();
console.log("Airdrop claimed successfully!");
console.log("Transaction signature:", txSignature);
}
For more examples and advanced usage, refer to the SolSab repository test files and scripts.