aboutsummaryrefslogtreecommitdiffstats
path: root/src/api.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-06-25 09:39:14 -0700
committerAdam Soltys <[email protected]>2026-06-25 09:39:14 -0700
commita2bb363e2c86dc845e6748e046c8d489e656c584 (patch)
tree04bd4a631cc6b1a6b1356a75ff20f93fa4632fb2 /src/api.js
parent554716b916c5b4c4ca39bf6344f840c62a0da54a (diff)
downloadcoinosv3-a2bb363e2c86dc845e6748e046c8d489e656c584.tar.gz
coinosv3-a2bb363e2c86dc845e6748e046c8d489e656c584.zip
Realtime via self-hosted ZMQ watcher (Electrum-over-WS)
Replace the unreliable public WebSocket push (mempool/blockchain.info address subscriptions never reliably fire) with a private notification service: - tools/zmq-watcher.js: a standalone Bun service (reusing coinos lib/zmq.ts's ZMTP subscriber) that reads Bitcoin Core's ZMQ rawtx/rawblock, computes the scripthash of each output, and pushes a blockchain.scripthash.subscribe notification to subscribed clients. No historical index (~24MB RAM) — just the live tx stream. Runs on the coinos box reading its Core's ZMQ. - wallet.js: realtime client now speaks the Electrum protocol (server.version, scripthash.subscribe, server.ping) over the WS; any scripthash notification triggers the existing refreshLive() (REST stays the source of truth). - api.js: wsUrl -> wss://coinos.io/electrum. Verified end-to-end: live mempool txs to subscribed addresses notify instantly. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src/api.js')
-rw-r--r--src/api.js21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/api.js b/src/api.js
index 08f03b2..20041e2 100644
--- a/src/api.js
+++ b/src/api.js
@@ -45,11 +45,24 @@ function resolveHosts(net) {
return [host('https://mempool.space', 'mempool'), host('https://blockstream.info', 'esplora')];
}
-// WebSocket URL for live updates — only mempool.space exposes one, so other
-// explorers fall back to polling (returns null → no socket).
+// Realtime is a private Fulcrum (Electrum protocol over WebSocket-Secure). It
+// reliably pushes a scripthash-status notification the moment a tx touches a
+// watched address — unlike the public Esplora/blockchain.info sockets, whose
+// address push doesn't fire. Independent of the REST explorer choice. Mainnet
+// only; testnet falls back to polling (null). Overridable for staging/testing.
+const ELECTRUM_KEY = 'btc-wallet-electrum';
+export function getElectrumWsUrl() {
+ try {
+ const u = localStorage.getItem(ELECTRUM_KEY);
+ if (u) return u;
+ } catch {}
+ // Served as a path under coinos.io (a dedicated subdomain hit a Cloudflare
+ // WebSocket quirk; the main hostname proxies WS cleanly).
+ return 'wss://coinos.io/electrum';
+}
export function wsUrl(net) {
- if (getExplorerConfig().server !== 'mempool') return null;
- return 'wss://mempool.space' + (net === 'testnet' ? '/testnet/api/v1/ws' : '/api/v1/ws');
+ if (net === 'testnet') return null;
+ return getElectrumWsUrl();
}
const REQUEST_TIMEOUT_MS = 10000;