Skip to main content

Documentation Index

Fetch the complete documentation index at: https://kamino.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Repaying debt on a multiply position reduces your outstanding debt balance, lowers your LTV (Loan-to-Value) ratio, and improves position health. This example shows how to repay USDC debt on a TSLAx multiply position using the Klend SDK.

Multiply Repay with xStocks

Repay debt on a TSLAx multiply position to reduce leverage and improve position health.
1

Import Dependencies

Import the required packages for Solana RPC communication, Kamino SDK operations, and transaction building.
import {
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  address,
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstructions,
  signTransactionMessageWithSigners,
  sendAndConfirmTransactionFactory,
  getSignatureFromTransaction,
} from '@solana/kit';
import {
  KaminoMarket,
  KaminoAction,
  MultiplyObligation,
  PROGRAM_ID,
  parseKeypairFile,
  DEFAULT_RECENT_SLOT_DURATION_MS,
} from '@kamino-finance/klend-sdk';
import BN from 'bn.js';
2

Load Configuration and Initialize Market

Load the keypair and initialize the xStocks market.
const KEYPAIR_FILE = '/path/to/your/keypair.json';

const signer = await parseKeypairFile(KEYPAIR_FILE);

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');

const marketPubkey = address('5wJeMrUYECGq41fxRESKALVcHnNX26TAWy4W98yULsua'); // xStocks Market
const market = await KaminoMarket.load(rpc, marketPubkey, DEFAULT_RECENT_SLOT_DURATION_MS);
3

Find TSLAx Reserve in Market

Dynamically discover the TSLAx token mint by searching the market reserves by symbol.
const tslaReserve = Array.from(market!.reserves.values()).find((reserve) => reserve.symbol === 'TSLAx');
if (!tslaReserve) {
  console.log('TSLAx reserve not found in xStocks market');
}
const collTokenMint = tslaReserve.getLiquidityMint();
const debtTokenMint = address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); // USDC
This dynamic discovery approach allows the code to work across different markets without hardcoding token mint addresses.
4

Configure Repay Parameters

Set the amount of USDC to repay. This example repays $10 USDC.
const repayAmount = new BN(10_000_000); // 10.00 USDC (6 decimals)

const currentSlot = await rpc.getSlot().send();
You can repay any amount up to your total debt. After repaying, you are able to withdraw your collateral.
5

Fetch Existing Multiply Obligation

Create the multiply obligation type and fetch the existing position from the blockchain.
const obligationType = new MultiplyObligation(collTokenMint, debtTokenMint, PROGRAM_ID);

const obligation = await market!.getObligationByWallet(address(signer.address), obligationType);

if (!obligation) {
  console.log('No obligation found for this wallet. You must have an active borrow to repay.');
}
The MultiplyObligation type identifies this as a leveraged position rather than a standard borrow. The obligation must exist before you can repay debt.
6

Build Repay Transaction

Use KaminoAction.buildRepayTxns to generate the repay instructions.
const repayAction = await KaminoAction.buildRepayTxns(
  market!,
  repayAmount,
  debtTokenMint,
  signer,
  obligationType,
  true, // useV2Ixs
  undefined, // scopeRefreshConfig
  currentSlot,
  signer, // payer
  1_000_000, // extraComputeBudget
  true, // includeAtaIxs
  false // requestElevationGroup
);

const allInstructions = [
  ...(repayAction.setupIxs || []),
  ...(repayAction.lendingIxs || []),
  ...(repayAction.cleanupIxs || []),
];
buildRepayTxns handles all the complexity of repaying multiply positions, including ATA creation, scope price refreshes, and obligation updates.
7

Send Transaction

Get a fresh blockhash, build the transaction, sign it, and send it to the network.
const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();

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

const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
const signature = getSignatureFromTransaction(signedTransaction);

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

console.log(`Multiply repay successful! Repaid $10 USDC debt on TSLAx multiply position.`);
console.log(`Transaction signature: ${signature}`);
The repay transaction is complete, reducing your debt balance and improving your position’s health factor.

Borrow and Multiply SDK Methods

MethodOperationWhen to Use
getDepositWithLeverageIxsOpen position or add collateralCreating or adding to a leveraged position
buildRepayTxnsRepay with wallet fundsReducing debt using USDC, SOL, etc. from wallet
buildWithdrawTxnsWithdraw collateralWithdrawing collateral after debt is repaid
getWithdrawWithLeverageIxsDeleverage and withdrawSell collateral to repay debt and receive remaining value in wallet
getRepayWithCollIxsRepay debt with collateralSell collateral to repay debt without withdrawing (value stays in position)
Multiply operations use MultiplyObligation. Vanilla operations use VanillaObligation. The obligation type determines which PDA is derived for your position.