Agent documentation index: llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Skip to main content

Direct Minting Troubleshooting

Use this page as a Developer Hub reference for FXRP direct minting. The tables below are a one-screen summary; later sections add prevention steps, tag and executor edge cases, and smart-account routing.

Before You Send XRP

Validate these before submitting an XRPL payment. Mistakes here are often irreversible.

CheckHow to verifyIf wrong
Core Vault addressdirectMintingPaymentAddress()Payment not recognized; mint reverts with InvalidReceivingAddress
Amount ≥ minimum feegetDirectMintingMinimumFeeUBA()Entire payment goes to fee receiver; minter receives 0 FXRP (DirectMintingPaymentTooSmallForFee)
Recipient encodingTag via MintingTagManager, or 32-byte / 48-byte memo (see memo field)FXRP may mint to the wrong address or route via smart accounts
Memo format32-byte: DIRECT_MINTING prefix + recipient. 48-byte: DIRECT_MINTING_EX + recipient + executor (see Direct Mint FXRP guide)Unrecognized memo → smart account path
Not a donationDo not use the Core Vault donation destination tagReverts with PaymentIsCoreVaultDonation
Not a redemption referenceDo not reuse agent redemption memosReverts with ForbiddenPaymentReference

Irreversible Failures

These do not revert. Funds are consumed or sent to the wrong place.

No on-chain recovery

The failures below succeed on-chain from the protocol's perspective. Prevention is the only remedy.

1. Payment below the minimum minting fee

2. Wrong recipient in memo or tag

  • Cause: Incorrect EVM address in 32-byte memo, 48-byte DIRECT_MINTING_EX memo, or setMintingRecipient()
  • Result: FXRP mints to the encoded address. No recovery on-chain.
  • Prevention: Double-check recipient address. Prefer destination tags with a registered recipient over raw memo encoding.

3. Payment sent to the wrong XRPL address

  • Cause: User sends XRP to an address other than directMintingPaymentAddress()
  • Result: InvalidReceivingAddress on execution; XRP is outside the FAssets system.
  • Prevention: Always fetch the address from the contract at runtime. Do not hardcode.

4. Unrecognized memo routes to smart accounts

  • Cause: Missing memo, invalid tag, or memo that does not match DIRECT_MINTING / DIRECT_MINTING_EX / registered tag
  • Result: FXRP is minted to SmartAccountManager, not directly to your wallet.
  • Event: DirectMintingExecutedToSmartAccount
  • Prevention: Use a supported encoding path, or confirm smart account routing is intended. See Smart Account Path below.

Execution Reverts

Call executeDirectMinting or executeDirectMintingWithData only after the XRPL payment is finalized and attested.

ErrorCauseResolution
InvalidReceivingAddressProof shows payment not to Core VaultVerify XRPL destination address
AmountNotPositiveZero-amount paymentSend a positive amount
PaymentFailedUnderlying transaction failed on XRPLRetry payment on XRPL
MissingMintingTagManagerTag manager not configuredWait for governance setup; direct minting unavailable
MissingSmartAccountManagerSmart account manager not configuredSame as above
InvalidExecutorCaller is not the allowed executor, and exclusive window not expiredUse allowed executor, or wait getDirectMintingOthersCanExecuteAfterSeconds()
OnlyProofOwnerFDC proof proofOwnermsg.senderExecutor who paid for attestation must submit the proof, or request proof with proofOwner = address(0)
DirectMintingStillDelayedRate limit or large-mint delay not elapsedWait until executionAllowedAt from directMintingDelayState(txId)
PaymentAlreadyConfirmedSame payment executed twiceNormal — mint already completed
MintingCapExceededGlobal FAsset supply cap reachedRetry later or wait for cap increase
PaymentIsCoreVaultDonationCore Vault donation tag usedUse confirmCoreVaultDonation instead
ForbiddenPaymentReferenceRedemption-style memo detectedUse a valid direct-minting memo or tag
NoDataExpectedForDirectMintingexecuteDirectMintingWithData used for tag/memo/direct pathUse executeDirectMinting instead
NoValueExpectedNon-zero msg.value on direct-recipient pathSend native tokens only on smart-account path
EmergencyPauseActiveSystem emergency pauseWait for unpause
LegalPaymentNotProven / TransactionNotProvenInvalid or unverifiable FDC proofRegenerate proof after finalization

