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

# Deposit and Borrow

> Deposit collateral and borrow assets against it

## Deposit Collateral

Deposit assets as collateral to enable borrowing.

<Steps>
  <Step>
    ### Import Dependencies

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

    ```typescript theme={null}
    import {
      createSolanaRpc,
      createSolanaRpcSubscriptions,
      address,
      pipe,
      createTransactionMessage,
      setTransactionMessageFeePayerSigner,
      setTransactionMessageLifetimeUsingBlockhash,
      appendTransactionMessageInstructions,
      signTransactionMessageWithSigners,
      sendAndConfirmTransactionFactory,
      getSignatureFromTransaction,
    } from '@solana/kit';
    import { KaminoMarket, KaminoAction, VanillaObligation, PROGRAM_ID } from '@kamino-finance/klend-sdk';
    import { parseKeypairFile } from '@kamino-finance/klend-sdk/dist/utils/signer.js';
    import BN from 'bn.js';
    ```
  </Step>

  <Step>
    ### Load Signer and Initialize Market

    Load your keypair from a file and initialize RPC connections and the Kamino market.

    ```typescript theme={null}
    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('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
    const market = await KaminoMarket.load(rpc, marketPubkey, 400);
    ```

    <Note>
      Replace `/path/to/your/keypair.json` with the actual path to your keypair file. The `KaminoMarket.load()` method fetches the current market state including all reserve data.
    </Note>
  </Step>

  <Step>
    ### Build Deposit Instructions

    Build deposit instructions for depositing collateral to enable borrowing.

    ```typescript theme={null}
    const usdcMint = address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
    const depositAmount = new BN(3_000_000); // 3 USDC (6 decimals)

    const signatures: string[] = [];

    let depositAction = await KaminoAction.buildDepositTxns(
      market!,
      depositAmount,
      usdcMint,
      signer,
      new VanillaObligation(PROGRAM_ID),
      true,
      undefined,
      1_000_000,
      true,
      false,
      { skipInitialization: false, skipLutCreation: false }
    );

    const hasSetup = (depositAction.setupIxs || []).length > 0;

    let instructions = [
      ...(depositAction.setupIxs || []),
      ...(depositAction.lendingIxs || []),
      ...(depositAction.cleanupIxs || []),
    ];
    ```

    <Info>
      The `buildDepositTxns` method creates instructions to deposit collateral. This enables you to borrow other assets against your deposit.
    </Info>
  </Step>

  <Step>
    ### Send Deposit Transaction with Error Handling

    Send the deposit transaction with automatic retry logic for setup-related errors.

    ```typescript theme={null}
    try {
      const { value: depositBlockhash } = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
      const depositTx = pipe(
        createTransactionMessage({ version: 0 }),
        (tx) => setTransactionMessageFeePayerSigner(signer, tx),
        (tx) => setTransactionMessageLifetimeUsingBlockhash(depositBlockhash, tx),
        (tx) => appendTransactionMessageInstructions(instructions, tx)
      );
      const depositSigned = await signTransactionMessageWithSigners(depositTx);
      const depositSignature = getSignatureFromTransaction(depositSigned);
      signatures.push(depositSignature);

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

      console.log(`Deposit successful! Signature: ${depositSignature}`);
    } catch (error: any) {
      const errorMsg = error?.message || error?.toString() || '';
      const is0x17a3 =
        errorMsg.includes('0x17a3') || errorMsg.includes('6051') || errorMsg.includes('IncorrectInstructionInPosition');

      if (hasSetup && is0x17a3) {
        await new Promise((resolve) => setTimeout(resolve, 2000));

        const reloadedMarket = await KaminoMarket.load(rpc, marketPubkey, 400);

        depositAction = await KaminoAction.buildDepositTxns(
          reloadedMarket!,
          depositAmount,
          usdcMint,
          signer,
          new VanillaObligation(PROGRAM_ID),
          true,
          undefined,
          1_000_000,
          true,
          false,
          { skipInitialization: false, skipLutCreation: false }
        );

        instructions = [
          ...(depositAction.setupIxs || []),
          ...(depositAction.lendingIxs || []),
          ...(depositAction.cleanupIxs || []),
        ];

        const { value: retryBlockhash } = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
        const retryTx = pipe(
          createTransactionMessage({ version: 0 }),
          (tx) => setTransactionMessageFeePayerSigner(signer, tx),
          (tx) => setTransactionMessageLifetimeUsingBlockhash(retryBlockhash, tx),
          (tx) => appendTransactionMessageInstructions(instructions, tx)
        );
        const retrySigned = await signTransactionMessageWithSigners(retryTx);
        const retrySignature = getSignatureFromTransaction(retrySigned);
        signatures.push(retrySignature);

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

        console.log(
          `Deposit successful! Signature: ${retrySignature}\nSetup transaction: https://solscan.io/tx/${signatures[0]}`
        );
      } else {
        console.error('Deposit failed:', error);
      }
    }
    ```

    <Warning>
      When setup instructions are included, the first transaction may fail with error 0x17a3. The retry logic handles this by waiting for blockchain state to settle, reloading the market, and rebuilding instructions.
    </Warning>

    <Check>
      Once the deposit transaction is confirmed, your collateral is deposited and you can now borrow assets against it. An obligation is created to track your position.
    </Check>
  </Step>
</Steps>

## Borrow Assets

Borrow assets against your deposited collateral.

<Steps>
  <Step>
    ### Import Dependencies

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

    ```typescript theme={null}
    import {
      createSolanaRpc,
      createSolanaRpcSubscriptions,
      address,
      pipe,
      createTransactionMessage,
      setTransactionMessageFeePayerSigner,
      setTransactionMessageLifetimeUsingBlockhash,
      appendTransactionMessageInstructions,
      signTransactionMessageWithSigners,
      sendAndConfirmTransactionFactory,
      getSignatureFromTransaction,
    } from '@solana/kit';
    import { KaminoMarket, KaminoAction, VanillaObligation, PROGRAM_ID } from '@kamino-finance/klend-sdk';
    import { parseKeypairFile } from '@kamino-finance/klend-sdk/dist/utils/signer.js';
    import BN from 'bn.js';
    ```
  </Step>

  <Step>
    ### Load Signer and Initialize Market

    Load your keypair from a file and initialize RPC connections and the Kamino market.

    ```typescript theme={null}
    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('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
    const market = await KaminoMarket.load(rpc, marketPubkey, 400);
    ```

    <Note>
      Replace `/path/to/your/keypair.json` with the actual path to your keypair file. The `KaminoMarket.load()` method fetches the current market state including all reserve data.
    </Note>
  </Step>

  <Step>
    ### Check for Existing Obligation

    Verify that an obligation exists before attempting to borrow.

    ```typescript theme={null}
    const existingObligation = await market!.getObligationByWallet(signer.address, new VanillaObligation(PROGRAM_ID));

    if (!existingObligation) {
      throw new Error('No existing obligation found. Please deposit collateral first.');
    }
    ```

    <Warning>
      You must have an existing obligation with deposited collateral before you can borrow. If you haven't deposited collateral yet, do that first.
    </Warning>
  </Step>

  <Step>
    ### Build Borrow Instructions

    Generate borrow instructions for the specified token and amount.

    ```typescript theme={null}
    const usdtMint = address('Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB');
    const borrowAmount = new BN(1_000_000); // 1.00 USDT (6 decimals)

    const borrowAction = await KaminoAction.buildBorrowTxns(
      market!,
      borrowAmount,
      usdtMint,
      signer,
      new VanillaObligation(PROGRAM_ID),
      true,
      undefined,
      1_000_000,
      true,
      false
    );

    const allInstructions = [
      ...(borrowAction.setupIxs || []),
      ...(borrowAction.lendingIxs || []),
      ...(borrowAction.cleanupIxs || []),
    ];
    ```

    <Info>
      The `buildBorrowTxns` method creates borrow instructions that withdraw assets from the reserve pool to your wallet. The amount borrowed is added to your debt obligation.
    </Info>
  </Step>

  <Step>
    ### Build and Sign Transaction

    Use Kit's functional pipe pattern to build and sign the transaction with a fresh blockhash.

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

  <Step>
    ### Send and Confirm Transaction

    Send the borrow transaction and wait for confirmation.

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

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

    console.log('Borrow successful! Signature:', signature);
    ```

    <Check>
      Once the borrow transaction is confirmed, the borrowed assets are transferred to your wallet. You now have a debt obligation that accrues interest. Monitor your loan-to-value ratio to avoid liquidation.
    </Check>
  </Step>
</Steps>
