Skip to main content
Withdraw liquidiy or collateral from the reserve. The SDK handles transaction building, instruction creation, and collateral release calculations.

Withdraw for Lending

Withdraw liquidity from the reserve.
1

Import Dependencies

Import the required packages for Solana RPC communication, Kamino SDK operations, and Kit transaction building.
import "dotenv/config";
import {
	createSolanaRpc,
	createSolanaRpcSubscriptions,
	address,
	pipe,
	createTransactionMessage,
	setTransactionMessageFeePayerSigner,
	setTransactionMessageLifetimeUsingBlockhash,
	appendTransactionMessageInstructions,
	signTransactionMessageWithSigners,
	sendAndConfirmTransactionFactory,
	getSignatureFromTransaction,
} from "@solana/kit";
import {
	KaminoMarket,
	KaminoAction,
	VanillaObligation,
	PROGRAM_ID,
	DEFAULT_RECENT_SLOT_DURATION_MS,
} from "@kamino-finance/klend-sdk";
import BN from "bn.js";
import { getKeypair } from "../../utils/keypair";
@solana/kit provides modern utilities for RPC, transaction building, and signing. @kamino-finance/klend-sdk contains market operation methods.
2

Initialize RPC and Load Market

Initialize the RPC connection and load the Kamino market instance.
const signer = await getKeypair();
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.mainnet-beta.solana.com");
const marketPubkey = address("DxXdAyU3kCjnyggvHmY5nAwg5cRbbmdyX3npfDMjjMek");
const market = await KaminoMarket.load(rpc, marketPubkey, DEFAULT_RECENT_SLOT_DURATION_MS);
KaminoMarket.load() fetches the current market state including all reserve data and configuration.
3

Build Withdraw Reserve Liquidity Instructions

Fetch the existing obligation from the blockchain and build withdraw instructions.
const usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const withdrawAmount = new BN(1_000_000); // 1 USDC (6 decimals)

// Fetch the existing obligation from the blockchain
const obligation = await market!.getObligationByWallet(
	address(signer.address),
	new VanillaObligation(PROGRAM_ID)
);

if (!obligation) {
	throw new Error(
		"No obligation found for this wallet. You must deposit first."
	);
}

const action = await KaminoAction.buildWithdrawTxns(
	market!,
	withdrawAmount,
	usdcMint,
	signer,
	obligation,
	true, // useV2Ixs
	undefined // scopeRefreshConfig
);

const instructions = [
	...action.computeBudgetIxs,
	...action.setupIxs,
	...action.lendingIxs,
	...action.cleanupIxs,
];

if (!instructions.length) {
	throw new Error("No instructions returned by Kamino SDK");
}
4

Build and Sign Transaction

Use Kit’s functional pipe pattern to build and sign the transaction.
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const transactionMessage = pipe(
	createTransactionMessage({ version: 0 }),
	(tx) => setTransactionMessageFeePayerSigner(signer, tx),
	(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
	(tx) => appendTransactionMessageInstructions(instructions, tx)
);

const signedTransaction = await signTransactionMessageWithSigners(
	transactionMessage
);
Kit’s pipe function enables functional composition of transaction building steps for cleaner, more maintainable code.
5

Send and Confirm Transaction

Send the transaction and confirm it using WebSocket.
const signature = getSignatureFromTransaction(signedTransaction);

await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction, {
	commitment: "confirmed",
	skipPreflight: true,
});

console.log("Withdrawal successful! Signature:", signature);

Withdraw for Borrowing

Withdraw collateral from an obligation.
1

Import Dependencies

Import the required packages for Solana RPC communication, Kamino SDK operations, and Kit transaction building.
import "dotenv/config";
import {
	createSolanaRpc,
	createSolanaRpcSubscriptions,
	address,
	pipe,
	createTransactionMessage,
	setTransactionMessageFeePayerSigner,
	setTransactionMessageLifetimeUsingBlockhash,
	appendTransactionMessageInstructions,
	signTransactionMessageWithSigners,
	sendAndConfirmTransactionFactory,
	getSignatureFromTransaction,
} from "@solana/kit";
import {
	KaminoMarket,
	KaminoAction,
	VanillaObligation,
	PROGRAM_ID,
	DEFAULT_RECENT_SLOT_DURATION_MS,
} from "@kamino-finance/klend-sdk";
import BN from "bn.js";
import { getKeypair } from "../../utils/keypair";
@solana/kit provides modern utilities for RPC, transaction building, and signing. @kamino-finance/klend-sdk contains market operation methods.
2

Initialize RPC and Load Market

Initialize the RPC connection and load the Kamino market instance.
const signer = await getKeypair();
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.mainnet-beta.solana.com");
const marketPubkey = address("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
const market = await KaminoMarket.load(rpc, marketPubkey, DEFAULT_RECENT_SLOT_DURATION_MS);
KaminoMarket.load() fetches the current market state including all reserve data and configuration.
3

Build Withdraw Collateral Instructions

Build withdraw instructions for collateral withdrawal.
const usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const withdrawAmount = new BN(1_000_000); // 1 USDC (6 decimals)

const withdrawAction = await KaminoAction.buildWithdrawTxns(
	market!,
	withdrawAmount,
	usdcMint,
	signer,
	new VanillaObligation(PROGRAM_ID),
	true, // useV2Ixs
	undefined, // scopeRefreshConfig
	1_000_000, // extraComputeBudget
	true, // includeAtaIxs
	false // requestElevationGroup
);

// Combine all instructions
const allInstructions = [
	...(withdrawAction.setupIxs || []),
	...(withdrawAction.lendingIxs || []),
	...(withdrawAction.cleanupIxs || []),
];
4

Build and Sign Transaction

Use Kit’s functional pipe pattern to build and sign the transaction.
// Get fresh blockhash
const { value: latestBlockhash } = await rpc
	.getLatestBlockhash({
		commitment: "finalized",
	})
	.send();

// Build transaction using functional pipe pattern
const transactionMessage = pipe(
	createTransactionMessage({ version: 0 }),
	(tx) => setTransactionMessageFeePayerSigner(signer, tx),
	(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
	(tx) => appendTransactionMessageInstructions(allInstructions, tx)
);

// Sign transaction
const signedTransaction = await signTransactionMessageWithSigners(
	transactionMessage
);
5

Send and Confirm Transaction

Send the transaction and confirm it using WebSocket.
const signature = getSignatureFromTransaction(signedTransaction);

await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction, {
	commitment: "confirmed",
	skipPreflight: true,
});

console.log("Withdrawal successful! Signature:", signature);
  1. The collateral amount is removed from your obligation
  2. Your borrowing capacity decreases
  3. Your loan-to-value (LTV) ratio increases