Skip to main content
Borrow assets against your collateral in Kamino lending markets. The SDK handles transaction building, instruction creation, and obligation management for borrowing operations.

Borrow

Borrow assets against your collateral.
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("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
const market = await KaminoMarket.load(rpc, marketPubkey, 100);
KaminoMarket.load() fetches the current market state including all reserve data and configuration.
3

Check for Existing Obligation

Verify that an obligation exists before attempting to borrow.
// Check if obligation exists
const existingObligation = await market!.getObligationByWallet(
	signer.address,
	new VanillaObligation(PROGRAM_ID)
);

if (!existingObligation) {
	throw new Error(
		"No existing obligation found. Please deposit collateral first."
	);
}
You must have an existing obligation with deposited collateral before you can borrow. If you haven’t deposited collateral yet, do that first.
4

Build Borrow Instructions

Generate borrow instructions for the specified token and amount.
const usdtMint = address("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
const borrowAmount = new BN(1_000_000); // 1.00 USDT (6 decimals)

const borrowAction = await KaminoAction.buildBorrowTxns(
	market!,
	borrowAmount,
	usdtMint,
	signer,
	new VanillaObligation(PROGRAM_ID),
	true, // useV2Ixs
	undefined, // scopeRefreshConfig
	1_000_000, // extraComputeBudget
	true, // includeAtaIxs
	false // requestElevationGroup
);
buildBorrowTxns creates borrow instructions that withdraw assets from the reserve pool to your wallet. The amount borrowed is added to your debt obligation.
5

Build and Sign Transaction

Combine all instructions and build the transaction using Kit’s functional pipe pattern.
// Combine all instructions
const allInstructions = [
	...(borrowAction.setupIxs || []),
	...(borrowAction.lendingIxs || []),
	...(borrowAction.cleanupIxs || []),
];

// 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
);
All setup, lending, and cleanup instructions are combined in a single transaction for borrowing.
6

Send and Confirm Transaction

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

// Send transaction
const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });
await sendTransaction(signedTransaction, {
	commitment: "confirmed",
	skipPreflight: true,
	maxRetries: 3n,
});

// Confirm transaction
await confirmTransactionViaPolling(rpc, signature);

console.log("Borrow successful! Signature:", signature);
Borrowing increases your debt and LTV ratio. Monitor your position to avoid liquidation risk.
  1. USDT is withdrawn from the reserve pool and sent to your wallet
  2. Your borrow amount increases in your obligation
  3. You start accruing interest on the borrowed amount
  4. Your loan-to-value (LTV) ratio increases
  5. Your available borrowing capacity decreases
Your maximum borrow amount depends on:
  1. Your collateral value
  2. Loan-to-Value (LTV) ratio
  3. Current borrows
  4. Reserve liquidity
Interest:
  • Accrues continuously based on the reserve’s borrow APY
  • Compounds over time
  • Varies based on reserve utilization
Repayment:
  • You must repay borrowed amount + accrued interest
  • Repay anytime to reduce debt and improve your position health
Keep LTV well below maximum:
  • Monitor your position regularly
  • Repay borrows or add collateral if LTV increases
  • Be aware of price volatility