Skip to main content
Borrow assets from a Kamino reserve using the API. The API builds the transaction, and you sign it locally keeping your keys secure.

Borrow via the API

1

Import Dependencies

Import the required packages for Solana RPC communication, transaction handling, and Kamino SDK utilities.
import {
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  getTransactionDecoder,
  getCompiledTransactionMessageDecoder,
  decompileTransactionMessageFetchingLookupTables,
  pipe,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  addSignersToTransactionMessage,
  signTransactionMessageWithSigners,
  sendAndConfirmTransactionFactory,
  getSignatureFromTransaction,
} from '@solana/kit';
import { parseKeypairFile } from '@kamino-finance/klend-sdk/dist/utils/signer';
2

Configure and Initialize

Set up the configuration and initialize RPC connections.
const KEYPAIR_FILE = '/path/to/your/keypair.json';
const API_BASE_URL = 'https://api.kamino.finance';
const RPC_ENDPOINT = 'https://api.mainnet-beta.solana.com';
const WS_ENDPOINT = 'wss://api.mainnet-beta.solana.com';

const MAIN_MARKET = '7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF';
const SOL_RESERVE = 'd4A2prbA2whesmvHaL88BH6Ewn5N4bTSU2Ze8P6Bc4Q';

const signer = await parseKeypairFile(KEYPAIR_FILE);
const rpc = createSolanaRpc(RPC_ENDPOINT);
const rpcSubscriptions = createSolanaRpcSubscriptions(WS_ENDPOINT);
3

Call the Kamino API

Make a POST request to the Kamino API to build the borrow transaction.
const res = await fetch(`${API_BASE_URL}/ktx/klend/borrow`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    wallet: signer.address,
    market: MAIN_MARKET,
    reserve: SOL_RESERVE,
    amount: '0.02',
  }),
});

const data = await res.json();

if (!res.ok) {
  console.error('Response error:', data);
}

const encodedTransaction = data.transaction;
The API returns a pre-built transaction encoded in base64 format ready for signing.
4

Decode Transaction

Decode the base64-encoded transaction and extract the message bytes.
const txBuffer = Buffer.from(encodedTransaction, 'base64');
const txMessageBytes = getTransactionDecoder().decode(txBuffer).messageBytes;
const compiledMessage = getCompiledTransactionMessageDecoder().decode(txMessageBytes);
5

Resolve Address Lookup Tables and Sign

Fetch the latest blockhash, decompile the transaction to resolve Address Lookup Tables, and sign.
const { value: latestBlockhash } = await rpc.getLatestBlockhash({
  commitment: 'finalized'
}).send();

const signedTransaction = await pipe(
  await decompileTransactionMessageFetchingLookupTables(compiledMessage, rpc),
  tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
  tx => setTransactionMessageFeePayerSigner(signer, tx),
  tx => addSignersToTransactionMessage([signer], tx),
  tx => signTransactionMessageWithSigners(tx)
);
const signature = getSignatureFromTransaction(signedTransaction);
decompileTransactionMessageFetchingLookupTables fetches the lookup table data from the blockchain and resolves all address references. This is required for transactions that use ALTs.
6

Send and Confirm Transaction

Submit the signed transaction to the Solana network.
const sendAndConfirm = sendAndConfirmTransactionFactory({
  rpc,
  rpcSubscriptions,
});

await sendAndConfirm(signedTransaction, {
  commitment: 'confirmed',
  skipPreflight: false,
});

console.log('Borrow successful! Signature:', signature);
Your borrow is complete! The API built the transaction, you signed it locally (keeping your keys secure), and it was successfully submitted to the network.