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
| what | where | used for |
|---|---|---|
| SUBFROST Bitcoin + alkanes API | https://mainnet.subfrost.io/v4/jsonrpc with your API key (authentication) | alkane balances, the views (GetLimits, GetBurnsByHeight, GetPendingLimits), broadcasting burns |
| frXRP gateway | https://fr1q4mgjev2fnzp2z2p0hwv89q59pxnq8r07px97rcrfkptdhlw6vyqcwkl7e.fr.style | registering a deposit intent and getting its deposit address |
| XRP Ledger | any public rippled or Clio server, ideally more than one | paying deposit addresses, watching the group account for payouts |
| Solana | any Solana RPC | calling the frSOL vault's deposit, watching payouts |
| frSOL vault, frXRP group account, frADA vault | 25oyhHXj19hFvtut2Vd9fq3u3E2YJrHwQXoY7vRFpfBb (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
-
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. -
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
409means the gateway disagrees with your derivation: stop, don't pay. -
Pay at least 2 XRP to
Dwith a plainPayment. Never a Check, Escrow, payment channel or trust line. -
Wait for the sweep: an
AccountDeleteofDinto the group account with anfrxrp/intentmemo. The XRP Ledger only lets an account be deleted 256 ledgers after it was created, about 15–20 minutes. -
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
- 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.
- Check the limits. Read
GetLimits(opcode 22): the burn must not exceedmax_burn(word 4). ReadGetPendingLimits(opcode 23) if you depend on a limit staying where it is. - 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.
- Simulate before you broadcast, then broadcast and keep the txid.
- Wait for 3 Bitcoin confirmations (about 30 minutes). The group then pays the burns in Bitcoin order.
- Match the payout to your burn by its id. Your burn's id is
(height, index): its block height and its position inGetBurnsByHeightat that height.- frXRP: a
Paymentfrom the group account whosefrxrp/payoutmemo carries the 12-byte id (height u64 LE ‖ index u32 LE);frxrp/voidmeans voided. - frSOL: a
withdrawwhose memo starts withfrsol:burn:<height>:<index>. Large payouts arrive in parts, so match on the prefix.
- frXRP: a
Timing
| step | typical time |
|---|---|
| frXRP deposit → sweep | 256 XRP Ledger ledgers, about 15–20 minutes |
| sweep or Solana deposit → mint | a few Bitcoin blocks |
| burn → payout | 3 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.