Delays

Delays are not failures

Rate limits delay minting; they do not permanently reject it.

TriggerSettingEvent
Hourly cap exceededgetDirectMintingHourlyLimitUBA()DirectMintingDelayed
Daily cap exceededgetDirectMintingDailyLimitUBA()DirectMintingDelayed
Large mintgetDirectMintingLargeMintingThresholdUBA() + getDirectMintingLargeMintingDelaySeconds()LargeDirectMintingDelayed

Retry steps:

  1. Listen for DirectMintingDelayed or LargeDirectMintingDelayed.
  2. Read directMintingDelayState(transactionId)allowedAt.
  3. Re-submit the same FDC proof with executeDirectMinting after allowedAt.
  4. If governance unblocks mints, watch for DirectMintingsUnblocked and check getDirectMintingsUnblockUntilTimestamp(). Optionally call markUnblockedDirectMintingAllowed(transactionId) to reset the executor exclusive window.

Notes

  • Recipient and executor are frozen at delay creation. Tag transfers during a delay cannot redirect funds.
  • Attached native value (msg.value) is returned to the executor if minting is delayed.
  • Minting capacity is reserved during a delay and counts toward MintingCapExceeded.

For off-chain pre-flight logic, see Check Direct Minting Limits and rate limits.

Executor and Proof of Ownership

Preferred executor

Set via:

If allowedExecutor ≠ address(0):

FDC Proof Ownership

If the attestation request sets proofOwner to a specific address, only that address can call executeDirectMinting. Use proofOwner = address(0) for open execution.

Minting Tag Manager Pitfalls

MistakeError / behavior
Wrong fee on reserve()WrongReservationPaymentAmount
Non-owner sets recipientOnlyTagOwner
Recipient set to address(0)ZeroAddress
Tag transferredRecipient resets to new owner; executor cleared immediately
Executor changedCooldown before new executor is active — query pendingAllowedExecutorChange(tagId)

See Minting Tag Manager and Transfer a Minting Tag.

Smart Account Path

Use this path only when intentional.

RuleDetail
When usedNo memo, unrecognized memo, or unregistered destination tag
ExecutionexecuteDirectMintingWithData(proof, data)data verified by smart account manager
Native valuemsg.value forwarded to smart account manager (e.g., for composed redeem flows)
Executor feeSet by smart account manager, not AssetManager
Direct pathDo not use WithData or attach msg.value for tag/memo/direct mints

If smart-account execution reverts, FXRP is not minted and XRP remains at the Core Vault. See Failure Handling and Recover Stuck Mint Transaction.

Fee Reference

FeeGetter
Minimum minting feegetDirectMintingMinimumFeeUBA()
Percentage minting feegetDirectMintingFeeBIPS()
Executor fee (direct path)getDirectMintingExecutorFeeUBA()

Minted amount (direct path):

receivedAmount - mintingFee - executorFee

Minting fee = max(percentage, minimum), capped at receivedAmount. The executor fee is taken from the remainder.

Pre-flight Checklist

  • Core Vault address from directMintingPaymentAddress()
  • Amount > getDirectMintingMinimumFeeUBA()
  • Recipient encoded correctly (tag or memo)
  • Executor set if exclusivity is required
  • Hourly/daily/large-mint limits checked
  • FDC proof obtained after XRPL finalization
  • Correct execute method (WithData only for smart account path)
  • Emergency pause not active

Monitoring Events

EventMeaning
DirectMintingExecutedSuccess — mint to recipient
DirectMintingExecutedToSmartAccountSuccess — mint via smart accounts
DirectMintingDelayedHourly/daily rate limit; retry after executionAllowedAt
LargeDirectMintingDelayedLarge mint above threshold; retry after executionAllowedAt
DirectMintingPaymentTooSmallForFeePayment consumed as fee; no user mint
DirectMintingsUnblockedGovernance bypassed hourly/daily limiter until startedUntilTimestamp