# Claw Back First-Loss Capital

This tutorial shows you how to claw back tokens from a [LoanBroker](/docs/references/protocol/ledger-data/ledger-entry-types/loanbroker) on the XRP Ledger. The clawback feature enables token issuers (Multi-Purpose or Trust Line) to meet regulatory standards and claw back funds even if those funds have been deposited as [first-loss capital](/es-es/docs/concepts/tokens/lending-protocol#risk-management).

LendingProtocol
## Goals

By the end of this tutorial, you will be able to:

- Deposit an MPT as first-loss capital into a `LoanBroker` entry.
- Verify the MPT issuer.
- Claw back all first-loss capital from the `LoanBroker` entry.
- Check the cover available for the `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/get-started/get-started-javascript) for setup steps.
  - **Python** with the [xrpl-py library](https://github.com/XRPLF/xrpl-py). See [Get Started Using Python](/docs/tutorials/get-started/get-started-python) for setup steps.
  - **Go** with the [xrpl-go library](https://github.com/XRPLF/xrpl-go). See [Get Started Using Go](/docs/tutorials/get-started/get-started-go) 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
```

Python
From the code sample folder, set up a virtual environment and use `pip` to install dependencies.


```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

Go
From the code sample folder, use `go` to install dependencies.


```bash
go mod tidy
```

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

JavaScript
- `xrpl`: Used for XRPL client connection, transaction submission, and wallet handling.
- `fs` and `child_process`: Used to run tutorial set up scripts.



```js
// IMPORTANT: This example deposits and claws back first-loss capital from a
// preconfigured LoanBroker entry. The first-loss capital is an MPT
// with clawback enabled.

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()
```

Python
- `xrpl`: Used for XRPL client connection, transaction submission, and wallet handling.
- `json`: Used for loading and formatting JSON data.
- `os`, `subprocess`, and `sys`: Used to run tutorial set up scripts.



```py
# IMPORTANT: This example deposits and claws back first-loss capital from a
# preconfigured LoanBroker entry. The first-loss capital is an MPT
# with clawback enabled.

import json
import os
import subprocess
import sys

from xrpl.clients import JsonRpcClient
from xrpl.models import LedgerEntry, LoanBrokerCoverClawback, LoanBrokerCoverDeposit, MPTAmount
from xrpl.transaction import submit_and_wait
from xrpl.wallet import Wallet

# Set up client ----------------------
client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
```

Go
- `xrpl-go`: Used for XRPL client connection, transaction submission, and wallet handling.
- `encoding/json` and `fmt`: Used for formatting and printing results to the console.
- `os` and `os/exec`: Used to run tutorial set up scripts.



```go
// IMPORTANT: This example deposits and claws back first-loss capital from a
// preconfigured LoanBroker entry. The first-loss capital is an MPT
// with clawback enabled.

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"

	"github.com/Peersyst/xrpl-go/xrpl/queries/common"
	"github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
	"github.com/Peersyst/xrpl-go/xrpl/transaction"
	"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
	"github.com/Peersyst/xrpl-go/xrpl/wallet"
	"github.com/Peersyst/xrpl-go/xrpl/websocket"
	wstypes "github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)

// mptIssuanceEntryRequest looks up an MPTIssuance ledger entry by its MPT ID.
// The library's GetLedgerEntry() method only supports lookup by ledger entry ID,
// so this custom type is used with the generic Request() method.
type mptIssuanceEntryRequest struct {
	common.BaseRequest
	MPTIssuance string                 `json:"mpt_issuance"`
	LedgerIndex common.LedgerSpecifier `json:"ledger_index,omitempty"`
}

func (*mptIssuanceEntryRequest) Method() string  { return "ledger_entry" }
func (*mptIssuanceEntryRequest) Validate() error { return nil }
func (*mptIssuanceEntryRequest) APIVersion() int { return 2 }

func main() {
	// Connect to the network ----------------------
	client := websocket.NewClient(
		websocket.NewClientConfig().
			WithHost("wss://s.devnet.rippletest.net:51233"),
	)
	defer client.Disconnect()

	if err := client.Connect(); err != nil {
		panic(err)
	}
```

Next, load the loan broker account, MPT issuer account, loan broker ID, and MPT ID.

JavaScript

```js
// 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 mptIssuer = xrpl.Wallet.fromSeed(setupData.depositor.seed)
const loanBrokerID = setupData.loanBrokerID
const mptID = setupData.mptID

console.log(`\nLoan broker address: ${loanBroker.address}`)
console.log(`MPT issuer address: ${mptIssuer.address}`)
console.log(`LoanBrokerID: ${loanBrokerID}`)
console.log(`MPT ID: ${mptID}`)
```

This example uses preconfigured accounts, MPTs, and loan broker data from the `lendingSetup.js` script, but you can replace `loanBroker`, `mptIssuer`, `loanBrokerID`, and `mptID` with your own values.

Python

```py
# This step checks for the necessary setup data to run the lending protocol tutorials.
# If missing, lending_setup.py will generate the data.
if not os.path.exists("lending_setup.json"):
    print("\n=== Lending tutorial data doesn't exist. Running setup script... ===\n")
    subprocess.run([sys.executable, "lending_setup.py"], check=True)

# Load preconfigured accounts, loan_broker_id, and mpt_id.
with open("lending_setup.json") as f:
    setup_data = json.load(f)

# You can replace these values with your own.
loan_broker = Wallet.from_seed(setup_data["loan_broker"]["seed"])
mpt_issuer = Wallet.from_seed(setup_data["depositor"]["seed"])
loan_broker_id = setup_data["loan_broker_id"]
mpt_id = setup_data["mpt_id"]

print(f"\nLoan broker address: {loan_broker.address}")
print(f"MPT issuer address: {mpt_issuer.address}")
print(f"LoanBrokerID: {loan_broker_id}")
print(f"MPT ID: {mpt_id}")
```

This example uses preconfigured accounts, MPTs, and loan broker data from the `lending_setup.py` script, but you can replace `loan_broker`, `mpt_issuer`, `loan_broker_id`, and `mpt_id` with your own values.

Go

```go
	// Check for setup data; run lending-setup if missing
	if _, err := os.Stat("lending-setup.json"); os.IsNotExist(err) {
		fmt.Printf("\n=== Lending tutorial data doesn't exist. Running setup script... ===\n\n")
		cmd := exec.Command("go", "run", "./lending-setup")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			panic(err)
		}
	}

	// Load preconfigured accounts and LoanBrokerID
	data, err := os.ReadFile("lending-setup.json")
	if err != nil {
		panic(err)
	}
	var setup map[string]any
	if err := json.Unmarshal(data, &setup); err != nil {
		panic(err)
	}

	// You can replace these values with your own
	loanBrokerWallet, err := wallet.FromSecret(setup["loanBroker"].(map[string]any)["seed"].(string))
	if err != nil {
		panic(err)
	}
	mptIssuerWallet, err := wallet.FromSecret(setup["depositor"].(map[string]any)["seed"].(string))
	if err != nil {
		panic(err)
	}
	loanBrokerID := setup["loanBrokerID"].(string)
	mptID := setup["mptID"].(string)

	fmt.Printf("\nLoan broker address: %s\n", loanBrokerWallet.ClassicAddress)
	fmt.Printf("MPT issuer address: %s\n", mptIssuerWallet.ClassicAddress)
	fmt.Printf("LoanBrokerID: %s\n", loanBrokerID)
	fmt.Printf("MPT ID: %s\n", mptID)
```

This example uses preconfigured accounts, MPTs, and loan broker data from the `lending-setup` script, but you can replace `loanBrokerWallet`, `mptIssuerWallet`, `loanBrokerID`, and `mptID` with your own values.

### 3. Check initial cover available

Check the initial cover (first-loss capital) available using the [ledger_entry method](/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry).

JavaScript

```js
// Check cover available ----------------------
console.log(`\n=== Cover Available ===\n`)
const coverInfo = await client.request({
  command: 'ledger_entry',
  index: loanBrokerID,
  ledger_index: 'validated'
})

let currentCoverAvailable = coverInfo.result.node.CoverAvailable || '0'
console.log(`${currentCoverAvailable} TSTUSD`)
```

Python

```py
# Check cover available ----------------------
print("\n=== Cover Available ===\n")
cover_info = client.request(LedgerEntry(
    index=loan_broker_id,
    ledger_index="validated",
))

current_cover_available = cover_info.result["node"].get("CoverAvailable", "0")
print(f"{current_cover_available} TSTUSD")
```

Go

```go
	// Check cover available ----------------------
	fmt.Printf("\n=== Cover Available ===\n\n")
	coverInfo, err := client.GetLedgerEntry(&ledger.EntryRequest{
		Index:       loanBrokerID,
		LedgerIndex: common.Validated,
	})
	if err != nil {
		panic(err)
	}

	currentCoverAvailable := "0"
	if ca, ok := coverInfo.Node["CoverAvailable"].(string); ok {
		currentCoverAvailable = ca
	}
	fmt.Printf("%s TSTUSD\n", currentCoverAvailable)
```

If the `CoverAvailable` field is missing, it means no first-loss capital has been deposited.

### 4. Prepare LoanBrokerCoverDeposit transaction

Create the [LoanBrokerCoverDeposit transaction](/docs/references/protocol/transactions/types/loanbrokercoverdeposit) object.

JavaScript

```js
// 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: '1000'
  }
}

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

