# Redeem FXRP by Amount

> Redeem any amount of FXRP without rounding to whole lots.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/fassets/developer-guides/fassets-redeem-amount

## Overview[​](#overview "Direct link to Overview")

This guide walks you through redeeming FXRP using [`redeemAmount`](/fassets/reference/IAssetManager#redeemamount) on the `AssetManagerFXRP` contract. Unlike the previous [`redeem`](/fassets/reference/IAssetManager#redeem) guide, `redeemAmount` accepts an arbitrary amount instead of whole lots.

The complete runnable example is available in the [flare-viem-starter](https://github.com/flare-foundation/flare-viem-starter/blob/main/src/fassets/redeem-amount.ts) repository.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

-   An EVM wallet with FXRP.
-   Native tokens on the same wallet to cover the gas fees.
-   An XRPL address to receive the redeemed XRP.

## Redeem Amount Script[​](#redeem-amount-script "Direct link to Redeem Amount Script")

src/fassets/redeem-amount.ts

```
import { coston2 } from "@flarenetwork/flare-wagmi-periphery-package";import { parseEventLogs, type Address } from "viem";import { account, publicClient, walletClient } from "./utils/client";import { getContractAddressByName } from "./utils/flare-contract-registry";// 1. Amount to redeem in UBA (underlying base units; 1 XRP = 1_000_000 UBA).const REDEEM_AMOUNT_UBA = 5000000n;// 2. Redeemer underlying (XRPL) address that will receive the redeemed XRP.const REDEEMER_UNDERLYING_ADDRESS_STRING = "rSHYuiEvsYsKR8uUHhBTuGP5zjRcGt4nm";// 3. Executor (not used here, so the zero address).const EXECUTOR_ZERO_ADDRESS: Address =  "0x0000000000000000000000000000000000000000";async function main() {  // 4. Resolve the AssetManagerFXRP address from the Flare Contract Registry.  const assetManagerAddress =    await getContractAddressByName("AssetManagerFXRP");  console.log("AssetManagerFXRP address:", assetManagerAddress, "\n");  // 5. Read the protocol-wide minimum redemption amount and assert that the  //    requested amount is above it. Smaller redemptions are rejected on-chain.  const minimumRedeemAmountUBA = await publicClient.readContract({    address: assetManagerAddress,    abi: coston2.iAssetManagerAbi,    functionName: "minimumRedeemAmountUBA",  });  console.log(    "minimumRedeemAmountUBA:",    minimumRedeemAmountUBA.toString(),    "\n",  );  console.log(    "Requested redeem amount UBA:",    REDEEM_AMOUNT_UBA.toString(),    "\n",  );  if (REDEEM_AMOUNT_UBA < minimumRedeemAmountUBA) {    throw new Error(      `Redeem amount (${REDEEM_AMOUNT_UBA.toString()}) must be greater than minimumRedeemAmountUBA (${minimumRedeemAmountUBA.toString()}).`,    );  }  // 6. Simulate the redeemAmount call to validate args and produce a request  //    that walletClient can submit.  const { request } = await publicClient.simulateContract({    account,    address: assetManagerAddress,    abi: coston2.iAssetManagerAbi,    functionName: "redeemAmount",    args: [      REDEEM_AMOUNT_UBA,      REDEEMER_UNDERLYING_ADDRESS_STRING,      EXECUTOR_ZERO_ADDRESS,    ],  });  // 7. Submit the redemption request transaction on Flare.  const txHash = await walletClient.writeContract(request);  console.log("redeemAmount tx hash:", txHash, "\n");  // 8. Wait for the transaction receipt.  const receipt = await publicClient.waitForTransactionReceipt({    hash: txHash,  });  console.log("redeemAmount status:", receipt.status, "\n");  // 9. Decode RedemptionRequested events from the receipt logs and pick the  //    one that belongs to this redeemer.  const redemptionLogs = parseEventLogs({    abi: coston2.iAssetManagerAbi,    eventName: "RedemptionRequested",    logs: receipt.logs,  });  const redemptionEvent = redemptionLogs.find(    (log) => log.args.redeemer.toLowerCase() === account.address.toLowerCase(),  );  if (!redemptionEvent) {    throw new Error(      "RedemptionRequested event not found for this transaction and redeemer",    );  }  console.log("RedemptionRequested event:", redemptionEvent, "\n");}void main()  .then(() => process.exit(0))  .catch((error) => {    console.error(error);    process.exit(1);  });
```

## Code Breakdown[​](#code-breakdown "Direct link to Code Breakdown")

1.  Set `REDEEM_AMOUNT_UBA` to the amount of FXRP to redeem in UBA (underlying base unit).
2.  Set `REDEEMER_UNDERLYING_ADDRESS_STRING` to the XRPL address that will receive the redeemed XRP from the agent.
3.  `EXECUTOR_ZERO_ADDRESS` is used because no executor is appointed in this example. Pass a real address to delegate default-handling to an executor.
4.  Resolve the `AssetManagerFXRP` address through the [Flare Contract Registry](/network/guides/flare-contracts-registry) using [`getContractAddressByName`](/network/guides/flare-contracts-registry).
5.  Read [`minimumRedeemAmountUBA`](/fassets/reference/IAssetManager#minimumredeemamountuba) and check that the requested amount is at least the protocol minimum.
6.  Simulate the [`redeemAmount`](/fassets/reference/IAssetManager#redeemamount) call to validate the arguments and produce a signed request payload.
7.  Submit the redemption request transaction.
8.  Wait for the transaction receipt.
9.  Decode [`RedemptionRequested`](/fassets/reference/IAssetManagerEvents#redemptionrequested) events from the receipt logs with the `parseEventLogs` function and select the one whose `redeemer` matches the caller. A single call may emit multiple `RedemptionRequested` events when multiple agents fulfill the request.

## Important Notes[​](#important-notes "Direct link to Important Notes")

-   **`minimumRedeemAmountUBA` is enforced on-chain.** Requests below the threshold revert.
-   **The redemption may be partial.** If the request requires too many redemption tickets, only part is fulfilled, and the remaining tickets are returned via [`RedemptionAmountIncomplete`](/fassets/reference/IAssetManagerEvents#redemptionamountincomplete). Call `redeemAmount` again for the remainder.
-   **Multiple agents may pay.** A single `redeemAmount` call can produce several [`RedemptionRequested`](/fassets/reference/IAssetManagerEvents#redemptionrequested) events — one per agent serving the request. Track each `requestId` for the agent's underlying-chain payment.
-   **Agents have a deadline to pay.** If an agent fails to pay within the redemption window, start the [redemption default process](/fassets/developer-guides/fassets-redemption-default).
-   **Use `redeemWithTag` for exchange deposits.** When the destination XRPL address requires a destination tag, call [`redeemWithTag`](/fassets/reference/IAssetManager#redeemwithtag) instead.

What's next

To continue your FAssets development journey, you can:

-   Redeem with tag with [`redeemWithTag`](/fassets/developer-guides/fassets-redeem-with-tag).
-   Handle non-paying agents in [Monitor Redemptions & Execute Defaults](/fassets/developer-guides/fassets-redemption-default).
-   Mint without a tag using [memo-based direct minting](/fassets/developer-guides/fassets-direct-minting) or [direct minting with tag](/fassets/developer-guides/fassets-direct-minting-tag).

FAssets demo dApp

The [FAssets demo dApp](https://fassets-demo-dapp.vercel.app/) showcases the FAssets system using the [Flare wagmi periphery package](https://www.npmjs.com/package/@flarenetwork/flare-wagmi-periphery-package). This app is a Next.js reference implementation for settings, minting, tags, transfer, and redeem functionality.

The source code is available in the [fassets-demo-dapp](https://github.com/flare-foundation/fassets-demo-dapp) repository.
