# Mint FXRP

> Mint FXRP in a single XRPL payment.

> 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-mint

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

This guide walks you through minting FAssets FXRP using [minting](/fassets/minting): a single XRPL payment to the FXRP [Core Vault](/fassets/core-vault) with a memo that encodes the Flare-side recipient. An executor then finalizes the mint on Flare, and the recipient receives FXRP.

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

## How it works[​](#how-it-works "Direct link to How it works")

Minting FXRP is a single-step XRPL payment:

-   A single XRPL payment to the Core Vault address.
-   The recipient (and optionally the executor) is encoded in the XRPL memo or destination tag.
-   An executor calls [`executeDirectMinting`](/fassets/reference/IAssetManager#executedirectminting) on Flare to finalize and receives a flat fee.

This guide demonstrates the **32-byte memo format**, where the recipient is a Flare address and any executor can finalize.

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

-   [Flare smart account](/smart-accounts/overview) controlled by your XRPL wallet.
-   Testnet XRP on the XRP Ledger Testnet usage. Get testnet XRP from the [XRP Testnet Faucet](https://xrpl.org/resources/dev-tools/xrp-faucets).

## Minting Memo[​](#minting-memo "Direct link to Minting Memo")

The memo is a packed 32-byte [`PaymentReference`](/fassets/minting#memo-field):

Bytes

Value

Meaning

0-7

`4642505266410018`

Minting prefix (`DIRECT_MINTING`).

8-11

`00000000`

Zero padding to fill the 32-byte memo.

12-31

20-byte recipient

EVM address of the Flare smart account receiving FXRP tokens.

Because no executor is encoded, anyone can finalize this minting on Flare. For executor-restricted minting, use the 48-byte memo format described in [Memo Field](/fassets/minting#memo-field).

## Minting Script[​](#minting-script "Direct link to Minting Script")

src/fassets/direct-mint.ts

```
import { Client, Wallet } from "xrpl";import type { Address } from "viem";import { sendXrplPayment } from "./utils/xrpl";import { getPersonalAccountAddress } from "./utils/smart-accounts";import {  getContractAddressByName,  getDirectMintingPaymentAddress,} from "./utils/flare-contract-registry";import {  computeDirectMintingPaymentAmountXrp,  getFxrpBalance,  waitForDirectMintingOutcome,} from "./utils/fassets";// 1. Direct minting prefixconst DIRECT_MINTING_PREFIX = "4642505266410018";// 2. Build the 32-byte direct-minting PaymentReference memo://    [8-byte prefix][4-byte zero padding][20-byte recipient address]function buildDirectMintingMemo(recipientAddress: Address): string {  return (    DIRECT_MINTING_PREFIX + "00000000" + recipientAddress.slice(2).toLowerCase()  );}// 3. Send the XRPL payment to the Core Vault with the direct-minting memoasync function sendDirectMintPayment({  coreVaultXrplAddress,  recipientAddress,  amountXrp,  xrplClient,  xrplWallet,}: {  coreVaultXrplAddress: string;  recipientAddress: Address;  amountXrp: number;  xrplClient: Client;  xrplWallet: Wallet;}) {  const memoData = buildDirectMintingMemo(recipientAddress);  console.log("Direct minting memo (32 bytes):", memoData, "\n");  const transaction = await sendXrplPayment({    destination: coreVaultXrplAddress,    amount: amountXrp,    memos: [{ Memo: { MemoData: memoData } }],    wallet: xrplWallet,    client: xrplClient,  });  console.log(    "Direct mint XRPL transaction hash:",    transaction.result.hash,    "\n",  );  return transaction;}async function main() {  // 4. Net FXRP amount to mint in XRP. Minting + executor fees are added on top  //    by computeDirectMintingPaymentAmountXrp to form the XRPL payment amount.  const fxrpMintAmount = 10;  // 5. Connect to the XRPL Testnet and load the sender wallet from XRPL_SEED.  const xrplClient = new Client(process.env.XRPL_TESTNET_RPC_URL!);  const xrplWallet = Wallet.fromSeed(process.env.XRPL_SEED!);  // 6. Resolve the Flare smart-account recipient and the AssetManagerFXRP address.  const [personalAccountAddress, assetManagerAddress] = await Promise.all([    getPersonalAccountAddress(xrplWallet.address),    getContractAddressByName("AssetManagerFXRP"),  ]);  console.log("Personal account address:", personalAccountAddress, "\n");  // 7. Read the Core Vault XRPL payment address, the recipient's initial FXRP  //    balance, and the gross XRP amount (net mint + minting fee + executor fee).  const [coreVaultXrplAddress, initialBalance, paymentAmountXrp] =    await Promise.all([      getDirectMintingPaymentAddress(assetManagerAddress),      getFxrpBalance(personalAccountAddress),      computeDirectMintingPaymentAmountXrp({        netMintAmountXrp: fxrpMintAmount,      }),    ]);  console.log("Core Vault XRPL address:", coreVaultXrplAddress, "\n");  console.log("AssetManagerFXRP address:", assetManagerAddress, "\n");  console.log("Initial FXRP balance:", initialBalance, "\n");  console.log("Payment amount (XRP, net mint + fees):", paymentAmountXrp, "\n");  // 8. Send the XRPL payment that triggers direct minting on Flare.  await sendDirectMintPayment({    coreVaultXrplAddress,    recipientAddress: personalAccountAddress,    amountXrp: paymentAmountXrp,    xrplClient,    xrplWallet,  });  // 9. Wait for direct minting to finish. Rate limits may emit DirectMintingDelayed  //    first; waitForDirectMintingOutcome logs executionAllowedAt and keeps polling  //    until DirectMintingExecuted.  const mintEvent = await waitForDirectMintingOutcome({    assetManagerAddress,    targetAddress: personalAccountAddress,  });  console.log("DirectMintingExecuted event:", mintEvent, "\n");  console.log("Minted amount (UBA):", mintEvent.args.mintedAmountUBA, "\n");  console.log("Minting fee (UBA):", mintEvent.args.mintingFeeUBA, "\n");  console.log("Executor fee (UBA):", mintEvent.args.executorFeeUBA, "\n");  // 10. Read the final FXRP balance and log the delta.  const finalBalance = await getFxrpBalance(personalAccountAddress);  console.log("Final FXRP balance:", finalBalance, "\n");  console.log("FXRP minted:", finalBalance - initialBalance, "\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.  Define the minting prefix constant `DIRECT_MINTING_PREFIX`.
    
2.  `buildDirectMintingMemo` concatenates the prefix, four zero bytes, and the recipient address (without the `0x` prefix, lowercased) into a 32-byte hex string ready to be passed as [`MemoData`](https://xrpl.org/docs/references/protocol/transactions/common-fields#memos-field) on the XRPL payment.
    
3.  `sendDirectMintPayment` builds the memo for the recipient and submits an XRPL `Payment` transaction to the [Core Vault](/fassets/core-vault) address with `memos: [{ Memo: { MemoData } }]`, returning the resulting transaction.
    
4.  Set the net FXRP amount to mint in XRP. Minting and executor fees are added to the net amount to form the XRPL payment amount.
    
5.  Connect to the XRPL Testnet using `XRPL_TESTNET_RPC_URL` and load the sender wallet from `XRPL_SEED`.
    
6.  Resolve the recipient — the Flare [`PersonalAccount`](/smart-accounts/reference/IPersonalAccount) for the XRPL wallet — via [`getPersonalAccountAddress`](/smart-accounts/reference/IPersonalAccount), and look up `AssetManagerFXRP` through the [Flare Contract Registry](/network/guides/flare-contracts-registry) using [`getContractAddressByName`](/network/guides/flare-contracts-registry).
    
7.  Read three values in parallel:
    
    -   `getDirectMintingPaymentAddress` — the Core Vault XRPL address that receives the payment.
    -   `getFxrpBalance` — the recipient's FXRP balance before minting.
    -   `computeDirectMintingPaymentAmountXrp` — the gross XRP amount equal to the net mint amount plus the minting fee and the executor fee, as quoted by the `AssetManagerFXRP` contract.
8.  Send the XRPL payment to the Core Vault with the recipient memo via the `sendDirectMintPayment` function.
    
9.  Wait for minting to complete via `waitForDirectMintingOutcome`. This helper watches for both [`DirectMintingDelayed`](/fassets/reference/IAssetManagerEvents#directmintingdelayed) and [`DirectMintingExecuted`](/fassets/reference/IAssetManagerEvents#directmintingexecuted):
    
    -   If hourly or daily rate limits apply, an executor's first `executeDirectMinting` call emits [`DirectMintingDelayed`](/fassets/reference/IAssetManagerEvents#directmintingdelayed) with `executionAllowedAt`.
    -   If the amount is strictly above the [large-mint threshold](/fassets/minting#large-minting-delay), it emits [`LargeDirectMintingDelayed`](/fassets/reference/IAssetManagerEvents#largedirectmintingdelayed) instead. The underlying XRP stays at the Core Vault; no FXRP is minted yet.
    -   After `executionAllowedAt`, the executor retries with the same FDC proof.
    -   `waitForDirectMintingOutcome` logs any delay and keeps polling until `DirectMintingExecuted`.
    
    Pre-flight a mint amount with the [Check Minting Limits guide](/fassets/developer-guides/fassets-mint-limits).
    
    The executed event's `mintedAmountUBA`, `mintingFeeUBA`, and `executorFeeUBA` describe how the underlying payment was split.
    
10.  Read the final FXRP balance and log the delta.
     

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

-   **Fees are deducted from the underlying payment.** The XRP sent to the [Core Vault](/fassets/core-vault) must cover the net mint amount plus the minting fee and the executor fee.
-   **If the payment is below the minimum minting fee**, no FXRP is minted, and the entire payment is forfeited to the fee receiver.
-   **Rate limits delay execution; they do not revert.** When hourly or daily limits apply, the first finalization attempt emits [`DirectMintingDelayed`](/fassets/reference/IAssetManagerEvents#directmintingdelayed) with `executionAllowedAt`. When the amount is strictly above the [large-mint](/fassets/minting#large-minting-delay) threshold, it emits [`LargeDirectMintingDelayed`](/fassets/reference/IAssetManagerEvents#largedirectmintingdelayed) instead. Your XRP remains at the Core Vault until an executor successfully retries. Use `waitForDirectMintingOutcome` (see [Delayed minting flow](/fassets/minting#delayed-minting-flow)) rather than waiting only for `DirectMintingExecuted`.
-   **For repeat minters**, prefer the destination-tag flow via `IMintingTagManager` — it avoids constructing a memo per payment and lets you set a preferred executor.

## Common mistakes[​](#common-mistakes "Direct link to Common mistakes")

Before sending XRP, validate the Core Vault address, minimum fee, and recipient encoding. The most costly errors — payment below the minimum fee, wrong recipient, or payment to the wrong XRPL address — do not revert and cannot be recovered on-chain.

-   [Minting Troubleshooting](/fassets/troubleshooting/minting-troubleshooting) — pre-flight checks, errors, delays, and recovery

What's next

To continue your FAssets development journey, you can:

-   Mint with tag with [Mint FXRP with Tag](/fassets/developer-guides/fassets-mint-tag).
-   Read the protocol details in [Minting](/fassets/minting).
-   Redeem FAssets with [`redeemAmount`](/fassets/developer-guides/fassets-redeem-amount) or [`redeemWithTag`](/fassets/developer-guides/fassets-redeem-with-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.
