diff options
| author | Adam Soltys <[email protected]> | 2026-06-15 21:10:56 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-15 21:10:56 -0700 |
| commit | 011d18f65ca7895260370bbc2d29b513705593e3 (patch) | |
| tree | 28bf6f8926620e6853b643603aa8ae0efabe2043 | |
| parent | 36057966438b26327285e43ee00ce4895fd179c3 (diff) | |
| download | coinosv3-011d18f65ca7895260370bbc2d29b513705593e3.tar.gz coinosv3-011d18f65ca7895260370bbc2d29b513705593e3.zip | |
Route explorer traffic through VPS proxy (temporary)
This IP is rate-limited/banned by mempool.space, so REST + WS now go through
an nginx CORS proxy on the OVH VPS (mempool via /mp, blockstream via /bs).
Controlled by a single PROXY constant in api.js — set it to '' to revert to
the public explorers once the ban is lifted. Hosts are tagged by kind so fee
format detection still works.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
| -rw-r--r-- | src/api.js | 40 | ||||
| -rw-r--r-- | src/wallet.js | 6 |
2 files changed, 36 insertions, 10 deletions
@@ -6,10 +6,38 @@ // - a 429 from ANY request immediately backs off ALL subsequent requests // (global exponential pause), easing back as requests succeed. -const BACKENDS = { - mainnet: ['https://mempool.space/api', 'https://blockstream.info/api'], - testnet: ['https://mempool.space/testnet/api', 'https://blockstream.info/testnet/api'], -}; +// TEMPORARY: route explorer traffic through a VPS while this IP is rate-limited +// by mempool.space. Set PROXY = '' to go back to the public explorers directly. +const PROXY = 'http://51.79.52.200:8088'; + +const BACKENDS = PROXY + ? { + mainnet: [ + { base: `${PROXY}/mp/api`, kind: 'mempool' }, + { base: `${PROXY}/bs/api`, kind: 'esplora' }, + ], + testnet: [ + { base: `${PROXY}/mp/testnet/api`, kind: 'mempool' }, + { base: `${PROXY}/bs/testnet/api`, kind: 'esplora' }, + ], + } + : { + mainnet: [ + { base: 'https://mempool.space/api', kind: 'mempool' }, + { base: 'https://blockstream.info/api', kind: 'esplora' }, + ], + testnet: [ + { base: 'https://mempool.space/testnet/api', kind: 'mempool' }, + { base: 'https://blockstream.info/testnet/api', kind: 'esplora' }, + ], + }; + +// WebSocket URL (mempool) — through the proxy when configured. +export function wsUrl(net) { + const path = net === 'testnet' ? '/testnet/api/v1/ws' : '/api/v1/ws'; + if (PROXY) return PROXY.replace(/^http/, 'ws') + '/mp' + path; + return 'wss://mempool.space' + path; +} const REQUEST_TIMEOUT_MS = 10000; @@ -20,7 +48,7 @@ export class Api { // Hosts are tried in order (mempool first); a host that 429s is parked on // cooldown so we stop hammering it (Blockstream rate-limits aggressively). - this._hosts = (BACKENDS[net] || BACKENDS.mainnet).map((base) => ({ base, cooldownUntil: 0 })); + this._hosts = (BACKENDS[net] || BACKENDS.mainnet).map((h) => ({ ...h, cooldownUntil: 0 })); this._timeoutMs = REQUEST_TIMEOUT_MS; // Serialized scheduler: one request at a time, min gap between starts. @@ -162,7 +190,7 @@ export class Api { async feeRates() { for (const host of this._hosts) { if (host.cooldownUntil > Date.now()) continue; - const isMempool = host.base.includes('mempool'); + const isMempool = host.kind === 'mempool'; try { const res = await this.#run(host, isMempool ? '/v1/fees/recommended' : '/fee-estimates'); if (!res.ok) continue; diff --git a/src/wallet.js b/src/wallet.js index 241572a..b3c6a25 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -16,7 +16,7 @@ import { sha256 } from '@noble/hashes/sha256'; import * as btc from '@scure/btc-signer'; import { p2wpkh } from '@scure/btc-signer/payment'; -import { Api, pool } from './api.js'; +import { Api, pool, wsUrl } from './api.js'; // No look-ahead: stop scanning a chain at the first unused address. This wallet // only ever exposes ONE unused address at a time (freshReceive = first unused; @@ -481,9 +481,7 @@ export class Wallet { // Pushes us new mempool/confirmed transactions for our addresses so history // and balances update with no polling. wsUrl() { - return this.netName === 'testnet' - ? 'wss://mempool.space/testnet/api/v1/ws' - : 'wss://mempool.space/api/v1/ws'; + return wsUrl(this.netName); } // Addresses worth watching: those holding coins (to catch spends) plus a |
