From ba5e28249aac75310303174ac48b4c67b67224cb Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 5 Jul 2026 22:06:51 -0700 Subject: Exit works on plain-esplora regtest; human-readable ark status lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit submitPackage falls back to sequential /tx posts when the esplora lacks POST /txs/package (regtest electrs) — works wherever the node relays zero-fee v3 parents. The ark card stops speaking developer: in-flight operations summarize as '{n} deposit(s) confirming' instead of 'board:funded, exit:chain, …', exit lines read 'Exiting N sats — publishing on-chain…', and transient errors show 'hit a snag — retrying automatically' instead of raw gRPC/HTTP text. Co-Authored-By: Claude Fable 5 --- src/ark/exit.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/ark/exit.js') diff --git a/src/ark/exit.js b/src/ark/exit.js index 2770284..9310b65 100644 --- a/src/ark/exit.js +++ b/src/ark/exit.js @@ -150,11 +150,22 @@ export function buildExitClaim({ vtxo, keys, serverPub, destScript, feeRate }) { // Submit a [parent, child] (or single-tx) package via esplora -> bitcoind // submitpackage. Treats already-known txs as success so retries are safe. +// Esploras without the endpoint (regtest electrs) fall back to sequential +// /tx posts — which relays only if the node accepts zero-fee v3 parents +// (regtest with -minrelaytxfee=0); otherwise the node's error surfaces. export async function submitPackage(esploraBase, hexes) { const r = await fetch(`${esploraBase}/txs/package`, { method: 'POST', body: JSON.stringify(hexes) }); const body = await r.text(); - if (!r.ok && !/already|duplicate/i.test(body)) { - throw new Error(`package submit failed: ${body.slice(0, 160)}`); + if (r.ok || /already|duplicate/i.test(body)) return body; + if (r.status === 404 || /endpoint does not exist/i.test(body)) { + for (const hx of hexes) { + const br = await fetch(`${esploraBase}/tx`, { method: 'POST', body: hx }); + const bb = await br.text(); + if (!br.ok && !/already|duplicate/i.test(bb)) { + throw new Error(`broadcast failed: ${bb.slice(0, 160)}`); + } + } + return 'sequential'; } - return body; + throw new Error(`package submit failed: ${body.slice(0, 160)}`); } -- cgit v1.2.3