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,
	address,
	pipe,
	createTransactionMessage,
	setTransactionMessageFeePayerSigner,
	setTransactionMessageLifetimeUsingBlockhash,
	appendTransactionMessageInstructions,
	signTransactionMessageWithSigners,
	sendTransactionWithoutConfirmingFactory,
	getSignatureFromTransaction,
} from "@solana/kit";
import {
	KaminoMarket,
	KaminoAction,
	VanillaObligation,
	PROGRAM_ID,
} from "@kamino-finance/klend-sdk";
import BN from "bn.js";
import { getKeypair } from "../../utils/keypair";
import { confirmTransactionViaPolling } from "../../utils/tx";
@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 marketPubkey = address("DxXdAyU3kCjnyggvHmY5nAwg5cRbbmdyX3npfDMjjMek");
const market = await KaminoMarket.load(rpc, marketPubkey, 100);
KaminoMarket.load() fetches the current market state including all reserve data and configuration.
3

Fetch Obligation and Build Withdraw 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 HTTP polling.
const signature = getSignatureFromTransaction(signedTransaction);

const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });
await sendTransaction(signedTransaction, {
	commitment: "confirmed",
	skipPreflight: true,
});

// Confirm transaction using HTTP polling
await confirmTransactionViaPolling(rpc, signature);

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,
	address,
	pipe,
	createTransactionMessage,
	setTransactionMessageFeePayerSigner,
	setTransactionMessageLifetimeUsingBlockhash,
	appendTransactionMessageInstructions,
	signTransactionMessageWithSigners,
	sendTransactionWithoutConfirmingFactory,
	getSignatureFromTransaction,
} from "@solana/kit";
import {
	KaminoMarket,
	KaminoAction,
	VanillaObligation,
	PROGRAM_ID,
} from "@kamino-finance/klend-sdk";
import BN from "bn.js";
import { getKeypair } from "../../utils/keypair";
import { confirmTransactionViaPolling } from "../../utils/tx";
@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 marketPubkey = address("DxXdAyU3kCjnyggvHmY5nAwg5cRbbmdyX3npfDMjjMek");
const market = await KaminoMarket.load(rpc, marketPubkey, 100);
KaminoMarket.load() fetches the current market state including all reserve data and configuration.
3

Fetch Obligation and Build Withdraw 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
);
5

Send and Confirm Transaction

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

const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });
await sendTransaction(signedTransaction, {
	commitment: "confirmed",
	skipPreflight: true,
});

await confirmTransactionViaPolling(rpc, signature);

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