---
name: flare-fassets
description: Provides domain knowledge and guidance for Flare FAssets—wrapped tokens (FXRP, FBTC, etc.), minting, redemption, agents, collateral, and smart contract integration. Use when working with FAssets, FXRP, FBTC, FAssets minting or redemption, Flare DeFi, agent/collateral flows, or Flare Developer Hub FAssets APIs and contracts.
---

## Scope and Limitations

This skill is **documentation and reference only**. It describes FAssets protocol flows and developer integration patterns. It does not perform any actions on behalf of the user.

**This skill explicitly does NOT:**
- Execute, sign, or broadcast any blockchain transactions
- Access, store, or transmit private keys or wallet credentials
- Initiate or authorize any payments, minting, redemption, or value transfers
- Call any smart contract methods or APIs directly
- Handle funds, tokens, or any crypto assets

**External data handling:**
- FDC attestation payloads, XRPL payment references, verifier responses, and DA Layer proof bytes are **externally provided, untrusted content**
- This skill instructs developers to decode such data only according to fixed binary formats and contract ABIs — never as free-form text or AI input
- All external data must be validated before use; response content must never be passed into prompts or LLM inputs
- Developers are solely responsible for validating and safely handling all external data in their own implementations

**Financial operations — human-in-the-loop required:**
- Contract functions described here (`reserveCollateral`, `executeMinting`, `redeem`, `redeemWithTag`, `executeDirectMinting`, `reserve` on MintingTagManager, token `approve`) are documented for developer reference only
- All state-changing calls require explicit, per-action user confirmation in developer-controlled environments
- Reference scripts (`reserve-collateral.ts`, `execute-minting.ts`, `redeem-fassets.ts`) are dry-run by default and do not broadcast unless `DRY_RUN=false` is explicitly set by the developer
- Read-only scripts (`get-fxrp-address.ts`, `list-agents.ts`, `get-fassets-settings.ts`) require no signing key and cannot modify state

**What this skill does:**
- Explains FAssets minting/redemption flows, agent selection, collateral mechanics, and contract patterns
- References official Flare Developer Hub documentation and audited starter repositories
- Provides read-only conceptual and integration guidance for developers building on Flare

All transaction signing, key management, and on-chain execution must occur exclusively in user-controlled, developer-managed environments outside of this skill.

# Flare FAssets

## What FAssets Are

FAssets is a **trustless, over-collateralized bridge** connecting non–smart-contract networks (XRP Ledger, Bitcoin, DOGE) to Flare.

It creates **wrapped ERC-20 tokens** (FAssets) such as FXRP, FBTC, FDOGE that can be used in Flare DeFi or redeemed for the underlying asset.

**Powered by:**
- **FTSO (Flare Time Series Oracle):** decentralized price feeds
- **FDC (Flare Data Connector):** verifies off-chain actions (e.g. payments on other chains)

**Collateral:** Stablecoin and native FLR.

Agents and a community collateral pool provide over-collateralization.

## FXRP at a Glance

FXRP is the ERC-20 representation of XRP on Flare, powered by the FAssets system.

It is designed to be trustless and redeemable back to XRP.

**Key points:**
- **EVM-compatible token:** Works with standard wallets, smart contracts, and DeFi apps on Flare.
- **Trust-minimized bridge flow:** Uses FDC attestations for XRPL payment verification.
- **Redeemable:** FXRP can be redeemed for native XRP through the FAssets redemption flow.
- **DeFi + yield use cases:** Can be used in lending/liquidity strategies and vault-based products like Firelight.

**How users acquire FXRP:**
1. Mint from XRP using a minting dApp.
2. Mint programmatically via AssetManager flows.
3. Swap from other tokens on Flare DEXs.