Python

```py
# Prepare LoanBrokerCoverDeposit transaction ----------------------
print("\n=== Preparing LoanBrokerCoverDeposit transaction ===\n")
cover_deposit_tx = LoanBrokerCoverDeposit(
    account=loan_broker.address,
    loan_broker_id=loan_broker_id,
    amount=MPTAmount(mpt_issuance_id=mpt_id, value="1000"),
)

print(json.dumps(cover_deposit_tx.to_xrpl(), indent=2))
```

The `amount` field specifies the MPT and amount to deposit as first-loss capital.

Go

```go
	// Prepare LoanBrokerCoverDeposit transaction ----------------------
	fmt.Printf("\n=== Preparing LoanBrokerCoverDeposit transaction ===\n\n")
	coverDepositTx := transaction.LoanBrokerCoverDeposit{
		BaseTx: transaction.BaseTx{
			Account: loanBrokerWallet.ClassicAddress,
		},
		LoanBrokerID: loanBrokerID,
		Amount: types.MPTCurrencyAmount{
			MPTIssuanceID: mptID,
			Value:         "1000",
		},
	}

	// Flatten() converts the struct to a map and adds the TransactionType field
	flatCoverDepositTx := coverDepositTx.Flatten()
	coverDepositTxJSON, _ := json.MarshalIndent(flatCoverDepositTx, "", "  ")
	fmt.Printf("%s\n", string(coverDepositTxJSON))
```

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.

