Documentation Index
Fetch the complete documentation index at: https://v2-docs.exponent.finance/llms.txt
Use this file to discover all available pages before exploring further.
Use these instructions when your strategy vault should hold a direct Kamino Vault position.
Choose an execution API
Use the API that matches how much control you want over execution:
| API | Use it when | Kamino Vault withdraw behavior |
|---|
VaultTransactionBuilder | You want the SDK to assemble and send the flow for you, or you are chaining multiple steps | Omitted-reserve withdraws are planned and split into sequential transaction sets automatically when needed |
createVaultSyncTransactions | You want low-level wrapped sync transaction results for a smart omitted-reserve withdraw | Returns one or more VaultSyncTransactionResult objects |
createVaultSyncTransaction | You are building a deposit, an explicit-reserve withdraw, or any call that must fit in exactly one sync transaction | Throws if the planned withdraw does not fit in one sync transaction |
Kamino Vault deposits currently build one sync transaction result. The plural helper is mainly useful for smart omitted-reserve withdraws, because those can expand into multiple reserve-specific sync transactions.
In the current SDK, omitted-reserve Kamino Vault withdraws are the only Kamino Vault actions that can expand into multiple VaultSyncTransactionResult values. Other Kamino Vault calls still return one result.
Transaction structure
createVaultSyncTransaction returns one low-level sync transaction result with four parts:
import BN from "bn.js";
import {
createVaultSyncTransaction,
kaminoVaultAction,
} from "@exponent-labs/exponent-sdk";
import {
Transaction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
const { setupInstructions, preInstructions, instruction, postInstructions } =
await createVaultSyncTransaction({
instructions: [
kaminoVaultAction.deposit({
vault: kaminoVault,
amount: new BN(100_000_000),
}),
],
owner: vaultPda,
connection,
policyPda,
vaultPda,
signer: wallet.publicKey,
vaultAddress,
});
const tx = new Transaction().add(
...setupInstructions,
...preInstructions,
instruction,
...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
| Part | What it contains |
|---|
setupInstructions | Idempotent setup such as creating the Kamino Vault shares ATA for the managed vault |
preInstructions | Refresh or position-tracking instructions that must run before the Squads sync step |
instruction | The Squads sync transaction instruction that executes the Kamino Vault action |
postInstructions | Follow-up refresh instructions that must run after the sync step |
createVaultSyncTransactions and createVaultSyncTransaction both default autoManagePositions to false. VaultTransactionBuilder defaults it to true.
createVaultSyncTransactions returns the same structure in an array. Send those results sequentially in the order returned.
Deposit
kaminoVaultAction.deposit moves the vault’s deposit token ATA into a Kamino Vault and mints Kamino Vault shares back to the managed vault.
import BN from "bn.js";
import {
createVaultSyncTransaction,
kaminoVaultAction,
} from "@exponent-labs/exponent-sdk";
import {
Transaction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
const { setupInstructions, preInstructions, instruction, postInstructions } =
await createVaultSyncTransaction({
instructions: [
kaminoVaultAction.deposit({
vault: kaminoVault,
amount: new BN(100_000_000),
}),
],
owner: vaultPda,
connection,
policyPda,
vaultPda,
signer: wallet.publicKey,
vaultAddress,
});
const tx = new Transaction().add(
...setupInstructions,
...preInstructions,
instruction,
...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
Parameters
| Parameter | Type | Description |
|---|
vault | PublicKey | Kamino Vault address |
amount | BN | Amount of the deposit token to move into the Kamino Vault |
The SDK always adds an idempotent shares ATA creation instruction for the managed vault before the deposit runs.
Withdraw
kaminoVaultAction.withdraw burns Kamino Vault shares from the managed vault and withdraws the underlying deposit token back to the managed vault ATA.
import BN from "bn.js";
import {
createVaultSyncTransactions,
kaminoVaultAction,
} from "@exponent-labs/exponent-sdk";
import {
Transaction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
const results = await createVaultSyncTransactions({
instructions: [
kaminoVaultAction.withdraw({
vault: kaminoVault,
sharesAmount: new BN(50_000_000),
}),
],
owner: vaultPda,
connection,
policyPda,
vaultPda,
signer: wallet.publicKey,
vaultAddress,
});
for (const result of results) {
const tx = new Transaction().add(
...result.setupInstructions,
...result.preInstructions,
result.instruction,
...result.postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
}
Parameters
| Parameter | Type | Description |
|---|
vault | PublicKey | Kamino Vault address |
sharesAmount | BN | Amount of Kamino Vault shares to redeem |
reserve | PublicKey | Optional override for the underlying Kamino Lend reserve to unwind. Omit it to let the SDK plan the withdraw across the Kamino Vault’s allocated reserves |
reserve is not the Kamino Vault itself. A Kamino Vault has its own token_vault and shares_mint, and it can allocate capital across one or more underlying Kamino Lend reserves. The raw invested-withdraw path is reserve-specific, so reserve overrides which underlying reserve leg to unwind.
If you omit reserve, the SDK plans the withdraw across the Kamino Vault’s allocated reserves automatically. createVaultSyncTransactions returns however many sync transaction results that plan needs. VaultTransactionBuilder does the same at a higher level and sends the resulting transaction sets sequentially for you. Use createVaultSyncTransaction only when you specifically want the call to fail unless the full withdraw fits in one sync transaction.
Related pages