Blockstream Bitcoin Provider
Fetch Bitcoin chain data and submit transactions via the public Blockstream Esplora API — no API key required.
Overview
Blockstream operates a public Esplora REST API for Bitcoin mainnet and testnet. BlockstreamBitcoinProvider wraps this API and implements IBitcoinProvider from @meshsdk/provider, making it a drop-in data source for BitcoinHeadlessWallet.
When to use Blockstream:
- Development and prototyping — no account or API key required
- Low-to-medium volume production applications
- Testnet development before deploying to mainnet
For authenticated production access, use BlockstreamEnterpriseBitcoinProvider. Both providers share the same Esplora REST methods via an internal HTTP client.
Quick Start
npm install @meshsdk/provider @meshsdk/walletimport { BlockstreamBitcoinProvider } from "@meshsdk/provider";
import { BitcoinHeadlessWallet } from "@meshsdk/wallet";
const provider = new BlockstreamBitcoinProvider("testnet"); // "mainnet" | "testnet"
const wallet = await BitcoinHeadlessWallet.fromMnemonic({
network: "Testnet4",
mnemonic: ["word1", "word2", "..."],
provider,
});
const balance = await wallet.getBalance();
// { confirmed: "100000", unconfirmed: "0", total: "100000" }Configuration Options
| Parameter | Type | Required | Description |
|---|---|---|---|
network | "mainnet" | "testnet" | Yes | Bitcoin network to connect to |
The base URLs used internally:
| Network | Base URL |
|---|---|
"mainnet" | https://blockstream.info/api |
"testnet" | https://blockstream.info/testnet/api |
API Reference
fetchAddressInfo
Retrieve chain and mempool statistics for a Bitcoin address.
await provider.fetchAddressInfo(address: string): Promise<BitcoinAddressInfo>| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Bitcoin address (bech32, P2PKH, P2SH, etc.) |
Returns: BitcoinAddressInfo — confirmed and mempool funding/spending counts and sums.
Example:
import { BlockstreamBitcoinProvider } from "@meshsdk/provider";
const provider = new BlockstreamBitcoinProvider("mainnet");
const info = await provider.fetchAddressInfo("bc1q...");
console.log(info.chain_stats.funded_txo_sum); // total confirmed received (sats)
console.log(info.mempool_stats.funded_txo_sum); // unconfirmed incoming (sats)Return shape:
{
address: "bc1q...",
chain_stats: {
funded_txo_count: 5,
funded_txo_sum: 500000,
spent_txo_count: 3,
spent_txo_sum: 300000,
tx_count: 8
},
mempool_stats: {
funded_txo_count: 1,
funded_txo_sum: 50000,
spent_txo_count: 0,
spent_txo_sum: 0,
tx_count: 1
}
}fetchAddressUTxOs
Retrieve all unspent outputs for a Bitcoin address.
await provider.fetchAddressUTxOs(address: string): Promise<BitcoinUTxO[]>| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Bitcoin address to query |
Returns: Array of BitcoinUTxO objects.
Example:
const utxos = await provider.fetchAddressUTxOs("bc1q...");
utxos.forEach((utxo) => {
console.log(`${utxo.txid}:${utxo.vout} — ${utxo.value} sats`);
});Return shape:
[
{
txid: "abc123...",
vout: 0,
value: 50000,
status: {
confirmed: true,
block_height: 840000,
block_hash: "00000000...",
block_time: 1710000000
}
}
]fetchUTxO
Retrieve specific unspent output(s) from a transaction. Filters out already-spent outputs by cross-referencing the outspends endpoint.
await provider.fetchUTxO(txid: string, vout?: number): Promise<BitcoinUTxO[]>| Parameter | Type | Required | Description |
|---|---|---|---|
txid | string | Yes | Transaction ID (64-char hex) |
vout | number | No | Output index to filter to; omit to return all unspent outputs |
Example:
// All unspent outputs from a transaction
const utxos = await provider.fetchUTxO("abc123...");
// A specific output (only returned if unspent)
const utxo = await provider.fetchUTxO("abc123...", 0);fetchAddressTxs
Retrieve transaction history for a Bitcoin address. The provider returns the Esplora page unchanged: GET /address/{address}/txs, or GET /address/{address}/txs/chain/{lastSeenTxid} when a cursor is set. Esplora returns up to 25 transactions per page, unconfirmed first, then confirmed newest-first.
await provider.fetchAddressTxs(
address: string,
lastSeenTxid?: string,
): Promise<BitcoinTxInfo[]>| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Bitcoin address to query |
lastSeenTxid | string | No | Txid of the last transaction seen; fetches the next page of results |
Example:
// First Esplora page
const txs = await provider.fetchAddressTxs("bc1q...");
// Next page
const moreTxs = await provider.fetchAddressTxs("bc1q...", txs[txs.length - 1].txid);Blockstream paginates using path-based cursors:
/address/{address}/txs/chain/{lastSeenTxid}.
fetchTxInfo
Retrieve the confirmation status of a transaction.
await provider.fetchTxInfo(txid: string): Promise<BitcoinTxStatus>| Parameter | Type | Required | Description |
|---|---|---|---|
txid | string | Yes | Transaction ID (64-char hex) |
Returns: BitcoinTxStatus — confirmation status and block details.
Example:
const status = await provider.fetchTxInfo("abc123...");
if (status.confirmed) {
console.log(`Confirmed at block ${status.block_height}`);
} else {
console.log("Pending in mempool");
}Return shape:
{
confirmed: true,
block_height: 840000,
block_hash: "00000000...",
block_time: 1710000000
}fetchFeeEstimates
Retrieve the recommended fee rate (sat/vB) for a target confirmation within blocks blocks, from GET /fee-estimates. A failed request throws. If that block target is missing, the provider uses the smallest target greater than or equal to blocks, or the largest target in the map when every target is smaller. It returns 2 only when that lookup still has no rate.
await provider.fetchFeeEstimates(blocks: number): Promise<number>| Parameter | Type | Required | Description |
|---|---|---|---|
blocks | number | Yes | Target confirmation speed in blocks (e.g. 1, 6, 144) |
Example:
const feeRate = await provider.fetchFeeEstimates(6); // 6-block target
console.log(`Recommended: ${feeRate} sat/vB`);fetchScriptInfo
Retrieve chain and mempool statistics for a script hash (P2SH / P2WSH).
await provider.fetchScriptInfo(hash: string): Promise<BitcoinScriptInfo>| Parameter | Type | Required | Description |
|---|---|---|---|
hash | string | Yes | Esplora script hash. Passed through to /scripthash/{hash} with no hashing or byte reversal |
fetchScriptUTxOs
Retrieve unspent outputs locked by a script hash.
await provider.fetchScriptUTxOs(hash: string): Promise<BitcoinUTxO[]>fetchScriptTxs
Retrieve transaction history for a script hash, with optional pagination.
await provider.fetchScriptTxs(
hash: string,
lastSeenTxid?: string,
): Promise<BitcoinTxInfo[]>submitTx
Broadcast a signed raw transaction to the Bitcoin network.
await provider.submitTx(txHex: string): Promise<string>| Parameter | Type | Required | Description |
|---|---|---|---|
txHex | string | Yes | Signed raw transaction in hex format |
Returns: The broadcast transaction ID (64-char hex).
Example:
const txid = await provider.submitTx(signedRawTxHex);
console.log(`Broadcast: ${txid}`);Blockstream's
/txendpoint acceptstext/plainand returns the txid as plain text on success.
Complete Example
import { BlockstreamBitcoinProvider } from "@meshsdk/provider";
import { BitcoinHeadlessWallet, AddressPurpose } from "@meshsdk/wallet";
async function sendBitcoin() {
const provider = new BlockstreamBitcoinProvider("testnet");
const wallet = await BitcoinHeadlessWallet.fromMnemonic({
network: "Testnet4",
mnemonic: ["your", "twelve", "word", "mnemonic", "phrase", "here", "..."],
provider,
});
// Check balance
const balance = await wallet.getBalance();
console.log(`Balance: ${balance.total} sats`);
// Get receive address
const [address] = await wallet.getAddresses([AddressPurpose.Payment]);
console.log(`Address: ${address.address}`);
// Send to a recipient
const txid = await wallet.signTransfer([
{ address: "tb1q...", amount: 10_000 }, // satoshis
]);
console.log(`Sent: ${txid}`);
}References
- Blockstream Esplora API Reference - Full endpoint documentation
- Blockstream Explorer - Block explorer powered by the same API
Related
- Blockstream Enterprise Bitcoin Provider - Authenticated Esplora API with OAuth client credentials
- Bitcoin Headless Wallet - Use this provider with a self-custodial HD wallet
- All Providers - Compare with Cardano providers