### 5. Submit LoanBrokerCoverDeposit transaction

Sign and submit the `LoanBrokerCoverDeposit` transaction to the XRP Ledger.

JavaScript

```js
// 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!')
```

Python

```py
# Sign, submit, and wait for deposit validation ----------------------
print("\n=== Submitting LoanBrokerCoverDeposit transaction ===\n")
deposit_response = submit_and_wait(cover_deposit_tx, client, loan_broker)

if deposit_response.result["meta"]["TransactionResult"] != "tesSUCCESS":
    result_code = deposit_response.result["meta"]["TransactionResult"]
    print(f"Error: Unable to deposit cover: {result_code}")
    sys.exit(1)

print("Cover deposit successful!")
```

Go

```go
	// Sign, submit, and wait for deposit validation ----------------------
	fmt.Printf("\n=== Submitting LoanBrokerCoverDeposit transaction ===\n\n")
	depositResponse, err := client.SubmitTxAndWait(flatCoverDepositTx, &wstypes.SubmitOptions{
		Autofill: true,
		Wallet:   &loanBrokerWallet,
	})
	if err != nil {
		panic(err)
	}

	if depositResponse.Meta.TransactionResult != "tesSUCCESS" {
		fmt.Printf("Error: Unable to deposit cover: %s\n", depositResponse.Meta.TransactionResult)
		os.Exit(1)
	}
	fmt.Printf("Cover deposit successful!\n")
```

