Invitation Format
The invitation is the data structure a seller's bot generates and shares with a prospective buyer. The buyer's wallet (or a manual review tool) reads it, the buyer signs the deploy bundle, and the contract goes live.
This document describes the invitation's JSON schema. Sophisticated buyers who want to verify an invitation independently of the bot's UI can read the JSON directly.
Note: this format will be finalized in Phase 4 of the build. The Phase 0 version below is the design intent; field names and exact structure may shift slightly as the spike validates the mechanics.
Top-level structure
{
"version": "1",
"option_id": "0x77a2…1c4f",
"kind": "put",
"seller": {
"wallet": "rN7n3Eq8kQpExampleAddressHere",
"deposit_asset": "XRP",
"deposit_amount": "1.000000"
},
"terms": {
"tenor_days": 15,
"premium_pct": 3,
"min_buyer_margin_pct": 10
},
"amm": {
"pair": "XRP/RLUSD",
"rate_at_creation": "0.5421",
"max_slippage_pct": 2
},
"expires_at": "2026-04-29T00:00:00Z",
"signature": "ed25519:abc123…def456"
}
Field-by-field
version
String. The invitation schema version. Currently "1". Future versions may change the schema; bots reject invitations with unknown versions.
option_id
Hex string. A unique identifier for this contract, generated by the seller's bot when the invitation is created. Used to:
- Bind all transactions in the deploy bundle together (via memo).
- Identify the contract in the bot's database.
- Reference the contract for revocation if the seller cancels before acceptance.
kind
String, one of "put" or "call". The contract type from the buyer's perspective:
put— buyer is bearish on XRP. Seller deposits XRP. Bot swaps XRP→RLUSD at deploy. RLUSD locks for the term.call— buyer is bullish on XRP. Seller deposits RLUSD. Bot swaps RLUSD→XRP at deploy. XRP locks for the term.
seller
Object describing the seller's deposit:
wallet— XRPL address of the seller. Where premium will be released to at settlement.deposit_asset—"XRP"or"RLUSD". Determined bykind(put → XRP, call → RLUSD).deposit_amount— string-encoded number, the size of the seller's deposit in their deposit asset. The notional of the contract is set by this amount.
terms
Object describing contract terms:
tenor_days— integer, one of 5, 10, 15, 30. The contract term in days.premium_pct— integer, one of 3, 4, 5, 6, 7, 8, 9, 10. The premium as a percentage of the seller's deposit value.min_buyer_margin_pct— integer, one of 5, 10, 15, 20. The minimum buyer margin the seller will accept. The buyer can offer this exact margin or higher (buyer margin is also enum-restricted to 5/10/15/20).
These three fields are enum-restricted. Bots reject invitations with values outside these enums.
amm
Object describing the AMM venue:
pair— currently always"XRP/RLUSD".rate_at_creation— string-encoded number, the AMM rate (RLUSD per XRP) at the moment the invitation was created. Used for max-slippage check at acceptance.max_slippage_pct— number, the maximum acceptable rate deviation between invitation creation and buyer acceptance. If the AMM rate at acceptance differs fromrate_at_creationby more than this percentage, the buyer's bot rejects the invitation as stale.
expires_at
ISO 8601 timestamp. The invitation expires at this time. After expiry, no buyer can accept it. The seller can re-issue a fresh invitation at any time.
Default expiry is 24 hours from creation, but sellers can set shorter or longer windows.
signature
Cryptographic signature over the rest of the invitation, signed by the seller's wallet. Format: ed25519:<hex>.
The buyer's bot verifies:
- The signature is valid for the seller's stated
walletfield. - The signing key has not been compromised (best-effort — the bot can check XRPL for
AccountSettransactions that might indicate key rotation).
How the buyer's bot uses an invitation
- Receive the invitation (paste, link, QR scan).
- Parse JSON, check schema version.
- Verify signature against seller's stated wallet.
- Check expiry is in the future.
- Check
option_idagainst on-chain revocation memos to see if the seller revoked. - Query the AMM for current rate; compare to
rate_at_creation. If deviation exceedsmax_slippage_pct, reject. - Display terms to the buyer in the UI.
- Buyer picks their margin from the allowed enum values (must be ≥
min_buyer_margin_pct). - Buyer signs the deploy bundle.
What the invitation does NOT contain
- The buyer's identity. Invitations are open — anyone with the link can accept (or be rejected by the deploy bundle if they're not on the seller's allow-list, if any).
- The buyer's chosen margin. The buyer picks at acceptance time.
- Pre-signed transactions. Those are constructed at deploy time, after the buyer accepts.
- The multisig wallet address. That is generated at deploy time.
- AMM pool address. The XRP/RLUSD AMM is canonical (largest pool by liquidity, hardcoded in the bot).
Verification independent of the bot
A sophisticated buyer who wants to verify an invitation without trusting their bot's UI can:
- Parse the JSON manually.
- Verify the signature using a standalone XRPL signing library (xrpl.js, xrpl-py, etc.).
- Compare the seller's wallet against the seller's public identity (their stated XRPL address on a website, in a forum post, wherever the seller publishes).
- Query the AMM rate manually via
amm_infoRPC against a public XRPL node. - Check on-chain transactions for
option_idrevocation memos.
This is the audit-friendly path. The bot's UI is convenience; the JSON and the chain are truth.
Revocation
A seller can revoke an unaccepted invitation by submitting a transaction from their wallet with a memo of the form:
{
"type": "revoke",
"option_id": "0x77a2…1c4f"
}
Memo format: hex-encoded JSON in the transaction's Memos field, with MemoType set to caput-revoke.
Buyer bots check for revocation memos before allowing acceptance. Revoked invitations cannot be deployed, even if the buyer has the original JSON.
Future versions
Schema changes will increment the version field. The bot's invitation parser is version-aware and rejects unknown versions. Backward compatibility for old versions will be maintained for at least one major release.