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

# Flash Loans

> Execute a flash loan to borrow assets and repay within a single atomic transaction

## Flash Loans

<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 {
          createSolanaRpc,
          createSolanaRpcSubscriptions,
          address,
          pipe,
          createTransactionMessage,
          setTransactionMessageFeePayerSigner,
          setTransactionMessageLifetimeUsingBlockhash,
          appendTransactionMessageInstructions,
          signTransactionMessageWithSigners,
          sendAndConfirmTransactionFactory,
          getSignatureFromTransaction,
          none,
          getProgramDerivedAddress,
          getAddressEncoder,
        } from '@solana/kit';
        import {
          KaminoMarket,
          PROGRAM_ID,
          getFlashLoanInstructions
        } from '@kamino-finance/klend-sdk';
        import { parseKeypairFile } from '@kamino-finance/klend-sdk/dist/utils/signer.js';
        import { getAddMemoInstruction } from '@solana-program/memo';
        import Decimal from 'decimal.js';
        ```
      </Step>

      <Step>
        ### Setup Market and Signer

        Load your keypair, initialize RPC connections, and load 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'); // Main Market
        const market = await KaminoMarket.load(rpc, marketPubkey, 400);
        ```
      </Step>

      <Step>
        ### Configure Flash Loan Parameters

        Set the token mint, flash loan amount, and derive the user's token account address.

        ```typescript theme={null}
        const usdcMint = address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); // USDC
        const usdcReserve = market!.getReserveByMint(usdcMint)!;

        // Flash loan amount: 1 USDC
        const flashLoanAmount = new Decimal(1_000_000);

        // Derive user's USDC token account (ATA)
        const ASSOCIATED_TOKEN_PROGRAM = address('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
        const TOKEN_PROGRAM = usdcReserve.getLiquidityTokenProgram();

        const addressEncoder = getAddressEncoder();
        const [usdcAta] = await getProgramDerivedAddress({
          programAddress: ASSOCIATED_TOKEN_PROGRAM,
          seeds: [
            addressEncoder.encode(signer.address),
            addressEncoder.encode(TOKEN_PROGRAM),
            addressEncoder.encode(usdcMint)
          ],
        });
        ```
      </Step>

      <Step>
        ### Build Flash Loan Instructions

        Generate the flash borrow and flash repay instructions using the Kamino SDK.

        ```typescript theme={null}
        // Build flash loan instructions
        const lendingMarketAuthority = await market!.getLendingMarketAuthority();

        const { flashBorrowIx, flashRepayIx } = getFlashLoanInstructions({
          borrowIxIndex: 0,
          userTransferAuthority: signer,
          lendingMarketAuthority,
          lendingMarketAddress: market!.getAddress(),
          reserve: usdcReserve,
          amountLamports: flashLoanAmount,
          destinationAta: usdcAta,
          referrerAccount: none(),
          referrerTokenState: none(),
          programId: PROGRAM_ID,
        });
        ```

        <Info>
          The `borrowIxIndex:0 ` parameter specifies that the flash borrow instruction is at index 0 in the transaction. The SDK uses this to validate that repayment occurs in the same transaction.
        </Info>
      </Step>

      <Step>
        ### Add Your Custom Instructions

        Create your custom instructions to execute with the borrowed funds. In this example, we use a simple memo instruction.

        ```typescript theme={null}
        // Create memo instruction
        const memoIx = getAddMemoInstruction({ memo: 'Hello Kamino' });

        // Arrange instructions: flash borrow → your instructions → flash repay
        const allInstructions = [flashBorrowIx, memoIx, flashRepayIx];
        ```

        <Note>
          Replace the memo instruction with your actual business logic.
        </Note>
      </Step>

      <Step>
        ### Build and Send Transaction

        Build the transaction with a fresh blockhash and send it to the network.

        ```typescript theme={null}
        // Get fresh blockhash
        const { value: latestBlockhash } = await rpc
          .getLatestBlockhash({ commitment: 'finalized' })
          .send();

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

        const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);

        const signature = getSignatureFromTransaction(signedTransaction);

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

        console.log(`Flash loan successful! Signature: ${signature}`);
        ```

        <Check>
          Your flash loan transaction is complete! The borrowed funds were used for your operations and automatically repaid within the same atomic transaction.
        </Check>
      </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>
        ### Fetch Reserve Data

        ```rust theme={null}
        use klend_interface::helpers;
        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 spl_associated_token_account::get_associated_token_address;

        let user_token_account = get_associated_token_address(&owner, &reserve.liquidity_mint);
        ```
      </Step>

      <Step>
        ### Build Flash Loan Instructions

        ```rust theme={null}
        let (borrow_ix, repay_ix) = helpers::flash::flash_loan(
            owner,
            &reserve,
            user_token_account, // source for repayment
            user_token_account, // destination for borrowed funds
            1_000_000,          // 1 USDC (6 decimals)
            0,                  // borrow instruction index in the transaction
            None,               // no referrer
        );
        ```

        <Info>
          The `borrow_instruction_index` parameter specifies the position of the flash borrow instruction in the final transaction. Set to `0` if it is the first instruction.
        </Info>
      </Step>

      <Step>
        ### Compose and Send Transaction

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

        // Insert your custom instructions between borrow and repay
        let your_custom_instructions = vec![/* your logic here */];

        let mut all_instructions = vec![borrow_ix];
        all_instructions.extend(your_custom_instructions);
        all_instructions.push(repay_ix);

        let message = Message::new(&all_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!("Flash loan successful! Signature: {signature}");
        ```

        <Note>
          The flash borrow and repay must be in the same transaction. You can insert any number of instructions between them.
        </Note>
      </Step>
    </Steps>
  </Tab>
</Tabs>
