Skip to main content

IXRPPayment

An interface to relay and verify XRP Ledger Payment transactions, exposing XRPL-specific fields (source r-address, first Memo data, destination tag) directly to consumer contracts.

Sourced from IXRPPayment.sol on GitHub.

Overview

The IXRPPayment interface lets smart contracts on Flare verify native XRP payments using XRPL-native request fields. It surfaces the XRPL r-address as a string, the raw bytes of the first Memo's MemoData, and the DestinationTag. This is the proof type consumed, for example, by FAssets direct minting (executeDirectMinting(IXRPPayment.Proof calldata _payment)).

Supported Chains

Network TypeSupported Chains
MainnetXRP (XRP Ledger)
TestnettestXRP (XRPL Testnet)

Interface Definition

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
* @custom:name IXRPPayment
* @custom:id 0x08
* @custom:supported XRP, testXRP
* @author Flare
* @notice A relay of a transaction on an XRPL chain that is of type payment in a native (XRP) currency.
* The provable transaction is identified by its `transactionId`. The transactions represents a transfer
* / attempt of transfer of XRP currency from a source address to a receiving address, and it also includes
* relevant details such as amount sent, amount received, memos, destination tags, and success status.
*
* @custom:verification The transaction with `transactionId` is fetched from the RPC of the blockchain node
* or relevant indexer.
*
* If the transaction cannot be fetched or the transaction is in a block that does not have a sufficient
* number of confirmations, the attestation request is rejected.
*
* Once the transaction is received, the payment summary is computed according to the rules for the source
* chain. If the summary is successfully calculated, the response is assembled from the summary.
* `blockNumber` and `blockTimestamp` are retrieved from the block if they are not included in the
* transaction data. `blockTimestamp` is close time of the ledger converted to UNIX time.
*
* If the summary is not successfully calculated, the attestation request is rejected.
* @custom:lut `blockTimestamp`
* @custom:lutlimit `0x127500`
*/
interface IXRPPayment {
struct Request {
bytes32 attestationType;
bytes32 sourceId;
bytes32 messageIntegrityCode;
RequestBody requestBody;
}

struct Response {
bytes32 attestationType;
bytes32 sourceId;
uint64 votingRound;
uint64 lowestUsedTimestamp;
RequestBody requestBody;
ResponseBody responseBody;
}

struct Proof {
bytes32[] merkleProof;
Response data;
}

struct RequestBody {
bytes32 transactionId;
address proofOwner;
}

struct ResponseBody {
uint64 blockNumber;
uint64 blockTimestamp;
string sourceAddress;
bytes32 sourceAddressHash;
bytes32 receivingAddressHash;
bytes32 intendedReceivingAddressHash;
int256 spentAmount;
int256 intendedSpentAmount;
int256 receivedAmount;
int256 intendedReceivedAmount;
bool hasMemoData;
bytes firstMemoData;
bool hasDestinationTag;
uint256 destinationTag;
uint8 status;
}
}

Structs

Request

Top-level request structure.

Parameters

  • attestationType: ID of the attestation type (0x08 for XRPPayment)
  • sourceId: ID of the data source (XRP or testXRP)
  • messageIntegrityCode: MessageIntegrityCode derived from the expected response
  • requestBody: Data defining the request

Response

Top-level response structure.

Parameters

  • attestationType: Extracted from the request
  • sourceId: Extracted from the request
  • votingRound: The ID of the FDC round in which the request was considered
  • lowestUsedTimestamp: The lowest timestamp used to generate the response (set to blockTimestamp)
  • requestBody: Extracted from the request
  • responseBody: Data defining the response

Proof

Top-level proof structure for verification.

Parameters

  • merkleProof: Merkle proof corresponding to the attestation response
  • data: Attestation response

RequestBody

Parameters

  • transactionId: Hash of the XRPL Payment transaction to verify
  • proofOwner: EVM address authorized to use the proof; lower-cased by the verifier

ResponseBody

Parameters

  • blockNumber: Ledger index containing the transaction
  • blockTimestamp: Ledger close time, converted to UNIX time
  • sourceAddress: The XRPL r-address of the sender
  • sourceAddressHash: Standard address hash of the source address
  • receivingAddressHash: Standard address hash of the receiver (zero bytes32 if the transaction did not succeed)
  • intendedReceivingAddressHash: Standard address hash of the address in the Destination field, relevant for failed transactions
  • spentAmount: Drops actually spent by the source
  • intendedSpentAmount: Drops the source intended to spend (Amount + Fee)
  • receivedAmount: Drops received by the receiver
  • intendedReceivedAmount: Drops the receiver would have received on success
  • hasMemoData: true if the transaction has at least one Memo with MemoData
  • firstMemoData: Raw bytes of the first Memo's MemoData; empty when hasMemoData is false
  • hasDestinationTag: true if the transaction has a DestinationTag
  • destinationTag: The destination tag value (0 when hasDestinationTag is false); XRPL only allows uint32 values
  • status: Transaction status (0 = SUCCESS, 1 = SENDER_FAILURE, 2 = RECEIVER_FAILURE)

Transaction Status Codes

Status CodeDescriptionExplanation
0SUCCESSTransaction completed successfully
1SENDER_FAILURETransaction failed due to issues on the sender's side
2RECEIVER_FAILURETransaction failed due to issues on the receiver's side

Implementation Notes

  • Attestation ID: 0x08
  • The lowestUsedTimestamp parameter uses the value of blockTimestamp
  • The lutlimit (Lowest Used Timestamp limit) is 0x127500 (1,209,600 seconds = 14 days)
  • Only XRPL Payment transaction type produces a response; other transaction types are rejected
  • Multi-output payments (tfPartialPayment resulting in multiple deliveries) are rejected
  • proofOwner lets a contract bind a proof to a specific caller; pass address(0) when not needed