Files
bridge/internal
zeekay 4a75d55b8d feat(broadcast): XRP submit via rippled JSON-RPC
internal/broadcast/xrp.go: XRP-family broadcaster targeting rippled's
`submit` method.

- Wire: POST {method:"submit", params:[{tx_blob:"<hex>"}]} to
  https://s1.ripple.com:51234/ (mainnet) or
  https://s.altnet.rippletest.net:51234/ (testnet). Strips a 0x prefix
  if the caller (every other broadcaster in this package emits 0x...)
  appends one — rippled rejects 0x-prefixed blobs.
- classifyEngineResult: maps rippled's engine_result codes to one of
  success / retryable / fatal:
    tesSUCCESS         → success → return result.tx_json.hash
    ter*               → retryable (broadcast driver re-submits)
    tel*               → retryable (local server, may resolve next round)
    tec* / tem* / tef* → fatal (consumed-fee failure, malformed, or
                          server-rejected past-seq / already / etc.)
    unknown / empty    → retryable (rippled wasn't sure yet)
  Behaviour matches xrpl.org/transaction-results.html.
- doPlainJSON helper added to client.go: rippled is JSON-RPC-shaped
  (method, params) but does NOT emit the {jsonrpc,id,result,error}
  2.0 envelope, so it needs its own POST/decode helper.
- Broadcast() dispatch grows an AddressTypeXRP arm.
- rpcURLs table grows XRP_MAINNET + XRP_TESTNET defaults; operators
  shadow per-env via --source-rpc-overrides.

Tests: tesSUCCESS happy path (returns tx_json.hash), terQUEUED
retryable, tecINSUFFICIENT_FUNDS + tecNO_DST fatal, temBAD_AMOUNT
malformed fatal, telINSUF_FEE_P retryable, high-level rippled error
surfaced as RPCError, network transport error, success-without-hash
rejection, 0x-prefix stripping, classifyEngineResult table.
2026-05-27 17:59:02 -07:00
..
2026-05-27 14:49:55 +02:00
2026-05-27 14:49:55 +02:00