diff options
| author | Adam Soltys <[email protected]> | 2026-07-06 14:55:40 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-06 14:55:40 -0700 |
| commit | 312621af84136fddbe7d7e47ffecc1ba2b38920d (patch) | |
| tree | 6090489ef5ae7bac16a25340bd2c11f426079cbb /src/electrum.js | |
| parent | d071a09604599831d370b06563144cf4ba028902 (diff) | |
| download | coinosv3-312621af84136fddbe7d7e47ffecc1ba2b38920d.tar.gz coinosv3-312621af84136fddbe7d7e47ffecc1ba2b38920d.zip | |
Fee rates from live explorer + reconnect half-open socket on wake
- Fee rates on the electrum backend came from Fulcrum's estimatefee
(Core's estimatesmartfee): historical, laggy, floored at 1 sat/vB, so
it showed 1 across the board while mempool.space showed 11/10. Pull the
configured explorer's live recommendation instead (/v1/fees/recommended,
then /fee-estimates), falling back to estimatefee only when the explorer
is unreachable — self-hosted/regtest behaviour unchanged.
- On mobile a backgrounded page leaves the socket half-open: TCP is dead
but readyState still reads OPEN, so wake() never reconnected and fired
scan RPCs into the void, waiting ~20s for the heartbeat to recover.
wake() now forces a reconnect when the socket has been silent past the
heartbeat window, so a payment shows the instant you refocus.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Diffstat (limited to 'src/electrum.js')
| -rw-r--r-- | src/electrum.js | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/electrum.js b/src/electrum.js index b8ca164..fb61298 100644 --- a/src/electrum.js +++ b/src/electrum.js @@ -16,6 +16,7 @@ import * as btc from '@scure/btc-signer'; import { sha256 } from '@noble/hashes/sha256'; import { hexToBytes, bytesToHex } from '@noble/hashes/utils'; +import { mapEsploraFees } from './api.js'; const RAW_OPTS = { allowUnknownOutputs: true, allowUnknownInputs: true, disableScriptCheck: true }; @@ -214,7 +215,27 @@ export class ElectrumApi { } // ---- fees + broadcast -------------------------------------------------- + // Fee rates come from the configured block explorer's live recommendation + // (mempool.space projects the next block from actual mempool contents), NOT + // from Fulcrum's blockchain.estimatefee — that wraps Bitcoin Core's + // estimatesmartfee, which works off historical confirmation data, lags the + // mempool badly, and floors at 1 sat/vB, so it reports 1 across the board in + // normal conditions. estimatefee is only the last resort when the explorer is + // unreachable (regtest, or a self-hosted node with no REST explorer). async feeRates() { + const web = this._explorerWeb; + if (web && !this.offline) { + // mempool.space shape first (the live next-block projection)… + try { + const r = await fetch(`${web}/api/v1/fees/recommended`); + if (r.ok) { const d = await r.json(); if (d && d.halfHourFee) return d; } + } catch {} + // …then the plain-Esplora /fee-estimates shape. + try { + const r = await fetch(`${web}/api/fee-estimates`); + if (r.ok) { const d = await r.json(); if (d && Object.keys(d).length) return mapEsploraFees(d); } + } catch {} + } const targets = { fastestFee: 1, halfHourFee: 3, hourFee: 6, economyFee: 144, minimumFee: 1008 }; const out = {}; await Promise.all(Object.entries(targets).map(async ([k, n]) => { |
