From 21967766b0694065b8fe95bcbc112ce8b257536b Mon Sep 17 00:00:00 2001 From: Felipe Knorr Kuhn Date: Tue, 3 Mar 2026 19:16:44 -0800 Subject: [PATCH 1/3] Fix electrum address validation --- backend/src/api/bitcoin/bitcoin.routes.ts | 12 ++++++++++++ backend/src/api/bitcoin/electrum-api.ts | 22 +++------------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/backend/src/api/bitcoin/bitcoin.routes.ts b/backend/src/api/bitcoin/bitcoin.routes.ts index fafcfdbcd..1ae865701 100644 --- a/backend/src/api/bitcoin/bitcoin.routes.ts +++ b/backend/src/api/bitcoin/bitcoin.routes.ts @@ -664,6 +664,10 @@ class BitcoinRoutes { const addressData = await bitcoinApi.$getAddress(req.params.address); res.json(addressData); } catch (e) { + if (e instanceof Error && e.message === 'Invalid Bitcoin address') { + handleError(req, res, 400, e.message); + return; + } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { handleError(req, res, 413, e.message); return; @@ -690,6 +694,10 @@ class BitcoinRoutes { const transactions = await bitcoinApi.$getAddressTransactions(req.params.address, lastTxId); res.json(transactions); } catch (e) { + if (e instanceof Error && e.message === 'Invalid Bitcoin address') { + handleError(req, res, 400, e.message); + return; + } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { handleError(req, res, 413, e.message); return; @@ -712,6 +720,10 @@ class BitcoinRoutes { const addressData = await bitcoinApi.$getAddressUtxos(req.params.address); res.json(addressData); } catch (e) { + if (e instanceof Error && e.message === 'Invalid Bitcoin address') { + handleError(req, res, 400, e.message); + return; + } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { handleError(req, res, 413, e.message); return; diff --git a/backend/src/api/bitcoin/electrum-api.ts b/backend/src/api/bitcoin/electrum-api.ts index aa9765420..bf9a28c5d 100644 --- a/backend/src/api/bitcoin/electrum-api.ts +++ b/backend/src/api/bitcoin/electrum-api.ts @@ -44,23 +44,7 @@ class BitcoindElectrsApi extends BitcoinApi implements AbstractBitcoinApi { async $getAddress(address: string): Promise { const addressInfo = await this.bitcoindClient.validateAddress(address); if (!addressInfo || !addressInfo.isvalid) { - return ({ - 'address': address, - 'chain_stats': { - 'funded_txo_count': 0, - 'funded_txo_sum': 0, - 'spent_txo_count': 0, - 'spent_txo_sum': 0, - 'tx_count': 0 - }, - 'mempool_stats': { - 'funded_txo_count': 0, - 'funded_txo_sum': 0, - 'spent_txo_count': 0, - 'spent_txo_sum': 0, - 'tx_count': 0 - } - }); + throw new Error('Invalid Bitcoin address'); } try { @@ -96,7 +80,7 @@ class BitcoindElectrsApi extends BitcoinApi implements AbstractBitcoinApi { async $getAddressTransactions(address: string, lastSeenTxId: string): Promise { const addressInfo = await this.bitcoindClient.validateAddress(address); if (!addressInfo || !addressInfo.isvalid) { - return []; + throw new Error('Invalid Bitcoin address'); } try { @@ -166,7 +150,7 @@ class BitcoindElectrsApi extends BitcoinApi implements AbstractBitcoinApi { async $getAddressUtxos(address: string): Promise { const addressInfo = await this.bitcoindClient.validateAddress(address); if (!addressInfo || !addressInfo.isvalid) { - return []; + throw new Error('Invalid Bitcoin address'); } const scripthash = this.encodeScriptHash(addressInfo.scriptPubKey); return this.$getScriptHashUtxos(scripthash); From 18e378f73a588c2f6f9759d548ccc5341d098856 Mon Sep 17 00:00:00 2001 From: Felipe Knorr Kuhn Date: Tue, 3 Mar 2026 19:56:58 -0800 Subject: [PATCH 2/3] Don't send the error as json --- backend/src/api/bitcoin/bitcoin.routes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/api/bitcoin/bitcoin.routes.ts b/backend/src/api/bitcoin/bitcoin.routes.ts index 1ae865701..237a7caec 100644 --- a/backend/src/api/bitcoin/bitcoin.routes.ts +++ b/backend/src/api/bitcoin/bitcoin.routes.ts @@ -665,7 +665,7 @@ class BitcoinRoutes { res.json(addressData); } catch (e) { if (e instanceof Error && e.message === 'Invalid Bitcoin address') { - handleError(req, res, 400, e.message); + res.status(400).send(e.message); return; } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { @@ -695,7 +695,7 @@ class BitcoinRoutes { res.json(transactions); } catch (e) { if (e instanceof Error && e.message === 'Invalid Bitcoin address') { - handleError(req, res, 400, e.message); + res.status(400).send(e.message); return; } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { @@ -721,7 +721,7 @@ class BitcoinRoutes { res.json(addressData); } catch (e) { if (e instanceof Error && e.message === 'Invalid Bitcoin address') { - handleError(req, res, 400, e.message); + res.status(400).send(e.message); return; } if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) { From c537a3f2544991fef2a6ce9603482920cfb4d938 Mon Sep 17 00:00:00 2001 From: Felipe Knorr Kuhn Date: Tue, 3 Mar 2026 20:44:39 -0800 Subject: [PATCH 3/3] Do not send user to mempool.space on 400 errors --- frontend/src/app/components/address/address.component.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frontend/src/app/components/address/address.component.html b/frontend/src/app/components/address/address.component.html index b0d4c73da..0a2b0e2ed 100644 --- a/frontend/src/app/components/address/address.component.html +++ b/frontend/src/app/components/address/address.component.html @@ -249,11 +249,6 @@

Consider viewing this address on the official Mempool website instead: - } @else if (!officialMempoolSpace) { -
- Consider viewing this address on the official Mempool website instead: - } - @if (!officialMempoolSpace) {
https://mempool.space/address/{{ addressString }}