# Deposit and Withdraw First-Loss Capital This tutorial shows you how to deposit and withdraw first-loss capital from a [LoanBroker](/docs/references/protocol/ledger-data/ledger-entry-types/loanbroker) on the XRP Ledger. First-loss capital helps protect vault depositor's assets, acting as a buffer in the event of loan defaults. The tutorial demonstrates how a loan broker can manage risk by depositing XRP as first-loss capital, and how they can withdraw it when needed. LendingProtocol ## Goals By the end of this tutorial, you will be able to: - Deposit an MPT as first-loss capital into a `LoanBroker` entry. - Check the available cover balance in the loan broker's pseudo-account. - Withdraw first-loss capital from a `LoanBroker` entry. ## Prerequisites To complete this tutorial, you should: - Have a basic understanding of the XRP Ledger. - Have an XRP Ledger client library set up in your development environment. This page provides examples for the following: - **JavaScript** with the [xrpl.js library](https://github.com/XRPLF/xrpl.js). See [Get Started Using JavaScript](/docs/tutorials/javascript/build-apps/get-started) for setup steps. ## Source Code You can find the complete source code for this tutorial's examples in the code samples section of this website's repository. ## Steps ### 1. Install dependencies JavaScript From the code sample folder, use npm to install dependencies: ```bash npm install xrpl ``` ### 2. Set up client and accounts To get started, import the necessary libraries and instantiate a client to connect to the XRPL. This example imports: - `xrpl`: Used for XRPL client connection and transaction handling. - `fs` and `child_process`: Used to run tutorial set up scripts. JavaScript // IMPORTANT: This example deposits and withdraws first-loss capital from a // preconfigured LoanBroker entry. import fs from 'fs' import { execSync } from 'child_process' import xrpl from 'xrpl' // Connect to the network ---------------------- const client = new xrpl.Client('wss://s.devnet.rippletest.net:51233') await client.connect() Next, load the loan broker account, loan broker ID, and MPT issuance ID. JavaScript // This step checks for the necessary setup data to run the lending protocol tutorials. // If missing, lendingSetup.js will generate the data. if (!fs.existsSync('lendingSetup.json')) { console.log(`\n=== Lending tutorial data doesn't exist. Running setup script... ===\n`) execSync('node lendingSetup.js', { stdio: 'inherit' }) } // Load preconfigured accounts and LoanBrokerID. const setupData = JSON.parse(fs.readFileSync('lendingSetup.json', 'utf8')) // You can replace these values with your own const loanBroker = xrpl.Wallet.fromSeed(setupData.loanBroker.seed) const loanBrokerID = setupData.loanBrokerID const mptID = setupData.mptID console.log(`\nLoan broker address: ${loanBroker.address}`) console.log(`LoanBrokerID: ${loanBrokerID}`) console.log(`MPT ID: ${mptID}`) This example uses preconfigured accounts and loan broker data from the `lendingSetup.js` script, but you can replace `loanBroker`, `loanBrokerID`, and `mptID` with your own values. ### 3. Prepare LoanBrokerCoverDeposit transaction Create the [LoanBrokerCoverDeposit transaction](/docs/references/protocol/transactions/types/loanbrokercoverdeposit) object: JavaScript // Prepare LoanBrokerCoverDeposit transaction ---------------------- console.log(`\n=== Preparing LoanBrokerCoverDeposit transaction ===\n`) const coverDepositTx = { TransactionType: 'LoanBrokerCoverDeposit', Account: loanBroker.address, LoanBrokerID: loanBrokerID, Amount: { mpt_issuance_id: mptID, value: '2000' } } // Validate the transaction structure before submitting xrpl.validate(coverDepositTx) console.log(JSON.stringify(coverDepositTx, null, 2)) The `Amount` field specifies the MPT and amount to deposit as first-loss capital. If the transaction succeeds, the amount is deposited and held in the pseudo-account associated with the `LoanBroker` entry. ### 4. Submit LoanBrokerCoverDeposit transaction Sign and submit the `LoanBrokerCoverDeposit` transaction to the XRP Ledger. JavaScript // Sign, submit, and wait for deposit validation ---------------------- console.log(`\n=== Submitting LoanBrokerCoverDeposit transaction ===\n`) const depositResponse = await client.submitAndWait(coverDepositTx, { wallet: loanBroker, autofill: true }) if (depositResponse.result.meta.TransactionResult !== 'tesSUCCESS') { const resultCode = depositResponse.result.meta.TransactionResult console.error('Error: Unable to deposit cover:', resultCode) await client.disconnect() process.exit(1) } console.log('Cover deposit successful!') Verify that the transaction succeeded by checking for a `tesSUCCESS` result code. ### 5. Check cover balance after deposit Retrieve the cover balance from the transaction result by checking the `LoanBroker` entry in the transaction metadata. JavaScript // Extract cover balance from the transaction result console.log(`\n=== Cover Balance ===\n`) let loanBrokerNode = depositResponse.result.meta.AffectedNodes.find(node => node.ModifiedNode?.LedgerEntryType === 'LoanBroker' ) // First-loss capital is stored in the LoanBroker's pseudo-account. console.log(`LoanBroker Pseudo-Account: ${loanBrokerNode.ModifiedNode.FinalFields.Account}`) console.log(`Cover balance after deposit: ${loanBrokerNode.ModifiedNode.FinalFields.CoverAvailable} TSTUSD`) The `LoanBroker` pseudo-account address is the `Account` field, and `CoverAvailable` shows the cover balance. ### 6. Prepare LoanBrokerCoverWithdraw transaction Create the [LoanBrokerCoverWithdraw transaction](/docs/references/protocol/transactions/types/loanbrokercoverwithdraw) object: JavaScript // Prepare LoanBrokerCoverWithdraw transaction ---------------------- console.log(`\n=== Preparing LoanBrokerCoverWithdraw transaction ===\n`) const coverWithdrawTx = { TransactionType: 'LoanBrokerCoverWithdraw', Account: loanBroker.address, LoanBrokerID: loanBrokerID, Amount: { mpt_issuance_id: mptID, value: '1000' } } // Validate the transaction structure before submitting xrpl.validate(coverWithdrawTx) console.log(JSON.stringify(coverWithdrawTx, null, 2)) ### 7. Submit LoanBrokerCoverWithdraw transaction Sign and submit the `LoanBrokerCoverWithdraw` transaction to the XRP Ledger. JavaScript // Sign, submit, and wait for withdraw validation ---------------------- console.log(`\n=== Submitting LoanBrokerCoverWithdraw transaction ===\n`) const withdrawResponse = await client.submitAndWait(coverWithdrawTx, { wallet: loanBroker, autofill: true }) if (withdrawResponse.result.meta.TransactionResult !== 'tesSUCCESS') { const resultCode = withdrawResponse.result.meta.TransactionResult console.error('Error: Unable to withdraw cover:', resultCode) await client.disconnect() process.exit(1) } console.log('Cover withdraw successful!') Verify that the transaction succeeded by checking for a `tesSUCCESS` result code. ### 8. Check cover balance after withdrawal Retrieve the updated cover balance from the transaction result. JavaScript // Extract updated cover balance from the transaction result console.log(`\n=== Updated Cover Balance ===\n`) loanBrokerNode = withdrawResponse.result.meta.AffectedNodes.find(node => node.ModifiedNode?.LedgerEntryType === 'LoanBroker' ) console.log(`LoanBroker Pseudo-Account: ${loanBrokerNode.ModifiedNode.FinalFields.Account}`) console.log(`Cover balance after withdraw: ${loanBrokerNode.ModifiedNode.FinalFields.CoverAvailable} TSTUSD`) await client.disconnect() The `CoverAvailable` field now shows the reduced balance after the withdrawal. ## See Also **Concepts**: - [Lending Protocol](/docs/concepts/tokens/lending-protocol) **Tutorials**: - [Create a Loan Broker](/docs/tutorials/how-tos/set-up-lending/use-the-lending-protocol/create-a-loan-broker) **References**: - [LoanBrokerCoverDeposit transaction](/docs/references/protocol/transactions/types/loanbrokercoverdeposit) - [LoanBrokerCoverWithdraw transaction](/docs/references/protocol/transactions/types/loanbrokercoverwithdraw)