@bitcoinerlab/explorer is a library that provides a common interface for interacting with various blockchain explorer services like Esplora and Electrum. The library aims to standardize the way developers access the functionality provided by these services and enable easy integration with the @bitcoinerlab ecosystem.
- A consistent interface for interacting with different explorer services
- Connection lifecycle methods:
connect,isConnected,isClosed,close - Fetch confirmed/unconfirmed balances and tx counts for addresses and script hashes
- Fetch fee estimates based on confirmation targets
npm install @bitcoinerlab/explorer- Node.js 18 or newer
Depending on the specific client you wish to use (Electrum or Esplora), there are different considerations to keep in mind.
-
Install Required Modules:
npm install @bitcoinerlab/explorer react-native-tcp-socket
-
Eject from Expo (if in use):
npx expo prebuild cd ios && pod install && cd ..
-
Shim
net&tlsby adding these lines to yourpackage.json:
"react-native": {
"net": "react-native-tcp-socket",
"tls": "react-native-tcp-socket"
}-
Set Up Global Variables: Create an
electrumSupport.jsfile that you must import at the entry point of your application (before any other imports). This file should contain the following code:global.net = require('react-native-tcp-socket'); global.tls = require('react-native-tcp-socket');
If you're integrating the Esplora client within a React Native environment, you might encounter the error "URL.protocol is not implemented". This arises because React Native doesn't have a full implementation of the browser's URL class.
To address this:
-
Install the URL Polyfill:
npm install @bitcoinerlab/explorer react-native-url-polyfill
-
Integrate the Polyfill:
At the top of your entry file (e.g.,
index.jsorApp.js), include:import 'react-native-url-polyfill/auto';
This polyfill will provide the missing
URLfunctionalities in React Native, ensuring the Esplora client operates without issues.
This library provides a unified interface for interacting with Bitcoin Blockchain explorers. Currently, it supports two popular explorers: Esplora and Electrum.
The following methods are shared in all implementations:
connect(): Establish a connection to the server.isConnected(): Check if the server is reachable and responsive.isClosed(): Check whether the client is currently closed.close(): Terminate the connection.fetchAddress(address: string): Retrieve confirmed/unconfirmed balance and transaction count details for a Bitcoin address. This returns an object with:balance: Confirmed balance in satoshis.txCount: Number of confirmed transactions.unconfirmedBalance: Unconfirmed balance delta in satoshis.unconfirmedTxCount: Number of unconfirmed transactions.
fetchScriptHash(scriptHash: string): Acts similar tofetchAddressbut for a script hash.fetchTxHistory({ address?: string; scriptHash?: string; }): Acquires the transaction history for a specific address or script hash. The function returns a promise that resolves to an array of transaction histories. Each entry is an object that contains:txId: stringblockHeight: numberirreversible: booleanNote: They're typically returned in blockchain order. But there's a known issue with Esplora where transactions from the same block might not maintain this order.
fetchFeeEstimates(): Obtain fee predictions based on confirmation targets. It returns an object where keys are confirmation targets and values are the projected feerate (measured in sat/vB).fetchBlockStatus(blockHeight: number): Retrieve block metadata at a given height (blockHash,blockTime,irreversible), orundefinedif that height is not mined yet.fetchBlockHeight(): Determine the current block tip height.fetchTx(txId: string): Fetch a raw transaction in hex format.push(txHex: string): Submit a transaction in hex format.
In this section, we demonstrate how to use the existing implementations, Esplora and Electrum, provided by this library. You can also create your own implementations following the Explorer interface to work with other services.
Here's an example of how to use the EsploraExplorer class:
import { EsploraExplorer } from '@bitcoinerlab/explorer';
(async () => {
const explorer = new EsploraExplorer({ url: 'https://blockstream.info/api' });
// Connect to the Esplora server
await explorer.connect();
// Fetch address information (returns a Promise)
const addressInfo = await explorer.fetchAddress(
'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'
);
// Fetch script-hash information (returns a Promise)
const scriptHashInfo = await explorer.fetchScriptHash(
'<scripthash>'
);
// Fetch transaction history by address
const txHistory = await explorer.fetchTxHistory({
address:
'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'
});
// Fetch raw transaction hex
const txHex = await explorer.fetchTx('<txid>');
// Broadcast a signed transaction
// const txId = await explorer.push('<raw-transaction-hex>');
// Check connected status
const alive = await explorer.isConnected();
console.log({ addressInfo, scriptHashInfo, txHistory, txHex, alive });
// Fetch fee estimates (returns a Promise)
const feeEstimates = await explorer.fetchFeeEstimates();
// Close the connection
explorer.close();
})();To use the ElectrumExplorer class, follow a similar pattern but with different constructor parameters:
import { ElectrumExplorer } from '@bitcoinerlab/explorer';
(async () => {
const explorer = new ElectrumExplorer({
host: 'electrum.example.com',
port: 50002,
protocol: 'ssl'
});
await explorer.connect();
const tipHeight = await explorer.fetchBlockHeight();
console.log({ tipHeight });
explorer.close();
})();EsploraExplorer and ElectrumExplorer both accept irrevConfThresh, maxTxPerScriptPubKey, and timeout. EsploraExplorer also accepts requestQueueParams. irrevConfThresh controls the number of confirmations required to consider a transaction irreversible (default: 3). maxTxPerScriptPubKey sets an upper bound on history length per address/script hash (default: 1000). timeout is in milliseconds and defaults to 0 (disabled). If you expect heavily reused addresses, you may increase maxTxPerScriptPubKey, at the cost of performance.
To generate the API documentation for this module, you can run the following command:
npm run docsHowever, if you'd prefer to skip this step, the API documentation has already been compiled and is available for reference at bitcoinerlab.com/modules/explorer/api.
The project was initially developed and is currently maintained by Jose-Luis Landabaso. Contributions and help from other developers are welcome.
Here are some resources to help you get started with contributing:
To download the source code and build the project, follow these steps:
- Clone the repository:
git clone https://github.com/bitcoinerlab/explorer.git- Install the dependencies:
npm install- Build the project:
npm run buildThis will build the project and generate the necessary files in the dist directory.
Before finalizing and committing your code, it's essential to make sure all tests are successful. To run these tests:
- A Bitcoin regtest node must be active.
- Utilize the Express-based bitcoind manager which should be operational at
127.0.0.1:8080. - An Electrum server and an Esplora server are required, both indexing the regtest node.
To streamline this setup, you can use the Docker image, bitcoinerlab/tape, which comes preconfigured with the required services. When you run the test script using:
npm testit will automatically download and start the Docker image if it's not already present on your machine. However, ensure you have the docker binary available in your path for this to work seamlessly.
This project is licensed under the MIT License.