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

# Repay and Withdraw

> Repay borrowed assets and withdraw collateral using the klend-interface Rust crate

## Repay Debt

Repay borrowed assets to improve your position health.

<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"
    ```

    <Note>
      `klend-interface` is a lightweight Rust instruction builder that creates `Vec<Instruction>` with required refresh instructions prepended automatically.
    </Note>
  </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 repay_reserve_pubkey = Pubkey::from_str("FBSyPnxtHKLBZ4UeeUyAnbtFuAmTHLtso9YtsqRDRWpM").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
    )?;
    ```

    <Note>
      `ObligationContext` is the recommended approach for obligation-based operations. It fetches the obligation and its associated reserves, then provides convenient `.deposit()`, `.borrow()`, `.repay()`, and `.withdraw()` methods.
    </Note>
  </Step>

  <Step>
    ### Derive Token Accounts

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

    // User's ATA for the repay token (e.g. USDT)
    let repay_liquidity_mint = Pubkey::from_str("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB").unwrap();
    let user_source_liquidity = get_associated_token_address(&owner, &repay_liquidity_mint);
    ```
  </Step>

  <Step>
    ### Build Instructions

    ```rust theme={null}
    let instructions = ctx.repay(
        owner,
        &repay_reserve_pubkey,
        user_source_liquidity,
        1_000_000, // 1 USDT (6 decimals)
    )?;
    // Returns: [refresh_reserves..., refresh_obligation, repay_obligation_liquidity_v2]
    ```
  </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!("Repay successful! Signature: {signature}");
    ```

    <Info>
      Repaying reduces your debt and improves your loan-to-value (LTV) ratio, making your position healthier and reducing liquidation risk.
    </Info>

    <Check>
      The repay is complete. Your debt has been reduced.
    </Check>
  </Step>
</Steps>

## Withdraw

<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"
    ```

    <Note>
      `klend-interface` is a lightweight Rust instruction builder that creates `Vec<Instruction>` with required refresh instructions prepended automatically.
    </Note>
  </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
    )?;
    ```

    <Note>
      `ObligationContext` is the recommended approach for obligation-based operations. It fetches the obligation and its associated reserves, then provides convenient `.deposit()`, `.borrow()`, `.repay()`, and `.withdraw()` methods.
    </Note>
  </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}");
    ```

    <Check>
      The withdrawal is complete. Your collateral has been returned to your wallet.
    </Check>
  </Step>
</Steps>
