> ## 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.

# Withdraw

> Withdraw liquidity or collateral

Withdraw liquidity or collateral from the reserve. The SDK handles transaction building, instruction creation, and collateral release calculations.

## Withdraw for Lending

Withdraw liquidity from the reserve.

<Tabs>
  <Tab title="TypeScript">
    <Steps>
      <Step>
        ### Import Dependencies

        Import the required packages for Solana RPC communication, Kamino SDK operations, and Kit transaction building.

        ```typescript theme={null}
        import "dotenv/config";
        import {
        	createSolanaRpc,
        	createSolanaRpcSubscriptions,
        	address,
        	pipe,
        	createTransactionMessage,
        	setTransactionMessageFeePayerSigner,
        	setTransactionMessageLifetimeUsingBlockhash,
        	appendTransactionMessageInstructions,
        	signTransactionMessageWithSigners,
        	sendAndConfirmTransactionFactory,
        	getSignatureFromTransaction,
        } from "@solana/kit";
        import {
        	KaminoMarket,
        	KaminoAction,
        	VanillaObligation,
        	PROGRAM_ID,
        	DEFAULT_RECENT_SLOT_DURATION_MS,
        } from "@kamino-finance/klend-sdk";
        import BN from "bn.js";
        import { getKeypair } from "../../utils/keypair";
        ```

        <Note>
          `@solana/kit` provides modern utilities for RPC, transaction building, and
          signing. `@kamino-finance/klend-sdk` contains market operation methods.
        </Note>
      </Step>

      <Step>
        ### Initialize RPC and Load Market

        Initialize the RPC connection and load the Kamino market instance.

        ```typescript theme={null}
        const signer = await getKeypair();
        const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
        const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.mainnet-beta.solana.com");
        const marketPubkey = address("DxXdAyU3kCjnyggvHmY5nAwg5cRbbmdyX3npfDMjjMek");
        const market = await KaminoMarket.load(rpc, marketPubkey, DEFAULT_RECENT_SLOT_DURATION_MS);
        ```

        <Note>
          `KaminoMarket.load()` fetches the current market state including all reserve
          data and configuration.
        </Note>
      </Step>

      <Step>
        ### Build Withdraw Reserve Liquidity Instructions

        Fetch the existing obligation from the blockchain and build withdraw instructions.

        ```typescript theme={null}
        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");
        }
        ```
      </Step>

      <Step>
        ### Build and Sign Transaction

        Use Kit's functional pipe pattern to build and sign the transaction.

        ```typescript theme={null}
        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
        );
        ```

        <Note>
          Kit's `pipe` function enables functional composition of transaction building
          steps for cleaner, more maintainable code.
        </Note>
      </Step>

      <Step>
        ### Send and Confirm Transaction

        Send the transaction and confirm it using WebSocket.

        ```typescript theme={null}
        const signature = getSignatureFromTransaction(signedTransaction);

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

        console.log("Withdrawal successful! Signature:", signature);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Rust">
    <Info>
      `klend-interface` is a lightweight Rust instruction builder — it creates `Vec<Instruction>` with required refresh instructions prepended automatically. Use `ReserveInfo::from_account_data(pubkey, &data)` to construct reserve info from raw RPC account bytes. For simple lending withdrawals (no obligation), use `helpers::withdraw::redeem()` to redeem cTokens for the underlying liquidity plus accrued interest.
    </Info>

    <Steps>
      <Step>
        ### Add Dependencies

        ```toml theme={null}
        [dependencies]
        klend-interface = "0.1.0"
        solana-pubkey = "2.1"
        solana-instruction = "2.1"
        solana-sdk = "~2.3"
        solana-client = "~2.3"
        spl-token = "7"
        spl-associated-token-account = "6"
        ```
      </Step>

      <Step>
        ### Set Up RPC Client

        ```rust theme={null}
        use solana_client::rpc_client::RpcClient;
        use solana_sdk::signer::keypair::read_keypair_file;
        use solana_sdk::signer::Signer;

        let rpc_client = RpcClient::new("https://api.mainnet-beta.solana.com");
        let signer = read_keypair_file("/path/to/your/keypair.json")
            .expect("Failed to read keypair file");
        let owner = signer.pubkey();
        ```
      </Step>

      <Step>
        ### Fetch Reserve Data

        ```rust theme={null}
        use klend_interface::ReserveInfo;
        use solana_pubkey::Pubkey;
        use std::str::FromStr;

        let reserve_pubkey = Pubkey::from_str("D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59").unwrap();

        let reserve_data = rpc_client.get_account(&reserve_pubkey)?;
        let reserve = ReserveInfo::from_account_data(reserve_pubkey, &reserve_data.data)?;
        ```
      </Step>

      <Step>
        ### Derive Token Accounts

        ```rust theme={null}
        use klend_interface::pda;
        use klend_interface::KLEND_PROGRAM_ID;
        use spl_associated_token_account::get_associated_token_address;

        // User's ATA for the underlying token (e.g. USDC)
        let user_destination_liquidity = get_associated_token_address(&owner, &reserve.liquidity_mint);

        // User's ATA for the cToken (collateral token received when depositing)
        let (collateral_mint, _) = pda::reserve_collateral_mint(&KLEND_PROGRAM_ID, &reserve_pubkey);
        let user_source_collateral = get_associated_token_address(&owner, &collateral_mint);
        ```
      </Step>

      <Step>
        ### Build Instructions

        ```rust theme={null}
        use klend_interface::helpers;

        let collateral_amount = 1_000_000; // amount of cTokens to redeem

        let instructions = helpers::withdraw::redeem(
            owner,
            &reserve,
            user_source_collateral,     // cToken account (burned)
            user_destination_liquidity, // receives underlying tokens + interest
            collateral_amount,
        );
        // Returns: [refresh_reserve, redeem_reserve_collateral]
        ```

        <Note>
          Use `ObligationContext::withdraw()` if you need to withdraw collateral from an obligation (borrowing flow).
        </Note>
      </Step>

      <Step>
        ### Build and Send Transaction

        ```rust theme={null}
        use solana_sdk::transaction::Transaction;
        use solana_sdk::message::Message;

        let message = Message::new(&instructions, Some(&owner));
        let recent_blockhash = rpc_client.get_latest_blockhash()?;
        let tx = Transaction::new(&[&signer], message, recent_blockhash);
        let signature = rpc_client.send_and_confirm_transaction(&tx)?;
        println!("Redeem successful! Signature: {signature}");
        ```
      </Step>
    </Steps>

    <a href="https://github.com/Kamino-Finance/klend/blob/master/libs/klend-interface/examples/redeem_ctokens.rs" target="_blank" rel="noopener noreferrer" class="github-link">
      <Icon icon="github" iconType="brands" size={16} />

      <span>View Code</span>
    </a>
  </Tab>
</Tabs>

## Withdraw for Borrowing

Withdraw collateral from an obligation.

<Tabs>
  <Tab title="TypeScript">
    <Steps>
      <Step>
        ### Import Dependencies

        Import the required packages for Solana RPC communication, Kamino SDK operations, and Kit transaction building.

        ```typescript theme={null}
        import "dotenv/config";
        import {
        	createSolanaRpc,
        	createSolanaRpcSubscriptions,
        	address,
        	pipe,
        	createTransactionMessage,
        	setTransactionMessageFeePayerSigner,
        	setTransactionMessageLifetimeUsingBlockhash,
        	appendTransactionMessageInstructions,
        	signTransactionMessageWithSigners,
        	sendAndConfirmTransactionFactory,
        	getSignatureFromTransaction,
        } from "@solana/kit";
        import {
        	KaminoMarket,
        	KaminoAction,
        	VanillaObligation,
        	PROGRAM_ID,
        	DEFAULT_RECENT_SLOT_DURATION_MS,
        } from "@kamino-finance/klend-sdk";
        import BN from "bn.js";
        import { getKeypair } from "../../utils/keypair";
        ```

        <Note>
          `@solana/kit` provides modern utilities for RPC, transaction building, and
          signing. `@kamino-finance/klend-sdk` contains market operation methods.
        </Note>
      </Step>

      <Step>
        ### Initialize RPC and Load Market

        Initialize the RPC connection and load the Kamino market instance.

        ```typescript theme={null}
        const signer = await getKeypair();
        const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
        const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.mainnet-beta.solana.com");
        const marketPubkey = address("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
        const market = await KaminoMarket.load(rpc, marketPubkey, DEFAULT_RECENT_SLOT_DURATION_MS);
        ```

        <Note>
          `KaminoMarket.load()` fetches the current market state including all reserve
          data and configuration.
        </Note>
      </Step>

      <Step>
        ### Build Withdraw Collateral Instructions

        Build withdraw instructions for collateral withdrawal.

        ```typescript theme={null}
        const usdcMint = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
        const withdrawAmount = new BN(1_000_000); // 1 USDC (6 decimals)

        const withdrawAction = await KaminoAction.buildWithdrawTxns(
        	market!,
        	withdrawAmount,
        	usdcMint,
        	signer,
        	new VanillaObligation(PROGRAM_ID),
        	true, // useV2Ixs
        	undefined, // scopeRefreshConfig
        	1_000_000, // extraComputeBudget
        	true, // includeAtaIxs
        	false // requestElevationGroup
        );

        // Combine all instructions
        const allInstructions = [
        	...(withdrawAction.setupIxs || []),
        	...(withdrawAction.lendingIxs || []),
        	...(withdrawAction.cleanupIxs || []),
        ];
        ```
      </Step>

      <Step>
        ### Build and Sign Transaction

        Use Kit's functional pipe pattern to build and sign the transaction.

        ```typescript theme={null}
        // 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
        );
        ```
      </Step>

      <Step>
        ### Send and Confirm Transaction

        Send the transaction and confirm it using WebSocket.

        ```typescript theme={null}
        const signature = getSignatureFromTransaction(signedTransaction);

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

        console.log("Withdrawal successful! Signature:", signature);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Rust">
    <Info>
      `klend-interface` is a lightweight Rust instruction builder — it creates `Vec<Instruction>` with required refresh instructions prepended automatically. Use `ReserveInfo::from_account_data(pubkey, &data)` to construct reserve info from raw RPC account bytes. For obligation-based operations, `ObligationContext` is the recommended approach — it fetches the obligation and its associated reserves, then provides convenient `.deposit()`, `.borrow()`, `.repay()`, and `.withdraw()` methods.
    </Info>

    <Steps>
      <Step>
        ### Add Dependencies

        ```toml theme={null}
        [dependencies]
        klend-interface = "0.1.0"
        solana-pubkey = "2.1"
        solana-instruction = "2.1"
        solana-sdk = "~2.3"
        solana-client = "~2.3"
        spl-token = "7"
        spl-associated-token-account = "6"
        ```
      </Step>

      <Step>
        ### Set Up RPC Client

        ```rust theme={null}
        use solana_client::rpc_client::RpcClient;
        use solana_sdk::signer::keypair::read_keypair_file;
        use solana_sdk::signer::Signer;

        let rpc_client = RpcClient::new("https://api.mainnet-beta.solana.com");
        let signer = read_keypair_file("/path/to/your/keypair.json")
            .expect("Failed to read keypair file");
        let owner = signer.pubkey();
        ```
      </Step>

      <Step>
        ### Build Obligation Context

        ```rust theme={null}
        use klend_interface::ObligationContext;
        use klend_interface::pda;
        use klend_interface::KLEND_PROGRAM_ID;
        use solana_pubkey::Pubkey;
        use std::str::FromStr;

        let lending_market = Pubkey::from_str("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF").unwrap();
        let reserve_pubkey = Pubkey::from_str("D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59").unwrap();

        // Derive the obligation PDA
        let (obligation_pubkey, _) = pda::obligation(
            &KLEND_PROGRAM_ID, 0, 0, &owner, &lending_market,
            &Pubkey::default(), &Pubkey::default(),
        );

        // Fetch the obligation account
        let obligation_data = rpc_client.get_account(&obligation_pubkey)?;

        // Discover which reserves the obligation references
        let reserve_addrs = ObligationContext::reserve_addresses_for_obligation(&obligation_data.data)?;

        // Fetch all reserve accounts in one RPC call
        let reserve_accounts = rpc_client.get_multiple_accounts(&reserve_addrs)?;

        // Build the context
        let reserves: Vec<(Pubkey, &[u8])> = reserve_addrs.iter()
            .zip(reserve_accounts.iter())
            .filter_map(|(addr, acc)| acc.as_ref().map(|a| (*addr, a.data.as_slice())))
            .collect();
        let ctx = ObligationContext::from_account_data(
            obligation_pubkey, &obligation_data.data, &reserves
        )?;
        ```
      </Step>

      <Step>
        ### Derive Token Accounts

        ```rust theme={null}
        use spl_associated_token_account::get_associated_token_address;

        // User's ATA for the withdrawal token (e.g. USDC)
        let liquidity_mint = Pubkey::from_str("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v").unwrap();
        let user_dest_liquidity = get_associated_token_address(&owner, &liquidity_mint);
        ```
      </Step>

      <Step>
        ### Build Instructions

        ```rust theme={null}
        let instructions = ctx.withdraw(
            owner,
            &reserve_pubkey,
            user_dest_liquidity,
            1_000_000, // 1 USDC (6 decimals)
        )?;
        // Returns: [refresh_reserves..., refresh_obligation, withdraw_and_redeem]
        ```

        <Note>
          Use `helpers::withdraw::redeem()` if you hold cTokens without an obligation — see the [Withdraw for Lending](/docs/build/developers/borrow/operations/withdraw#withdraw-for-lending) tab.
        </Note>
      </Step>

      <Step>
        ### Build and Send Transaction

        ```rust theme={null}
        use solana_sdk::transaction::Transaction;
        use solana_sdk::message::Message;

        let message = Message::new(&instructions, Some(&owner));
        let recent_blockhash = rpc_client.get_latest_blockhash()?;
        let tx = Transaction::new(&[&signer], message, recent_blockhash);
        let signature = rpc_client.send_and_confirm_transaction(&tx)?;
        println!("Withdrawal successful! Signature: {signature}");
        ```
      </Step>
    </Steps>

    <a href="https://github.com/Kamino-Finance/klend/blob/master/libs/klend-interface/examples/withdraw_obligation.rs" target="_blank" rel="noopener noreferrer" class="github-link">
      <Icon icon="github" iconType="brands" size={16} />

      <span>View Code</span>
    </a>
  </Tab>
</Tabs>

<Accordion title="What Happens When You Withdraw Collateral?">
  1. The collateral amount is removed from your obligation
  2. Your borrowing capacity decreases
  3. Your loan-to-value (LTV) ratio increases
</Accordion>
