Documentation Index
Fetch the complete documentation index at: https://docs.meteora.ag/llms.txt
Use this file to discover all available pages before exploring further.
These examples are based on the local vault-sdk/ts-client source and tests. They focus on transaction construction and state reads. For the full method catalog, see the SDK Reference.
Setup
import VaultImpl, {
getAmountByShare,
getUnmintAmount,
getVaultPdas,
} from "@meteora-ag/vault-sdk";
import { AnchorProvider, BN, Wallet } from "@coral-xyz/anchor";
import { NATIVE_MINT } from "@solana/spl-token";
import {
Connection,
Keypair,
PublicKey,
Transaction,
} from "@solana/web3.js";
const connection = new Connection(process.env.RPC_URL!, "confirmed");
const wallet = new Wallet(Keypair.generate());
const provider = new AnchorProvider(connection, wallet, {
commitment: "confirmed",
});
const tokenMint = NATIVE_MINT;
const vault = await VaultImpl.create(connection, tokenMint, {
cluster: "mainnet-beta",
});
Use a real wallet adapter in browser apps. The generated keypair pattern is only suitable for local scripts and tests.
Fetch Vault State
await vault.refreshVaultState();
const lpSupply = await vault.getVaultSupply();
const withdrawableAmount = await vault.getWithdrawableAmount();
const strategies = await vault.getStrategiesState();
console.log({
vault: vault.vaultPda.toBase58(),
tokenVault: vault.tokenVaultPda.toBase58(),
tokenMint: vault.tokenMint.address.toBase58(),
lpMint: vault.vaultState.lpMint.toBase58(),
totalAmount: vault.vaultState.totalAmount.toString(),
withdrawableAmount: withdrawableAmount.toString(),
lpSupply: lpSupply.toString(),
strategies: strategies.length,
});
Convert LP To Underlying
const userLpBalance = await vault.getUserBalance(wallet.publicKey);
const withdrawableAmount = await vault.getWithdrawableAmount();
const lpSupply = await vault.getVaultSupply();
const underlyingShare = getAmountByShare(
userLpBalance,
withdrawableAmount,
lpSupply,
);
console.log("Underlying share", underlyingShare.toString());
Convert Desired Output To LP Burn
const desiredUnderlyingAmount = new BN(500_000_000); // 0.5 SOL
const lpToBurn = getUnmintAmount(
desiredUnderlyingAmount,
await vault.getWithdrawableAmount(),
await vault.getVaultSupply(),
);
console.log("LP to burn", lpToBurn.toString());
Deposit
const depositAmount = new BN(1_000_000_000); // 1 SOL
const tx = await vault.deposit(wallet.publicKey, depositAmount);
tx.feePayer = wallet.publicKey;
const simulation = await connection.simulateTransaction(tx);
console.log(simulation.value.err);
if (!simulation.value.err) {
const signature = await provider.sendAndConfirm(tx);
console.log("Deposit signature", signature);
}
For a native SOL vault, the SDK wraps SOL into the user’s wrapped SOL ATA before the deposit instruction.
Withdraw
const lpToBurn = await vault.getUserBalance(wallet.publicKey);
const tx = await vault.withdraw(wallet.publicKey, lpToBurn);
tx.feePayer = wallet.publicKey;
const simulation = await connection.simulateTransaction(tx);
console.log(simulation.value.err);
if (!simulation.value.err) {
const signature = await provider.sendAndConfirm(tx);
console.log("Withdraw signature", signature);
}
For a native SOL vault, the SDK adds a post-instruction to close the wrapped SOL ATA.
Batch Load Vaults
const tokenMints = [
new PublicKey("So11111111111111111111111111111111111111112"),
new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
];
const vaults = await VaultImpl.createMultiple(connection, tokenMints, {
cluster: "mainnet-beta",
});
for (const item of vaults) {
console.log({
vault: item.vaultPda.toBase58(),
tokenMint: item.tokenMint.address.toBase58(),
lpMint: item.vaultState.lpMint.toBase58(),
});
}
Batch Load User LP Balances
const lpMints = vaults.map((item) => item.vaultState.lpMint);
const balances = await VaultImpl.fetchMultipleUserBalance(
connection,
lpMints,
wallet.publicKey,
);
balances.forEach((balance, index) => {
console.log(lpMints[index].toBase58(), balance.toString());
});
Derive Vault PDAs
import { PROGRAM_ID } from "@meteora-ag/vault-sdk";
const pdas = getVaultPdas(
tokenMint,
new PublicKey(PROGRAM_ID),
);
console.log({
vault: pdas.vaultPda.toBase58(),
tokenVault: pdas.tokenVaultPda.toBase58(),
lpMint: pdas.lpMintPda.toBase58(),
});
Create A Permissionless Vault Instruction
const createVaultIx = await VaultImpl.createPermissionlessVaultInstruction(
connection,
wallet.publicKey,
tokenMint,
{
cluster: "mainnet-beta",
},
);
const tx = new Transaction().add(createVaultIx);
tx.feePayer = wallet.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
console.log(await connection.simulateTransaction(tx));
This helper builds the program initialize instruction and derives the vault, token vault, and LP mint PDAs.
Affiliate Flow
const affiliateVault = await VaultImpl.create(connection, tokenMint, {
cluster: "mainnet-beta",
affiliateId: new PublicKey("YOUR_PARTNER_PUBLIC_KEY"),
});
const partnerInfo = await affiliateVault.getAffiliateInfo();
const userLpBalance = await affiliateVault.getUserBalance(wallet.publicKey);
console.log({
partnerToken: partnerInfo.partnerToken.toBase58(),
userLpBalance: userLpBalance.toString(),
});
With affiliateId, deposit and withdraw use the affiliate program wrapper and derive affiliate user LP token accounts internally.