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
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, sorted newest-first. Supports cursor-based pagination.
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 page (most recent 25 transactions)
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. Falls back to the next-closest target if an exact match is unavailable; defaults to 2 sat/vB if the fee API is unreachable.
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); // next ~1 hour
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 | Script hash (hex, SHA256 of the script) |
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
- Maestro Bitcoin Provider - Enterprise-grade alternative with an API key
- Bitcoin Headless Wallet - Use this provider with a self-custodial HD wallet
- All Providers - Compare with Cardano providers