Skip to main content
Redeem cTokens (collateral tokens) to receive the underlying asset plus any accrued interest. This process burns your cTokens and returns the deposited assets along with earned yield.

Redeeming cTokens

Burn cTokens to withdraw your deposit and interest from Kamino lending reserves.
1

Import Dependencies

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

Load Signer and Initialize Market

Load your keypair from a file and initialize RPC connections and the Kamino 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('DxXdAyU3kCjnyggvHmY5nAwg5cRbbmdyX3npfDMjjMek');
const usdcMint = address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
const kUsdcMint = address('7D8C5pDFxug58L9zkwK7bCiDg4kD4AygzbcZUmf5usHS');

const market = await KaminoMarket.load(rpc, marketPubkey, 100);
Replace /path/to/your/keypair.json with the actual path to your keypair file. The kUsdcMint address represents the cToken (kV-STKUSDC) that you’ll be redeeming.
3

Get User’s cToken Balance

Query the user’s cToken account to determine how many tokens can be redeemed.
const tokenAccounts = await rpc
  .getTokenAccountsByOwner(signer.address, { mint: kUsdcMint }, { encoding: 'jsonParsed' })
  .send();

if (!tokenAccounts.value.length) {
  throw new Error('No kUSDC token account found');
}

const kUsdcAccount = tokenAccounts.value[0]!;
const kUsdcBalance = new BN(kUsdcAccount.account.data.parsed.info.tokenAmount.amount);

console.log(`Redeeming ${kUsdcBalance.toString()} kUSDC...`);
The getTokenAccountsByOwner method fetches all token accounts owned by your wallet for the specified mint. The balance represents the total amount of cTokens you can redeem.
4

Build Redeem Reserve Collateral Instructions

Generate instructions to redeem cTokens and receive the underlying asset plus interest.
const action = await KaminoAction.buildRedeemReserveCollateralTxns(
  market!,
  kUsdcBalance,
  usdcMint,
  signer,
  new VanillaObligation(PROGRAM_ID),
  undefined
);

const lendingInstructions = [...action.lendingIxs, ...action.cleanupIxs];

if (!lendingInstructions.length) {
  throw new Error('No instructions returned by Kamino SDK');
}
The buildRedeemReserveCollateralTxns method creates instructions to burn your cTokens (kV-STKUSDC) and receive the underlying USDC plus any accrued interest. The redemption amount is calculated based on the current exchange rate.
5

Build and Sign Transaction

Use Kit’s functional pipe pattern to build and sign the transaction with a fresh blockhash.
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(lendingInstructions, tx)
);

const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
6

Send and Confirm Transaction

Send the redemption transaction and wait for confirmation to receive your underlying assets.
const signature = getSignatureFromTransaction(signedTransaction);

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

console.log(`Redemption successful! Signature: ${signature}`);
Once the transaction is confirmed, your cTokens (kV-STKUSDC) will be burned and you’ll receive the underlying asset (USDC) plus any interest earned during the holding period. The USDC will appear in your wallet.