Verify that the transaction succeeded by checking for a `tesSUCCESS` result code.

### 6. Check updated cover available

Retrieve the cover available from the transaction result by checking the `LoanBroker` entry in the transaction metadata.

JavaScript

```js
// Extract updated cover available after deposit ----------------------
console.log(`\n=== Cover Available After Deposit ===\n`)
let loanBrokerNode = depositResponse.result.meta.AffectedNodes.find(node =>
  node.ModifiedNode?.LedgerEntryType === 'LoanBroker'
)

currentCoverAvailable = loanBrokerNode.ModifiedNode.FinalFields.CoverAvailable
console.log(`${currentCoverAvailable} TSTUSD`)
```

Python

```py
# Extract updated cover available after deposit ----------------------
print("\n=== Cover Available After Deposit ===\n")
loan_broker_node = next(
    node for node in deposit_response.result["meta"]["AffectedNodes"]
    if node.get("ModifiedNode", {}).get("LedgerEntryType") == "LoanBroker"
)

current_cover_available = loan_broker_node["ModifiedNode"]["FinalFields"]["CoverAvailable"]
print(f"{current_cover_available} TSTUSD")
```

Go

```go
	// Extract updated cover available after deposit ----------------------
	fmt.Printf("\n=== Cover Available After Deposit ===\n\n")
	for _, node := range depositResponse.Meta.AffectedNodes {
		if node.ModifiedNode != nil && node.ModifiedNode.LedgerEntryType == "LoanBroker" {
			currentCoverAvailable = node.ModifiedNode.FinalFields["CoverAvailable"].(string)
			break
		}
	}
	fmt.Printf("%s TSTUSD\n", currentCoverAvailable)
```

### 7. Verify the asset issuer

Before executing a clawback, verify that the account submitting the transaction is the same as the asset issuer.

JavaScript

```js
// Verify issuer of cover asset matches ----------------------
// Only the issuer of the asset can submit clawback transactions.
// The asset must also have clawback enabled.
console.log(`\n=== Verifying Asset Issuer ===\n`)
const assetIssuerInfo = await client.request({
  command: 'ledger_entry',
  mpt_issuance: mptID,
  ledger_index: 'validated'
})

if (assetIssuerInfo.result.node.Issuer !== mptIssuer.address) {
  console.error(`Error: ${assetIssuerInfo.result.node.Issuer} does not match account (${mptIssuer.address}) attempting clawback!`)
  await client.disconnect()
  process.exit(1)
}

console.log(`MPT issuer account verified: ${mptIssuer.address}. Proceeding to clawback.`)
```

Python

```py
# Verify issuer of cover asset matches ----------------------
# Only the issuer of the asset can submit clawback transactions.
# The asset must also have clawback enabled.
print("\n=== Verifying Asset Issuer ===\n")
asset_issuer_info = client.request(LedgerEntry(
    mpt_issuance=mpt_id,
    ledger_index="validated",
))

if asset_issuer_info.result["node"]["Issuer"] != mpt_issuer.address:
    issuer = asset_issuer_info.result["node"]["Issuer"]
    print(f"Error: {issuer} does not match account ({mpt_issuer.address}) attempting clawback!")
    sys.exit(1)

print(f"MPT issuer account verified: {mpt_issuer.address}. Proceeding to clawback.")
```

Go

