From 011d18f65ca7895260370bbc2d29b513705593e3 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 15 Jun 2026 21:10:56 -0700 Subject: Route explorer traffic through VPS proxy (temporary) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/api.js | 40 ++++++++++++++++++++++++++++++++++------ src/wallet.js | 6 ++---- 2 files changed, 36 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/api.js b/src/api.js index 5d0da77..0135369 100644 --- a/src/api.js +++ b/src/api.js @@ -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 -- cgit v1.2.3