diff options
| author | Adam Soltys <[email protected]> | 2026-06-15 13:17:26 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-15 13:17:26 -0700 |
| commit | 3dd7f8425ecf339332cc44b6f9734b51472d22c1 (patch) | |
| tree | e7eadb18256f0436c9aab671ded66acd0da7d713 /src | |
| parent | 3ecb137cc4300e60f00fbb575441f34e01839a8e (diff) | |
| download | coinosv3-3dd7f8425ecf339332cc44b6f9734b51472d22c1.tar.gz coinosv3-3dd7f8425ecf339332cc44b6f9734b51472d22c1.zip | |
Broadcast sends to all explorers in parallel
Post the signed tx to both mempool.space and Blockstream at once (outside the
throttle, since a send is urgent) so it's visible regardless of which explorer
the recipient watches. Succeeds if any accept; only fails if all do.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/api.js | 30 |
1 files changed, 15 insertions, 15 deletions
@@ -147,22 +147,22 @@ export class Api { return { fastestFee: 20, halfHourFee: 10, hourFee: 5, economyFee: 2, minimumFee: 1 }; } + // Broadcast to ALL explorers in parallel (not via the throttle — a send is + // urgent) so the tx is visible regardless of which explorer the recipient + // watches. Resolves with the txid if any accept it; rejects only if all fail. async broadcast(hexTx) { - let lastErr; - for (const base of this._hosts) { - try { - const res = await this.#run(base + '/tx', { method: 'POST', body: hexTx }); - const body = await res.text(); - if (!res.ok) { - lastErr = new Error(body || `${res.status} broadcast failed`); - continue; - } - return body.trim(); // txid - } catch (e) { - lastErr = e; - } - } - throw lastErr; + if (this.offline) throw new Error('offline'); + const attempts = this._hosts.map(async (base) => { + const res = await fetch(base + '/tx', { method: 'POST', body: hexTx }); + const body = await res.text(); + if (res.status === 429) this.#penalize(); + if (!res.ok) throw new Error(body || `${res.status} broadcast failed`); + return body.trim(); // txid + }); + const results = await Promise.allSettled(attempts); + const ok = results.find((r) => r.status === 'fulfilled'); + if (ok) return ok.value; + throw (results.find((r) => r.status === 'rejected') || {}).reason || new Error('broadcast failed'); } } |