```go
	// Verify issuer of cover asset matches ----------------------
	// Only the issuer of the asset can submit clawback transactions.
	// The asset must also have clawback enabled.
	fmt.Printf("\n=== Verifying Asset Issuer ===\n\n")
	assetIssuerInfo, err := client.Request(&mptIssuanceEntryRequest{
		MPTIssuance: mptID,
		LedgerIndex: common.Validated,
	})
	if err != nil {
		panic(err)
	}

	issuer := assetIssuerInfo.Result["node"].(map[string]any)["Issuer"].(string)
	if issuer != string(mptIssuerWallet.ClassicAddress) {
		fmt.Printf("Error: %s does not match account (%s) attempting clawback!\n", issuer, mptIssuerWallet.ClassicAddress)
		os.Exit(1)
	}
	fmt.Printf("MPT issuer account verified: %s. Proceeding to clawback.\n", mptIssuerWallet.ClassicAddress)
```

Clawback functionality is disabled by default. In the case of MPTs, the `tfMPTCanClawback` flag must be enabled when the [MPTokenIssuanceCreate transaction](/docs/references/protocol/transactions/types/mptokenissuancecreate) is submitted. This tutorial uses an MPT that is already configured for clawback.

### 8. Prepare LoanBrokerCoverClawback transaction

Create the [LoanBrokerCoverClawback transaction](/docs/references/protocol/transactions/types/loanbrokercoverclawback) object.

JavaScript

```js
// Prepare LoanBrokerCoverClawback transaction ----------------------
console.log(`\n=== Preparing LoanBrokerCoverClawback transaction ===\n`)
const coverClawbackTx = {
  TransactionType: 'LoanBrokerCoverClawback',
  Account: mptIssuer.address,
  LoanBrokerID: loanBrokerID,
  Amount: {
    mpt_issuance_id: mptID,
    value: currentCoverAvailable
  }
}

// Validate the transaction structure before submitting
xrpl.validate(coverClawbackTx)
console.log(JSON.stringify(coverClawbackTx, null, 2))
```

Python

```py
# Prepare LoanBrokerCoverClawback transaction ----------------------
print("\n=== Preparing LoanBrokerCoverClawback transaction ===\n")
cover_clawback_tx = LoanBrokerCoverClawback(
    account=mpt_issuer.address,
    loan_broker_id=loan_broker_id,
    amount=MPTAmount(mpt_issuance_id=mpt_id, value=current_cover_available),
)

print(json.dumps(cover_clawback_tx.to_xrpl(), indent=2))
```

Go

```go
	// Prepare LoanBrokerCoverClawback transaction ----------------------
	fmt.Printf("\n=== Preparing LoanBrokerCoverClawback transaction ===\n\n")
	lbID := types.LoanBrokerID(loanBrokerID)
	coverClawbackTx := transaction.LoanBrokerCoverClawback{
		BaseTx: transaction.BaseTx{
			Account: mptIssuerWallet.ClassicAddress,
		},
		LoanBrokerID: &lbID,
		Amount: types.MPTCurrencyAmount{
			MPTIssuanceID: mptID,
			Value:         currentCoverAvailable,
		},
	}

	flatCoverClawbackTx := coverClawbackTx.Flatten()
	coverClawbackTxJSON, _ := json.MarshalIndent(flatCoverClawbackTx, "", "  ")
	fmt.Printf("%s\n", string(coverClawbackTxJSON))
```

In this example we claw back the entire amount, but you can specify any amount so long as it doesn't exceed the available cover or reduce the cover below the minimum required by the `LoanBroker`.

### 9. Submit LoanBrokerCoverClawback transaction

Sign and submit the `LoanBrokerCoverClawback` transaction to the XRP Ledger.

JavaScript

```js
// Sign, submit, and wait for clawback validation ----------------------
console.log(`\n=== Submitting LoanBrokerCoverClawback transaction ===\n`)
const clawbackResponse = await client.submitAndWait(coverClawbackTx, {
  wallet: mptIssuer,
  autofill: true
})

if (clawbackResponse.result.meta.TransactionResult !== 'tesSUCCESS') {
  const resultCode = clawbackResponse.result.meta.TransactionResult
  console.error('Error: Unable to clawback cover:', resultCode)
  await client.disconnect()
  process.exit(1)
}

console.log(`Successfully clawed back ${currentCoverAvailable} TSTUSD!`)
```

