Skip to main content

Agents and Automation

Every step of an fr* deposit or redemption can be driven by a program: there is no web form in the path and nobody approves anything by hand. This page is for trading bots, market makers and AI agents that move value between Bitcoin and other chains through frSOL, frXRP, frADA and the assets that follow them. The byte formats it points to are in the developer reference.

What an agent talks to​

whatwhereused for
SUBFROST Bitcoin + alkanes APIhttps://mainnet.subfrost.io/v4/jsonrpc with your API key (authentication)alkane balances, the views (GetLimits, GetBurnsByHeight, GetPendingLimits), broadcasting burns
frXRP gatewayhttps://fr1q4mgjev2fnzp2z2p0hwv89q59pxnq8r07px97rcrfkptdhlw6vyqcwkl7e.fr.styleregistering a deposit intent and getting its deposit address
XRP Ledgerany public rippled or Clio server, ideally more than onepaying deposit addresses, watching the group account for payouts
Solanaany Solana RPCcalling the frSOL vault's deposit, watching payouts
frSOL vault, frXRP group account, frADA vault25oyhHXj19hFvtut2Vd9fq3u3E2YJrHwQXoY7vRFpfBb (frSOL), rD86YcZ35wxoTJEhrtmascwW932h2Qa7yE (frXRP), addr1w8a45tdfg0wnxtpcnuna7l4nez84m3n5w74ulvlsj63jlhgwqd6cr (frADA)the custody you can audit at any time

The gateway holds no keys and can't redirect anything, but an agent should still verify what it returns (below).

For AI agents: these docs are published in plain text for language models at docs.subfrost.io/llms.txt (an index) and docs.subfrost.io/llms-full.txt (everything). Load the relevant pages into context rather than relying on what a model remembers.

Loop 1: coin in, alkane out​

frXRP

  1. Derive the deposit address D(intent) yourself from the group key and your intent bytes (formula and test vectors). Use a version-2 intent with a refund account you control.

  2. Register it, passing your own result as expected_address:

    curl -s https://fr1q4mgjev2fnzp2z2p0hwv89q59pxnq8r07px97rcrfkptdhlw6vyqcwkl7e.fr.style/v1/intent \
    -H 'content-type: application/json' \
    -d '{"recipient_address": "bc1p…your taproot address…",
    "refund_address": "r…your XRP account…",
    "expected_address": "r…the D you derived…"}'

    A 409 means the gateway disagrees with your derivation: stop, don't pay.

  3. Pay at least 2 XRP to D with a plain Payment. Never a Check, Escrow, payment channel or trust line.

  4. Wait for the sweep: an AccountDelete of D into the group account with an frxrp/intent memo. The XRP Ledger only lets an account be deleted 256 ledgers after it was created, about 15–20 minutes.

  5. Wait for the mint on Bitcoin. Poll your recipient's frXRP balance until it rises by the swept amount less 0.10%. It normally lands within a few blocks of the sweep.

frSOL: call the vault's deposit instruction with your recipient script (instruction layout). The mint follows once the deposit record is finalized on Solana.

Loop 2: alkane in, coin out​

  1. Check the destination first. For XRP: it is not the group account, it exists or the payout covers the base reserve, it has no deposit authorization, and you have a tag if it requires one. For Solana: it is a plain wallet key. A burn the group can't pay is voided, and the alkane is already gone.
  2. Check the limits. Read GetLimits (opcode 22): the burn must not exceed max_burn (word 4). Read GetPendingLimits (opcode 23) if you depend on a limit staying where it is.
  3. Build the burn with an exact amount. The burn protostone burns everything it receives, so use Shape A or Shape B from Getting the amount right. This is where a careless agent loses funds: an edict inside the burn protostone does not limit it.
  4. Simulate before you broadcast, then broadcast and keep the txid.
  5. Wait for 3 Bitcoin confirmations (about 30 minutes). The group then pays the burns in Bitcoin order.
  6. Match the payout to your burn by its id. Your burn's id is (height, index): its block height and its position in GetBurnsByHeight at that height.
    • frXRP: a Payment from the group account whose frxrp/payout memo carries the 12-byte id (height u64 LE ‖ index u32 LE); frxrp/void means voided.
    • frSOL: a withdraw whose memo starts with frsol:burn:<height>:<index>. Large payouts arrive in parts, so match on the prefix.

Timing​

steptypical time
frXRP deposit → sweep256 XRP Ledger ledgers, about 15–20 minutes
sweep or Solana deposit → minta few Bitcoin blocks
burn → payout3 Bitcoin confirmations, about 30 minutes, then the next signing round

A payout waits, rather than failing, if the window's payout cap is used up or a read provider is unavailable. Build your agent to wait and re-check, not to resend.

Rules for agents​

  • Idempotent, never repeated. A burn is paid at most once; a second burn is a second redemption. Never "retry" a burn because a payout looks slow. Check the burn's confirmations and the payout memo instead.
  • Derive, don't trust. Recompute deposit addresses and release intents yourself, and compare.
  • Start small. Send a small amount through any new path before moving size.
  • Respect the caps. A transfer above one window's cap waits for the next window. Split large flows across windows, or across assets.
  • Read more than one source for the foreign chain, as the signer group does.
  • Keep keys out of the model. If an AI model plans the steps, let a separate signer that enforces these rules hold the keys and sign. The model should never see a private key.

Auditing custody​

Everything that backs the fr* assets is on public chains:

  • each alkane's supply comes from its view opcodes;
  • the frSOL vault and the frXRP group account balances can be read from any RPC;
  • every mint, sweep and payout carries a memo that ties it back to Bitcoin.

An agent that holds size can, and should, check that custody covers supply before it trusts a path. frZEC is designed around exactly this check.