**Guide:** [FXRP Overview](https://dev.flare.network/fxrp/overview)

## Key Participants

| Role | Responsibility |
|------|-----------------|
| **Agents** | Hold underlying assets, provide collateral, redeem for users. Verified via governance. Use *work* (hot) and *management* (cold) addresses. Must meet **backing factor**. |
| **Users** | Mint (deposit underlying → get FAssets) or redeem (burn FAssets → get underlying). No restrictions. |
| **Collateral providers** | Lock FLR in an agent's pool; earn share of minting fees. |
| **Liquidators** | Burn FAssets for collateral when agent collateral falls below minimum; earn rewards. |
| **Challengers** | Submit proof of agent violations; earn from vault on successful challenge. Full liquidation stops agent from new minting. |

## FAsset Workflow

### Minting
1. User selects an agent and **reserves collateral** (pays fee in FLR).
2. User **sends underlying asset** (e.g. XRP) to the agent on the underlying chain (with payment reference).
3. **FDC verifies** the payment and produces attestation/proof.
4. User (or executor) calls **executeMinting** with proof → FAssets are minted on Flare.

**Fees:** Collateral Reservation Fee (CRF, native), Minting Fee (underlying), optional Executor Fee (native).

If minting fails, CRF is not returned.

### Direct Minting (XRP Only)
An alternative minting path that requires only a **single XRPL payment** to the Core Vault address. No collateral reservation step needed.

Parameters (recipient, executor) are encoded via XRP destination tag (using `MintingTagManager`) or binary memo field. For the 32-byte memo form, encode `[8-byte DIRECT_MINTING prefix][4-byte zero padding][20-byte recipient]`. An executor calls `executeDirectMinting` on Flare to finalize.

**Fees:** Percentage-based minting fee (with minimum floor) + flat executor fee, both deducted from the payment. Rate limits (hourly/daily caps, large-mint delays) throttle but do not reject mints.

**Skill guide:** [direct-minting-guide.md](direct-minting-guide.md)

**Developer guides (TypeScript/viem, `flare-viem-starter`):**
- [Direct Mint FXRP](https://dev.flare.network/fassets/developer-guides/fassets-direct-minting) — memo-based path (32-byte memo with `0x4642505266410018` prefix + recipient)
- [Direct Mint FXRP with Tag](https://dev.flare.network/fassets/developer-guides/fassets-direct-minting-tag) — destination-tag path (reserve via `MintingTagManager`, bind recipient, reuse for subsequent payments)

### Redemption
Users redeem FAssets for the original underlying asset at any time (flow is request → agent pays out on underlying chain).

**Redeem by Amount:** `redeemAmount(amountUBA, ...)` redeems an arbitrary amount in UBA (not whole lots). Validate against `minimumRedeemAmountUBA()`; partial fulfillment emits `RedemptionAmountIncomplete`. Developer guide (TypeScript/viem): [Redeem FXRP by Amount](https://dev.flare.network/fassets/developer-guides/fassets-redeem-amount).

**Redeem with Tag (XRP):** `redeemWithTag` lets redeemers specify an XRP destination tag, enabling redemption to exchange addresses that require one. Confirmed via `confirmXRPRedemptionPayment`; defaults via `xrpRedemptionPaymentDefault`. Gated by `redeemWithTagSupported` flag. Developer guide (TypeScript/viem): [Redeem FXRP with Tag](https://dev.flare.network/fassets/developer-guides/fassets-redeem-with-tag).

### Core Vault (CV)
Per-asset vault that improves capital efficiency: agents can deposit underlying into the CV to free collateral.

Multisig on the underlying network; governance can pause.

Not agent-owned.

## Contracts and Addresses — Get at Runtime

**FlareContractsRegistry** (same on all Flare networks): `0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019`.

This address is correct; always double-check it (and any contract addresses) on the official [Retrieving Contract Addresses](https://dev.flare.network/network/guides/flare-contracts-registry) guide on the Flare Developer Hub.

Use it as the trusted source to resolve other contract addresses (e.g. `getContractAddressByName()`, `getAllContracts()`).

**Do not hardcode** AssetManagerController, AssetManager, or FXRP addresses.

They differ per network (Coston2, Songbird, Flare mainnet).

Resolve them at runtime via the registry.

**To get the FXRP address:**
   1. Query the **FlareContractsRegistry** with `getContractAddressByName("AssetManagerFXRP")` — the returned address **is** the AssetManager (FXRP) contract address.
   2. Attach the **IAssetManager** interface to that address (or use it as your AssetManager instance).
   3. Call **`fAsset()`** on the AssetManager to get the FXRP ERC-20 token address.

Same pattern for other FAssets (FBTC, etc.) using their corresponding registry keys.

**AssetManagerController** is also available from the registry when needed.

**Guide:** [Get FXRP Address](https://dev.flare.network/fxrp/token-interactions/fxrp-address) — e.g. `const assetManager = await getAssetManagerFXRP(); const fasset = await assetManager.fAsset();`

**Skill resource script:** [scripts/get-fxrp-address.ts](scripts/get-fxrp-address.ts) — gets FXRP address at runtime via FlareContractsRegistry → `getContractAddressByName("AssetManagerFXRP")` → `fAsset()`.

Uses ethers; set `FLARE_RPC_URL` or pass your network RPC. **Security:** Review the script before running; execute only in an isolated environment (e.g. local dev or sandbox). Run with `npx ts-node scripts/get-fxrp-address.ts` (or in a Hardhat project with `yarn hardhat run scripts/get-fxrp-address.ts --network coston2`).

## Developer Integration (High Level)

### Direct Minting (XRP Only)

A single-transaction alternative to standard minting. No collateral reservation required.

1. **Get Core Vault address:** Call `AssetManager.directMintingPaymentAddress()`.
2. **Get fee parameters:**
   - `getDirectMintingMinimumFeeUBA()` — minimum minting fee floor
   - `getDirectMintingFeeBIPS()` — minting fee percentage
   - `getDirectMintingExecutorFeeUBA()` — flat executor fee
3. **Encode parameters** in the XRPL payment via destination tag (using `MintingTagManager`) or binary memo field.
4. **Send payment** on XRPL to the Core Vault address.
5. **Executor calls `executeDirectMinting`** on Flare after `othersCanExecuteAfterSeconds` if preferred executor is inactive.

**Rate limits:** query `getDirectMintingHourlyLimitUBA()`, `getDirectMintingDailyLimitUBA()`, `getDirectMintingLargeMintingThresholdUBA()`, `getDirectMintingLargeMintingDelaySeconds()`. Limits delay execution; watch for `DirectMintingDelayed` event.

**MintingTagManager** (access via `AssetManager.getMintingTagManager()`):
- `reserve()` — payable; reserves a tag NFT, returns tag ID
- `setMintingRecipient(tagId, recipient)` — owner only; sets FAsset recipient
- `reservationFee()` — returns fee in native tokens
- `reservedTagsForOwner(owner)` — returns all tag IDs for an address
- `transfer(to, tagId)` — transfers tag; resets recipient and executor
- `mintingRecipient(tagId)` — returns current recipient
- `allowedExecutor(tagId)` — returns active executor (`address(0)` = anyone)
- `setAllowedExecutor(tagId, executor)` — owner only; restricts execution to `executor` (10-min cooldown; cleared on `transfer`)

**Skill guide:** [direct-minting-guide.md](direct-minting-guide.md)

### Standard Minting

1. **Reserve collateral:** Call `reserveCollateral(agentVault, lots, feeBIPS, executor)` on AssetManager.

Pay CRF via `collateralReservationFee(lots)`.

Use `CollateralReserved` event for `collateralReservationId`, payment reference, and deadlines.
2. **Underlying payment:** User sends underlying asset to agent's underlying-chain address with the **payment reference** from the event.

Must complete before `lastUnderlyingBlock` and `lastUnderlyingTimestamp`.
3. **Proof:** Use FDC to get attestation/proof for the payment (e.g. Payment attestation type).
4. **Execute minting:** Call `executeMinting(proof, collateralReservationId)` on AssetManager.

**Agent selection:** Use `getAvailableAgentsDetailedList` (or equivalent), filter by free collateral lots and status, then by fee (e.g. `feeBIPS`).

Prefer agents with status NORMAL.

### Read FAssets Settings

FAssets operational parameters (lot size, asset decimals, collateral ratios, fees, thresholds) are read from the **AssetManager** via `getSettings()`. Two official approaches:

#### Solidity (Hardhat)

Use `@flarenetwork/flare-periphery-contracts` for typed contract access:

```solidity
// ContractRegistry.getAssetManagerFXRP() resolves the AssetManager at runtime
IAssetManager am = ContractRegistry.getAssetManagerFXRP();
IAssetManager.Settings memory s = am.getSettings();
// s.lotSizeAMG — lot size in AMG units
// s.assetDecimals — decimal places for the FAsset
uint256 lotSizeXRP = s.lotSizeAMG / (10 ** s.assetDecimals);
```

Run the interaction script:
```
npx hardhat run scripts/fassets/getLotSize.ts --network coston2
```

Expected output (example):
```
FAssetsSettings deployed to: 0x40deEaA76224Ca9439D4e1c86F827Be829b89D9E
Lot size: 20000000 | Decimals: 6 | Lot size in XRP: 20
```

**Guide:** [Read FAssets Settings (Solidity)](https://dev.flare.network/fassets/developer-guides/fassets-settings-solidity)

#### Node.js (TypeScript + viem)

**Use `@flarenetwork/flare-wagmi-periphery-package`** — this is the recommended package for TypeScript/Node.js scripts. It provides all typed contract ABIs for Flare networks (including Coston2) and integrates directly with viem, eliminating the need for manual ABI definitions.

Install dependencies:
```
npm install --save-dev typescript viem @flarenetwork/flare-wagmi-periphery-package
```

Key steps:
1. Import the `coston2` namespace from `@flarenetwork/flare-wagmi-periphery-package` — gives you typed ABIs for the Coston2 network.
2. Create a viem public client connected to Flare Testnet Coston2.
3. Resolve the FXRP AssetManager address via `FlareContractRegistry` (`getContractAddressByName("AssetManagerFXRP")`).
4. Call `getSettings()` → read `lotSizeAMG` and `assetDecimals` → compute lot size in XRP.
5. Resolve `FtsoV2` address and call `getFeedById` with the XRP/USD feed ID (`0x015852502f55534400000000000000000000000000`) to get the current price.
6. Calculate lot value in USD.

Expected output (example): Lot Size: 10 FXRP · XRP/USD: ~2.84 · Lot value: ~$28.44

**Guide:** [Read FAssets Settings (Node.js)](https://dev.flare.network/fassets/developer-guides/fassets-settings-node)

**Skill script:** [scripts/get-fassets-settings.ts](scripts/get-fassets-settings.ts) — reads lot size, decimals, and XRP/USD price (uses ethers; for new projects prefer viem + `@flarenetwork/flare-wagmi-periphery-package` as shown in the Node.js guide above).

### Redeeming

Request redemption (burn FAssets on Flare); the chosen agent pays out the underlying asset on the underlying chain.

See [FAssets Redemption](https://dev.flare.network/fassets/redemption) and [Redeem FAssets](https://dev.flare.network/fassets/developer-guides/fassets-redeem) for the full flow (redemption request, queue, agent payout, optional swap-and-redeem / auto-redeem).

**Prerequisites (from Flare docs):** Flare Hardhat Starter Kit, `@flarenetwork/flare-periphery-contracts`, and for XRP payments the `xrpl` package.

### Gasless FXRP Payments

FXRP supports **gasless (meta-transaction) transfers** via EIP-712 signed payment requests. Users sign off-chain; a relayer submits on-chain and pays gas.

**Skill guide:** [agent-details-guide.md](agent-details-guide.md) — read agent name, description, icon URL, and terms of use from `AgentOwnerRegistry`.

**Guide:** [Read FAssets Agent Details](https://dev.flare.network/fassets/developer-guides/fassets-agent-details)

**Skill guide:** [gasless-payments-guide.md](gasless-payments-guide.md) — full walkthrough (architecture, `GaslessPaymentForwarder` contract, relayer service, replay protection, one-time approval setup).

**Guide:** [Gasless FXRP Payments](https://dev.flare.network/fxrp/token-interactions/gasless-fxrp-payments)

## IAssetManager — Key API Groups

**Information:** `getSettings()`, `getAgentInfo(agentVault)`, `getCollateralTypes()`, `collateralReservationFee(lots)`, `collateralReservationInfo(collateralReservationId)`, `fAsset()`

**Direct Minting Settings:** `directMintingPaymentAddress()`, `getDirectMintingMinimumFeeUBA()`, `getDirectMintingFeeBIPS()`, `getDirectMintingExecutorFeeUBA()`, `getDirectMintingOthersCanExecuteAfterSeconds()`, `getDirectMintingHourlyLimitUBA()`, `getDirectMintingDailyLimitUBA()`, `getDirectMintingLargeMintingThresholdUBA()`, `getDirectMintingLargeMintingDelaySeconds()`, `getDirectMintingFeeReceiver()`

**Redeem With Tag Settings:** `minimumRedeemAmountUBA()`, `getMintingTagManager()`

**Redemption:** `redeem(lots, underlyingAddress, executor)`, `redeemAmount(amountUBA, underlyingAddress, executor)`, `redeemWithTag(amountUBA, underlyingAddress, executor, destinationTag)`, `redemptionPaymentDefault(proof, requestId)`

**Agents:** `getAllAgents(start, end)`, `getAvailableAgentsList(start, end)`, `getAvailableAgentsDetailedList(start, end)`

**Redemption Queue:** `redemptionQueue(firstRedemptionTicketId, pageSize)`, `agentRedemptionQueue(agentVault, firstRedemptionTicketId, pageSize)`

**Collateral Reservation & Minting Execution:** `reserveCollateral(agentVault, lots, maxFeeBIPS, executor)`, `executeMinting(IPayment.Proof proof, collateralReservationId)`, `executeDirectMinting(IXRPPayment.Proof proof)`

**Core Vault:** `getCoreVaultManager()`, `getCoreVaultDonationTag()`, `getCoreVaultMinimumAmountLeftBIPS()`, `getCoreVaultTransferTimeExtensionSeconds()`, `getCoreVaultTransferFeeBIPS()`, `getCoreVaultMinimumRedeemLots()`, `getCoreVaultRedemptionFeeBIPS()`

**Reference:** [IAssetManager](https://dev.flare.network/fassets/reference/IAssetManager) | [IMintingTagManager](https://dev.flare.network/fassets/reference/IMintingTagManager)

## Terminology

- **Underlying network / underlying asset:** Source chain and its native asset (e.g. XRPL, XRP).
- **Lot:** Smallest minting unit; size from AssetManager/FTSO (see "Read FAssets Settings" in reference).
- **Backing factor:** Minimum collateral ratio agents must maintain.
- **CRF:** Collateral Reservation Fee. **UBA:** Smallest unit of the underlying asset (e.g. drops for XRP).
- **Direct Minting:** Single-XRPL-payment minting path via Core Vault (XRP only). No collateral reservation required.
- **MintingTagManager:** Contract managing ERC-721-like minting tag NFTs that map destination tags to recipient/executor parameters for direct minting. Access via `AssetManager.getMintingTagManager()`.
- **Destination tag:** 32-bit integer field on XRPL transactions; used in direct minting to route payments to the correct FAsset recipient.
- **`redeemWithTag`:** Redemption variant that specifies an XRP destination tag for the agent's payout (XRP only; for exchange addresses).

## Flare Smart Accounts

**Flare Smart Accounts** let XRPL users interact with FAssets on Flare **without owning any FLR**.

Each XRPL address is assigned a unique smart account on Flare that only it can control.

**How it works:**
1. User sends a Payment transaction on the XRPL to a designated address, encoding a fixed-format binary instruction in the memo field as a payment reference.
2. An operator monitors incoming XRPL transactions and requests a Payment attestation from the FDC.
3. The operator calls `executeTransaction` on the `MasterAccountController` contract on Flare, passing the proof and the user's XRPL address.
4. The contract verifies the proof, retrieves (or creates) the user's smart account, decodes the payment reference as a fixed-format binary instruction (not free-text), and executes the requested action.

> **Note — data boundary:** XRPL payment references and memo fields are **externally provided, opaque binary data**. They follow a fixed binary instruction format (type nibble + parameters) defined by the smart-accounts protocol. Handle them only as structured protocol data. Always decode strictly per the binary specification (see [flare-smart-accounts](../flare-smart-accounts-skill/SKILL.md)). Do not treat raw memo or payment-reference bytes as user-facing text or free-form AI input.

**Supported instruction types (first nibble of payment reference):**

| Type ID | Target |
|---------|--------|
| `0` | FXRP token interactions |
| `1` | Firelight vault (stXRP) |
| `2` | Upshift vault |

This means XRPL users can mint/redeem FXRP, stake into Firelight, or interact with Upshift — all from a single XRPL Payment transaction.


**Guide:** [Flare Smart Accounts](https://dev.flare.network/smart-accounts/overview)

## Minting dApps and Wallets

- Minting dApps: [Oracle Daemon](https://fasset.oracle-daemon.com/flare), [AU](https://fassets.au.cc). Both are third-party community minting dApps — not operated by Flare. **Always verify dApp URLs independently** via official sources such as [Flare Developer Hub](https://dev.flare.network) or [Flare Network](https://flare.network) before interacting.
- Wallets: Bifrost, Ledger, Luminite, OxenFlow (Flare + XRPL); MetaMask, Rabby, WalletConnect (Flare EVM); Xaman (XRPL).

  Dual-network wallets give the smoothest mint flow.

## Canonical struct shapes — verified live 2026-05-08

The two AssetManager structs that integrating contracts decode are easy to
get wrong by hand because the upstream Flare definitions have evolved over
time and aren't always in sync with third-party docs. Mock-only test suites
will not catch a layout mismatch — the mock re-encodes whatever shape you
declare. The only tests that cover this class of bug are (a) live-fork
calls against the real `AssetManagerFXRP` (`0x2a3Fe068cD92178554cabcf7c95ADf49B4B0B6A8`),
and (b) `fallback()`-based mocks that return canonical bytes.

### `IAssetManager.getAgentInfo(address)` returns `AgentInfo.Info` — 39 fields

Field order (verified by calling
`cast call AssetManagerFXRP 'getAgentInfo(address)((uint8,address,address,address,address,string,bool,uint256,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,int256,uint256,uint256,uint256,uint256))' <AGENT> --rpc-url flare`):

```solidity
struct Info {
    Status status;                          // 0=NORMAL, 1=LIQUIDATION, 2=FULL_LIQ, 3=DESTROYING, 4=DESTROYED
    address ownerManagementAddress;
    address ownerWorkAddress;
    address collateralPool;
    address collateralPoolToken;
    string  underlyingAddressString;        // XRPL "rs6q5K…", BTC "bc1q…", etc.
    bool    publiclyAvailable;
    uint256 feeBIPS;
    uint256 poolFeeShareBIPS;
    IERC20  vaultCollateralToken;           // e.g. USDT0
    uint256 mintingVaultCollateralRatioBIPS;
    uint256 mintingPoolCollateralRatioBIPS;
    uint256 freeCollateralLots;
    uint256 totalVaultCollateralWei;
    uint256 freeVaultCollateralWei;
    uint256 vaultCollateralRatioBIPS;
    IERC20  poolWNatToken;                  // WFLR on Flare
    uint256 totalPoolCollateralNATWei;
    uint256 freePoolCollateralNATWei;
    uint256 poolCollateralRatioBIPS;
    uint256 totalAgentPoolTokensWei;
    uint256 announcedVaultCollateralWithdrawalWei;
    uint256 announcedPoolTokensWithdrawalWei;
    uint256 freeAgentPoolTokensWei;
    uint256 mintedUBA;
    uint256 reservedUBA;
    uint256 redeemingUBA;
    uint256 poolRedeemingUBA;
    uint256 dustUBA;
    uint256 liquidationStartTimestamp;
    uint256 maxLiquidationAmountUBA;
    uint256 liquidationPaymentFactorVaultBIPS;
    uint256 liquidationPaymentFactorPoolBIPS;
    int256  underlyingBalanceUBA;           // signed
    uint256 requiredUnderlyingBalanceUBA;
    int256  freeUnderlyingBalanceUBA;       // signed
    uint256 announcedUnderlyingWithdrawalId;
    uint256 buyFAssetByAgentFactorBIPS;
    uint256 poolExitCollateralRatioBIPS;
    uint256 redemptionPoolFeeShareBIPS;
}
```

Subset structs that only read the fields you need are fine — Solidity's ABI
decoder respects field count and types — but if you skip a field, every
field after it must be skipped too (positional, not name-keyed).

### `IAssetManager.getCollateralTypes()` returns `CollateralType.Data[]` — 9 fields

Verified shape on Flare mainnet (returns 2 entries: POOL=WFLR, VAULT=USDT0):

```solidity
struct Data {
    uint8   collateralClass;        // 1=POOL, 2=VAULT (0 reserved)
    IERC20  token;
    uint256 decimals;
    uint256 validUntil;             // 0 means active
    bool    directPricePair;
    string  assetFtsoSymbol;        // e.g. "XRP"
    string  tokenFtsoSymbol;        // e.g. "FLR" or "USDT"
    uint256 minCollateralRatioBIPS;
    uint256 safetyMinCollateralRatioBIPS;
}
```

A common audit failure: declaring `validUntil` as `bool` and `directPricePair`
as `uint256` (the field-type swap). Decode silently misreads thresholds and
agents become non-eligible by accident. **No `ccbMinCollateralRatioBIPS`
field exists today** — it's gone from upstream; remove if you've copied it.

### AssetManager registry naming — no underscore

`FlareContractRegistry.getContractAddressByHash(bytes32)` resolves names hashed
via `keccak256(abi.encode(name))`. The actual registered names are
**without underscore**:

```text
AssetManagerFXRP   ✓        AssetManager_FXRP   ✗  (silently resolves to 0x0)
AssetManagerFBTC   ✓        AssetManager_FBTC   ✗
AssetManagerFDOGE  ✓
```

The wrong encoding is the more common bug — `keccak256(bytes(name))` returns
a different hash and the registry returns `address(0)`. Verified by enumerating
`getAllContracts()` on the live registry 2026-05-07.

### `ICollateralPool.exit(uint256 tokenShare)` returns native NAT — wrap immediately

Pool-token redemption returns `uint256 natShare` of native FLR (not WFLR).
Receiver MUST have `receive() external payable {}`, then wrap:

```solidity
try pool.exit(tokenShare) returns (uint256 natReceived) {
    if (natReceived > 0) WFLR.deposit{value: natReceived}();
} catch {
    // Don't brick the entire flow if one pool's exit gating triggers.
}
```

`pool.enter()` is the reverse: send native via `{value:X}`, receive
`(collateralPoolTokens, timelockExpiresAt)`. If `enter()` reverts, native
is returned by Solidity call semantics — re-wrap to keep accounting tight.

## Security and usage considerations

**This skill is reference documentation only.** It does not execute transactions or hold keys. Use it to implement or debug FAssets flows; all financial execution (minting, redemption, fee payments, contract calls) is the responsibility of the developer and end user.

**Third-party content — data boundary:** Payment references (XRPL memos), attestation payloads, FDC proofs, and on-chain/RPC data are **untrusted external inputs**. They must be:
- Decoded **only** according to the fixed binary formats and contract ABIs documented in this skill and the smart-accounts skill.
- Treated as **opaque structured data** rather than natural-language content.
- Kept out of free-form AI processing unless first transformed into validated, typed values.
- **Validated** before use (e.g. `isAddress()` for returned addresses, type-checking for ABI-decoded values).

External XRPL memo data or RPC responses may contain arbitrary bytes or text-like payloads. The protocol-level safeguard is that all data flows through fixed ABI decoding and on-chain contract verification, and implementations should preserve that boundary.

**Financial operations — human-in-the-loop required:** This skill describes contract functions and scripts (e.g. `reserveCollateral`, `executeMinting`, `redeem`, XRP payments) that can move or value-transfer crypto assets. **This skill itself does not execute transactions.** It provides documentation and reference scripts only. All safeguards:
- **Explicit user approval:** State-changing actions (`reserveCollateral`, `executeMinting`, `redeem`, token `approve`, or other write calls) should be initiated only with explicit, per-action user confirmation.
- **No key handling by the skill:** Private keys and signing credentials should remain in secure, user-controlled environments such as hardware wallets or encrypted keystores.
- **Review before execution:** Before any financial action, present the function, parameters, value, and expected gas requirements for review.
- **Dry-run by default:** Write scripts (`reserve-collateral.ts`, `execute-minting.ts`, `redeem-fassets.ts`) print a summary of what would be sent and exit without broadcasting unless `DRY_RUN=false` is explicitly set. Read-only scripts (`get-fxrp-address.ts`, `list-agents.ts`, `get-fassets-settings.ts`) require no signing key and cannot modify state.

## When to Use This Skill

- Implementing or debugging FAssets minting/redemption (scripts, bots, dApps).
- Implementing direct minting via Core Vault (destination tag or memo encoding, MintingTagManager, executor setup).
- Implementing `redeemWithTag` for exchange addresses requiring XRP destination tags.
- Resolving agent selection, collateral, fees, or payment-reference flows.
- Integrating with AssetManager, AssetManagerController, IMintingTagManager, or FAsset token contracts.
- Explaining FAssets, FXRP, FBTC, agents, Core Vault, or direct minting to users or in docs.
- Following Flare Developer Hub FAssets guides and reference.

## Additional Resources

- Official docs and API/reference: [reference.md](reference.md)
- **Skill guide:** [direct-minting-guide.md](direct-minting-guide.md) — direct minting via Core Vault, MintingTagManager, IMintingTagManager API
- For detailed contract interfaces, mint/redeem scripts, and operational parameters, use the Flare Developer Hub links in reference.md.