Python

```py
# Sign, submit, and wait for clawback validation ----------------------
print("\n=== Submitting LoanBrokerCoverClawback transaction ===\n")
clawback_response = submit_and_wait(cover_clawback_tx, client, mpt_issuer)

if clawback_response.result["meta"]["TransactionResult"] != "tesSUCCESS":
    result_code = clawback_response.result["meta"]["TransactionResult"]
    print(f"Error: Unable to clawback cover: {result_code}")
    sys.exit(1)

print(f"Successfully clawed back {current_cover_available} TSTUSD!")
```

Go

```go
	// Sign, submit, and wait for clawback validation ----------------------
	fmt.Printf("\n=== Submitting LoanBrokerCoverClawback transaction ===\n\n")
	clawbackResponse, err := client.SubmitTxAndWait(flatCoverClawbackTx, &wstypes.SubmitOptions{
		Autofill: true,
		Wallet:   &mptIssuerWallet,
	})
	if err != nil {
		panic(err)
	}

	if clawbackResponse.Meta.TransactionResult != "tesSUCCESS" {
		fmt.Printf("Error: Unable to clawback cover: %s\n", clawbackResponse.Meta.TransactionResult)
		os.Exit(1)
	}
	fmt.Printf("Successfully clawed back %s TSTUSD!\n", currentCoverAvailable)
```

Verify that the transaction succeeded by checking for a `tesSUCCESS` result code.

### 10. Check final cover available

Retrieve the final cover available from the transaction result.

JavaScript

```js
// Extract final cover available ----------------------
console.log(`\n=== Final Cover Available After Clawback ===\n`)
loanBrokerNode = clawbackResponse.result.meta.AffectedNodes.find(node =>
  node.ModifiedNode?.LedgerEntryType === 'LoanBroker'
)

console.log(`${loanBrokerNode.ModifiedNode.FinalFields.CoverAvailable || '0'} TSTUSD`)

await client.disconnect()
```

Python

```py
# Extract final cover available ----------------------
print("\n=== Final Cover Available After Clawback ===\n")
loan_broker_node = next(
    node for node in clawback_response.result["meta"]["AffectedNodes"]
    if node.get("ModifiedNode", {}).get("LedgerEntryType") == "LoanBroker"
)

print(f"{loan_broker_node['ModifiedNode']['FinalFields'].get('CoverAvailable', '0')} TSTUSD")
```

Go

```go
	// Extract final cover available ----------------------
	fmt.Printf("\n=== Final Cover Available After Clawback ===\n\n")
	for _, node := range clawbackResponse.Meta.AffectedNodes {
		if node.ModifiedNode != nil && node.ModifiedNode.LedgerEntryType == "LoanBroker" {
			finalCover := "0"
			if ca, ok := node.ModifiedNode.FinalFields["CoverAvailable"].(string); ok {
				finalCover = ca
			}
			fmt.Printf("%s TSTUSD\n", finalCover)
			break
		}
	}
}
```

## See Also

**Concepts**:

- [Lending Protocol](/docs/concepts/tokens/lending-protocol)
- [Clawing Back Tokens](/es-es/docs/concepts/tokens/fungible-tokens/clawing-back-tokens)


**Tutorials**:

- [Issue a Multi-Purpose Token (MPT)](/es-es/docs/tutorials/tokens/mpts/issue-a-multi-purpose-token)


**References**:

- [LoanBrokerCoverDeposit transaction](/docs/references/protocol/transactions/types/loanbrokercoverdeposit)
- [LoanBrokerCoverClawback transaction](/docs/references/protocol/transactions/types/loanbrokercoverclawback)
- [MPTokenIssuanceCreate transaction](/docs/references/protocol/transactions/types/mptokenissuancecreate)