Skip to content

Instantly share code, notes, and snippets.

@zhe-t
Created July 25, 2024 11:39
Show Gist options
  • Save zhe-t/b59278794de9ac0e120a57b568242d20 to your computer and use it in GitHub Desktop.
Save zhe-t/b59278794de9ac0e120a57b568242d20 to your computer and use it in GitHub Desktop.
import MerkleDistributor from '@jup-ag/merkle-distributor-sdk';
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
/**
* MerkleClaimChecker is a class that can be used to check if an address has already claimed a Merkle airdrop.
* Example usage:
* const merkleClaimChecker = MerkleClaimChecker.create()
* .setRpcUrl(rpcConnectionUrl)
* .setDefaultWallet()
* // or .setWallet(wallet)
* .generateProvider()
* .setTargetAddress(targetAddress)
* .setTokenMint(tokenMint)
* .setClaimProofEndpoint(claimProofEndpoint)
* .generateMerkleDistributor()
* const claimStatus = await merkleClaimChecker.getClaimStatus(address);
*/
export class MerkleClaimChecker {
private connection: Connection | undefined;
private provider: AnchorProvider | undefined;
private wallet: Wallet | undefined;
private merkleDistributor: MerkleDistributor | undefined;
private tokenMint: PublicKey | undefined;
private targetAddress: PublicKey | undefined;
private claimProofEndpoint: string | undefined;
/**
* Creates a new MerkleClaimChecker instance.
*/
constructor() { }
/**
* Creates a new MerkleClaimChecker instance.
* @returns MerkleClaimChecker instance.
*/
public static create() { return new MerkleClaimChecker(); }
/**
* Sets the RPC URL for the MerkleClaimChecker instance.
* @param url RPC URL.
* @returns MerkleClaimChecker instance.
*/
public setRpcUrl(url: string) {
this.connection = new Connection(url);
return this;
}
/**
* Sets the wallet for the MerkleClaimChecker instance.
* @param wallet Wallet.
* @returns MerkleClaimChecker instance.
*/
public setWallet(wallet: Wallet) {
this.wallet = wallet;
return this;
}
/**
* Sets the default wallet for the MerkleClaimChecker instance.
* This will generate a new wallet using the Keypair class.
* @returns MerkleClaimChecker instance.
*/
public setDefaultWallet() {
this.wallet = new Wallet(new Keypair());
return this;
}
/**
* Once the RPC URL, wallet, and connection are set, this method will generate the provider.
* @returns MerkleClaimChecker instance.
*/
public generateProvider() {
if (!this.connection || !this.wallet) {
throw new Error('Connection and wallet must be set before setting provider');
}
this.provider = new AnchorProvider(
this.connection,
this.wallet,
{ commitment: 'confirmed' }
);
return this;
}
/**
* Sets the target address for the MerkleClaimChecker instance.
* This is the address that will be checked for claim status.
* @param address Target address.
* @returns MerkleClaimChecker instance.
*/
public setTargetAddress(address: string | PublicKey) {
if (typeof address === 'string') {
this.targetAddress = new PublicKey(address);
} else {
this.targetAddress = address;
}
return this;
}
/**
* Sets the token mint for the MerkleClaimChecker instance.
* This is the token mint that will be used to check claim status.
* @param mint Token mint.
* @returns MerkleClaimChecker instance.
*/
public setTokenMint(mint: string | PublicKey) {
if (typeof mint === 'string') {
this.tokenMint = new PublicKey(mint);
} else {
this.tokenMint = mint;
}
return this;
}
/**
* Sets the claim proof endpoint for the MerkleClaimChecker instance.
* @param endpoint Claim proof endpoint.
* @returns MerkleClaimChecker instance.
*/
public setClaimProofEndpoint(endpoint: string) {
this.claimProofEndpoint = endpoint;
return this;
}
/**
* Once the target address, token mint, and claim proof endpoint are set, this method will generate the MerkleDistributor.
* @returns MerkleClaimChecker instance.
*/
public generateMerkleDistributor() {
if (!this.tokenMint || !this.claimProofEndpoint) {
throw new Error('Target address and claim proof endpoint must be set before generating merkle distributor');
}
if (!this.provider) {
throw new Error('Provider must be set before generating merkle distributor');
}
this.merkleDistributor = new MerkleDistributor(
this.provider,
{
targetToken: this.tokenMint,
claimProofEndpoint: this.claimProofEndpoint,
}
);
return this;
}
/**
* Checks if the address has already claimed the Merkle airdrop.
* @param address Address to check claims for.
* @returns True if the address has already claimed the Merkle airdrop, false otherwise.
*/
public async getClaimStatus() {
if (!this.merkleDistributor) {
throw new Error('Merkle distributor must be set before getting claim status');
}
if (!this.targetAddress) {
throw new Error('Target address must be set before getting claim status');
}
const claimStatus = await this.merkleDistributor.getClaimStatus(this.targetAddress);
if (claimStatus === null) {
return false;
}
return claimStatus.isClaimed;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment