Skip to main content
Instant withdrawals let a depositor burn LP tokens and receive one reserve token immediately when the vault has enough executable reserve liquidity. Use the read helpers first, then build the reserve-withdrawal instruction. If capacity is unavailable for the requested output mint, use the queued withdrawal flow instead.

Check vault capacity

fetchInstantWithdrawalCapacity returns the vault-level amount that can currently be withdrawn from reserves for one output mint.
import { ExponentVault } from "@exponent-labs/exponent-sdk";
import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const vault = await ExponentVault.load({ connection, address: vaultAddress });

const USDC_MINT = new PublicKey("...");

const capacity = await vault.fetchInstantWithdrawalCapacity({
  outputMint: USDC_MINT,
});

console.log("mint:", capacity.mint.toBase58());
console.log("amount:", capacity.amount);
console.log("decimals:", capacity.decimals);

Return value

FieldTypeDescription
mintPublicKeyVault underlying or selected output mint
amountbigintGross instant-withdrawal capacity in raw mint units
decimalsnumberDecimal places for the returned mint

Check user capacity

fetchUserInstantWithdrawalCapacity applies the user’s spendable LP balance to the vault-level capacity.
const userCapacity = await vault.fetchUserInstantWithdrawalCapacity({
  owner: wallet.publicKey,
  outputMint: USDC_MINT,
});

Parameters

ParameterTypeDescription
ownerPublicKeyDepositor wallet public key
outputMintPublicKeyOptional. Reserve mint to receive
tokenLpAccountPublicKeyOptional. LP token account to read instead of the owner’s ATA
tokenProgramPublicKeyOptional. Token program for the LP account

Quote an instant withdrawal

fetchInstantWithdrawalQuote quotes an executable instant withdrawal for a selected LP amount and output mint.
const quote = await vault.fetchInstantWithdrawalQuote({
  lpAmountIn: 500_000_000n,
  outputMint: USDC_MINT,
});

console.log("LP burned:", quote.lp.amountIn);
console.log("fee:", quote.fee.amount);
console.log("net base value:", quote.net.amount);
console.log("output:", quote.output.amount);
console.log("slot:", quote.quotedAtSlot);

Parameters

ParameterTypeDescription
lpAmountInbigintLP token amount to burn
outputMintPublicKeyReserve mint to receive

Return value

FieldTypeDescription
lpInstantWithdrawalQuoteLpBreakdownLP input, fee amount, user amount, mint, and decimals
grossInstantWithdrawalQuoteAmountGross base value consumed by reserve and window limits
feeInstantWithdrawalQuoteAmountBase value retained in the vault by the LP fee split
netInstantWithdrawalQuoteAmountBase value converted into the selected output token
outputInstantWithdrawalQuoteAmountExpected amount for the selected output mint
quotedAtSlotnumberSlot used for the quote

Execute from reserves

Use ixExecuteWithdrawalFromReservesWithResolvedAumAccounts after quoting. The resolved helper includes derived AUM accounts from current strategy state, including positions that require RPC-derived accounts.
import {
  ExponentVault,
  SQUADS_PROGRAM_ID,
} from "@exponent-labs/exponent-sdk";
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import { Connection, PublicKey, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const vault = await ExponentVault.load({ connection, address: vaultAddress });

const outputMint = new PublicKey("...");
const entryIdx = vault.state.tokenEntries.findIndex((entry) =>
  entry.mint.equals(outputMint),
);

if (entryIdx === -1) {
  throw new Error("Output mint is not a vault token entry");
}

const entry = vault.state.tokenEntries[entryIdx];

const quote = await vault.fetchInstantWithdrawalQuote({
  lpAmountIn: 500_000_000n,
  outputMint,
});

const ix = await vault.ixExecuteWithdrawalFromReservesWithResolvedAumAccounts({
  owner: wallet.publicKey,
  entryIdx,
  lpAmount: quote.lp.amountIn,
  tokenSrc: entry.tokenSquadsAccount,
  tokenVaultSrc: entry.tokenAccountVault,
  tokenDst: getAssociatedTokenAddressSync(outputMint, wallet.publicKey),
  squadsProgram: SQUADS_PROGRAM_ID,
});

const tx = new Transaction().add(ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);

Required parameters

ParameterTypeDescription
ownerPublicKeyDepositor wallet public key
entryIdxnumberIndex of the vault token entry to withdraw
lpAmountbigint | numberLP token amount to burn
tokenSrcPublicKeySquads-owned reserve token account for the selected entry
tokenVaultSrcPublicKeyVault-owned reserve token account for the selected entry
tokenDstPublicKeyDepositor token account for the output mint
squadsProgramPublicKeySquads program ID

Optional parameters

ParameterTypeDescription
tokenLpSrcPublicKeyDepositor LP token source account. Defaults to the depositor’s ATA
tokenProgramPublicKeyToken program for reserve transfers
token2022ProgramPublicKeyToken-2022 program when needed
tokenLpEscrowPublicKeyLP token escrow. Defaults to the vault’s LP escrow
mintLpPublicKeyLP mint. Defaults to the vault’s LP mint
extraRemainingAccountsAccountMeta[]Additional AUM accounts when you are not using the resolved helper
Quotes depend on reserve balances, AUM, LP supply, and the instant withdrawal window. Fetch a quote and submit the transaction promptly.

Queued withdrawal fallback

Instant withdrawal only uses executable reserve liquidity. If the quote is unavailable or the output amount is too low, use ixQueueWithdrawal and ixExecuteWithdrawal instead.