Metadata-Version: 2.4
Name: btc-toolkit
Version: 1.8.1
Summary: Read and verify Bitcoin from your terminal: OP_RETURN, inscriptions, raw transactions, offline address checks, Merkle-proof verify. Zero deps, no Bitcoin Core.
Author-email: Davi de Jesus <devdavidejesus@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/devdavidejesus/btc-toolkit
Project-URL: Documentation, https://github.com/devdavidejesus/btc-toolkit#readme
Project-URL: Repository, https://github.com/devdavidejesus/btc-toolkit
Project-URL: Issues, https://github.com/devdavidejesus/btc-toolkit/issues
Project-URL: Changelog, https://github.com/devdavidejesus/btc-toolkit/blob/main/CHANGELOG.md
Project-URL: Security, https://github.com/devdavidejesus/btc-toolkit/blob/main/SECURITY.md
Keywords: bitcoin,cli,op_return,ordinals,inscriptions,raw-transaction,merkle-proof,bech32,mempool,blockchain
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

<div align="center">

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/devdavidejesus/btc-toolkit/main/assets/logo-dark.svg"/>
  <img src="https://raw.githubusercontent.com/devdavidejesus/btc-toolkit/main/assets/logo.svg" alt="btc-toolkit" width="480"/>
</picture>

**Read and verify Bitcoin from your terminal.** Zero dependencies, no Bitcoin Core required.

Reads the chain through the [Mempool.space](https://mempool.space) public API, or your own Mempool instance, and checks what it can by computation: address checksums offline, and a transaction against its block's Merkle proof and proof of work.

[![Tests](https://github.com/devdavidejesus/btc-toolkit/actions/workflows/tests.yml/badge.svg)](https://github.com/devdavidejesus/btc-toolkit/actions/workflows/tests.yml)
[![PyPI](https://img.shields.io/pypi/v/btc-toolkit?label=PyPI&color=F7931A&logo=pypi&logoColor=white)](https://pypi.org/project/btc-toolkit/)
[![Python](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)](https://github.com/devdavidejesus/btc-toolkit/blob/main/pyproject.toml)
[![Dependencies](https://img.shields.io/badge/dependencies-zero-success)](https://github.com/devdavidejesus/btc-toolkit/blob/main/pyproject.toml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/devdavidejesus/btc-toolkit/blob/main/LICENSE)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/devdavidejesus/btc-toolkit/badge)](https://scorecard.dev/viewer/?uri=github.com/devdavidejesus/btc-toolkit)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/14966/badge)](https://www.bestpractices.dev/projects/14966)

</div>

<p align="center">
  <img src="https://raw.githubusercontent.com/devdavidejesus/btc-toolkit/main/assets/demo.gif" alt="btc-toolkit decoding the Liquid Network negotiation: first contact and the 2-byte :( that ended it" width="820"/>
</p>

<p align="center"><sub>The $320M Liquid Network drain was negotiated on-chain. Two of its messages, decoded live — <a href="https://dev.to/devdavidejesus/i-read-a-320m-ransom-negotiation-from-my-terminal-1159">read the whole story</a>.</sub></p>

---

## Quick start

```bash
pipx install btc-toolkit        # or: pip install btc-toolkit · brew install devdavidejesus/tap/btc-toolkit
btc-toolkit fees                # current fee rates
btc-toolkit opreturn f4ac7abcb689df30ec5e8d829733622f389ca91367c47b319bc582e653cd8cab
btc-toolkit verify c103de95817b43f2df635ec6f35ff126ca26a7c6d20570c4b01866b2b3e69a19   # check it is in a block
btc-toolkit validate bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq                         # offline: nothing sent
```

Try it without installing anything: `uvx btc-toolkit block 0`.

Options go **after** the command: `btc-toolkit fees --network signet`, not
`btc-toolkit --network signet fees`. `-n` is short for `--network`, and
`btc-toolkit <command> --help` lists every option of a command.

## Commands

| Command | Description |
|---|---|
| `btc-toolkit opreturn <txid>` | Decode OP_RETURN messages from a transaction |
| `btc-toolkit tx <txid>` | Transaction details: status, fees, size, input/output totals, RBF |
| `btc-toolkit address <address>` | Aggregated overview: type, balance, lifetime totals |
| `btc-toolkit balance <address>` | Confirmed + unconfirmed balance of any address |
| `btc-toolkit fees` | Recommended fee rates + mempool backlog |
| `btc-toolkit block <height\|hash\|latest>` | Block metadata by height, hash, or latest |
| `btc-toolkit utxo <address>` | Unspent outputs of any address |
| `btc-toolkit verify <txid>` | Check a transaction is in a block **by computation**: its Merkle proof and the header's proof of work |
| `btc-toolkit decode <rawtx>` | Decode a raw transaction **offline** (or `--txid`: fetch it and check its hash) |
| `btc-toolkit validate <address>` | Check an address **offline**: checksum, network, type — nothing is sent |
| `btc-toolkit inscription <txid>` | Ordinals inscription envelopes in a transaction: content type, size, SHA-256, text |

## Installation

**Requirements:** Python 3.11+. Supported versions follow CPython's own support window: a Python version is
dropped in the first minor release after it reaches end of life ([policy](https://github.com/devdavidejesus/btc-toolkit/blob/main/docs/releases.md#supported-python-versions)).

```bash
pip install btc-toolkit
```

Or isolated, via [pipx](https://pipx.pypa.io):

```bash
pipx install btc-toolkit
```

Or with [uv](https://docs.astral.sh/uv/): run it once without installing anything, or install it as a tool:

```bash
uvx btc-toolkit block 0
uv tool install btc-toolkit
```

Or via [Homebrew](https://brew.sh) on macOS and Linux, with shell completion included:

```bash
brew install devdavidejesus/tap/btc-toolkit
```

From source:

```bash
git clone https://github.com/devdavidejesus/btc-toolkit.git
cd btc-toolkit
pip install -e .
```

**Shell completion** (optional): static scripts in
[`completions/`](https://github.com/devdavidejesus/btc-toolkit/blob/main/completions) for bash and zsh — tab-complete
commands, networks and flags, zero dependencies as always. The Homebrew formula installs them for you.

## Usage

### tx — inspect any transaction

```bash
btc-toolkit tx f4ac7abcb689df30ec5e8d829733622f389ca91367c47b319bc582e653cd8cab
```

Shows confirmation status and block, fee and fee rate (sat/vB), total input/output, size/weight/vsize, version, locktime — and flags coinbase and RBF-signaling transactions.

![btc-toolkit tx demo](https://raw.githubusercontent.com/devdavidejesus/btc-toolkit/main/assets/demo.png)

```bash
# Every input (the output it spends, value, address) and every output (address, spent or not, and by what)
btc-toolkit tx <txid> --inputs --outputs

# JSON output for scripting
btc-toolkit tx <txid> --json
```

Addresses in `--inputs`/`--outputs` are computed locally from each output script, not taken from the API. With `--api-url` and no `-n`, the chain is unknown: the API's address is shown if it is a valid address (it is not checked against the script).

### address — aggregated overview

```bash
btc-toolkit address 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
```

One call, full picture: address type (P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2A or `witness_vN` — decoded offline from the checksum-verified address, per BIP 13/173/350), confirmed and unconfirmed balance, lifetime received/spent, and transaction counts.

```bash
# JSON output for scripting
btc-toolkit address <address> --json
```

### balance — check any address

```bash
btc-toolkit balance 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
```

Shows the confirmed balance in BTC and satoshis and, when the address has a non-zero unconfirmed amount, that amount and the total, plus confirmed and mempool transaction counts. Supports all address types: Legacy (P2PKH), P2SH, SegWit (Bech32), and Taproot.

```bash
# JSON output for scripting
btc-toolkit balance <address> --json

# Testnet or signet
btc-toolkit balance <address> --network testnet
btc-toolkit balance <address> --network signet
```

BTC conversion uses integer arithmetic (no floats) — satoshi-exact, always.

### fees — current rates and mempool backlog

```bash
btc-toolkit fees
```

Shows the five recommended fee tiers (sat/vB) — fastest, half hour, hour, economy, minimum — plus mempool backlog: pending tx count, size in vMB, and a rough estimate of blocks needed to clear it.

```bash
# JSON output for scripting
btc-toolkit fees --json

# Testnet
btc-toolkit fees --network testnet
```

### block — inspect any block

```bash
btc-toolkit block latest          # chain tip
btc-toolkit block 0               # by height (genesis)
btc-toolkit block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f   # by hash
```

Shows height, hash, mined timestamp (UTC), tx count, size, weight, difficulty, nonce, and previous block hash.

```bash
# JSON output for scripting
btc-toolkit block latest --json

# Testnet
btc-toolkit block latest --network testnet
```

### utxo — unspent outputs of any address

```bash
btc-toolkit utxo bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
```

Lists UTXOs sorted by value (largest first; the first 15 by default, see `--limit`), with txid:vout, value in BTC and sats, confirmation status, and block height. Shows aggregate count and total value.

> **Known limitation:** addresses with tens of thousands of UTXOs (e.g. Satoshi's genesis address, which has received over 80,000 outputs) exceed the upstream electrs response limit and return HTTP 400. Use `balance` for aggregate stats on such addresses — discovered and verified in production.

```bash
# Only confirmed UTXOs
btc-toolkit utxo <address> --confirmed-only

# Show more than 15 entries
btc-toolkit utxo <address> --limit 50

# JSON output (ignores --limit; --confirmed-only still applies)
btc-toolkit utxo <address> --json
```

### opreturn — decode embedded messages

```bash
btc-toolkit opreturn f4ac7abcb689df30ec5e8d829733622f389ca91367c47b319bc582e653cd8cab
```

```bash
# JSON output
btc-toolkit opreturn <txid> --json

# Raw hex only
btc-toolkit opreturn <txid> --raw
```

Known protocol markers are named by their prefix: a Runes Runestone (`OP_RETURN OP_13`), Omni Layer (a payload starting with `omni` — a plain text message can start that way too), and the BIP 141 witness commitment in a coinbase. They are tagged, not decoded.

**Seen in the wild:** the $320M Liquid Network drain (Sept 2026) was negotiated on-chain via OP_RETURN — every message of it decoded with this command, transaction IDs included: [*I Read a $320M Ransom Negotiation From My Terminal*](https://dev.to/devdavidejesus/i-read-a-320m-ransom-negotiation-from-my-terminal-1159). And the wallet holding 562 BTC from the Coldcard hack (July 2026) became a message board: 49 OP_RETURN messages, read with `opreturn --file`: [*49 Messages to a Thief*](https://dev.to/devdavidejesus/49-messages-to-a-thief-what-people-wrote-to-the-coldcard-hackers-bitcoin-wallet-l1n). btc-toolkit is also listed among the [developer tools](https://www.lopp.net/bitcoin-information/developer-tools.html) in Jameson Lopp's Bitcoin resources.

### Transactions to Try

Real, verified OP_RETURN transactions on mainnet. Verify each one yourself on [mempool.space](https://mempool.space).

| TXID | Description |
|---|---|
| `f4ac7abcb689df30ec5e8d829733622f389ca91367c47b319bc582e653cd8cab` | "Craig Wright is a liar and a fraud" — 34 bytes ([verify on-chain](https://mempool.space/tx/f4ac7abcb689df30ec5e8d829733622f389ca91367c47b319bc582e653cd8cab)) |
| `2033435de7ce307341231e818ed937cd3a5e8597381fd83a7e5b0234f61b38d3` | "learnmeabitcoin" — 75-byte OP_RETURN with null-padded ASCII ([verify on-chain](https://mempool.space/tx/2033435de7ce307341231e818ed937cd3a5e8597381fd83a7e5b0234f61b38d3)) |

> **Note:** Satoshi's famous "Chancellor on brink of second bailout for banks" message is in the
> **coinbase scriptSig** of the genesis block — NOT in an OP_RETURN output. That's a common
> misconception. This tool reads OP_RETURN outputs only, which is the standard mechanism
> for embedding data in Bitcoin transactions (introduced as standard in Bitcoin Core v0.9.0, March 2014).

### verify — check a transaction is in a block

```bash
btc-toolkit verify c103de95817b43f2df635ec6f35ff126ca26a7c6d20570c4b01866b2b3e69a19
```

Instead of taking the API's "confirmed" on faith, `verify` recomputes from raw bytes:

1. the **txid**, by hashing the raw transaction;
2. the **Merkle root**, from that txid and the proof's sibling hashes — refusing any pair of nodes that is also a valid 64-byte transaction, which could pose as a node (CVE-2017-12842);
3. the **block hash**, by hashing the 80-byte header — which must contain that root;
4. the **proof of work**: the header hash is below the target its `bits` encode, within the network's limit.

Any mismatch is `verification failed` (exit code `1`). The verdict depends only on the work proven — never on the height or date the API claims, since a forger picks those:

- **`✓ VERIFIED`** (`"work": "strong"`): a mainnet header at difficulty 50 T or more. Forging one takes about 2^77.5 hashes — over a third of a block's work at October 2026's difficulty (about 133 T).
- **`⚠ CONSISTENT, WEAK WORK`** (`"work": "weak"`): everything checks out, but the header carries less work — an older block, or testnet, signet (block signatures are not checked) or an unknown chain. That little work is cheap to fake: treat it as consistency, not proof.

With your own instance, add `-n mainnet` so `verify` knows which chain it is checking: `btc-toolkit verify <txid> --api-url http://umbrel.local:3006/api -n mainnet`.

What it does **not** prove: the block height (the API reports it; a header does not contain it), or that the block is in the chain everyone follows. Only a full node checks everything.

### decode — a raw transaction, offline

```bash
btc-toolkit decode 0100000001...           # or pipe it: cat tx.hex | btc-toolkit decode -
btc-toolkit decode --txid <txid>           # fetch the raw tx and check it hashes to <txid>
```

Version, inputs, outputs (with their addresses and script types), witness, locktime, txid and wtxid, size, weight and vsize — computed from the bytes. The fee is not shown: it needs the values of the outputs being spent, which a raw transaction does not carry (`tx` has it).

### validate — check an address offline

```bash
btc-toolkit validate bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
```

Verifies the checksum (Base58Check, or bech32 / bech32m per BIP 173 and BIP 350, tested against their official vectors), the network and the type — P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2A, or `witness_vN` for future versions. Nothing is sent anywhere. `balance`, `address` and `utxo` run the same check first, so a typo is caught locally (exit code `2`) and never reaches the API. With `--api-url` and no `-n`, the chain is unknown, so an address of any network is accepted.

### inscription — Ordinals envelopes

```bash
btc-toolkit inscription 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799
```

Finds the `OP_FALSE OP_IF "ord" … OP_ENDIF` envelopes in each input's Taproot script — parsed by ord's own rules, from its source — and shows the inscription ID, content type, encoding, metaprotocol, parents, delegate, body size and SHA-256, and the text of a text inscription (control characters escaped). This is **envelope detection, not the ord index**: it does not assign inscription numbers, track sats or owners, or apply ord's "cursed" rules. The witness comes from the API: a txid does not commit to it, so it is not verified.

## Architecture

```
btc-toolkit/
├── btc_toolkit/
│   ├── __init__.py       # Package version
│   ├── __main__.py       # python -m entry point
│   ├── cli.py            # Unified CLI: subcommands, batch mode, env vars, exit codes
│   ├── api.py            # Shared Mempool HTTP client: retry, timeout, custom base URL
│   ├── colors.py         # Shared terminal color helpers
│   ├── opreturn.py       # OP_RETURN decoder
│   ├── balance.py        # Address balance
│   ├── fees.py           # Fee estimator
│   ├── block.py          # Block explorer
│   ├── utxo.py           # UTXO inspector
│   ├── tx.py             # Transaction inspector
│   ├── address.py        # Address overview + offline type detection
│   ├── encoding.py       # Offline: bech32/bech32m, Base58Check, script types and addresses
│   ├── rawtx.py          # Offline raw transaction decoder (legacy and SegWit)
│   ├── verify.py         # Merkle-proof and proof-of-work verification
│   ├── inscription.py    # Ordinals inscription envelope detection
│   └── py.typed          # PEP 561 marker: the package ships its types
├── tests/                # One file per module, plus CLI, completion and robustness tests — all API calls mocked
├── fuzz/                 # Atheris fuzzer for the parsers of untrusted data
├── completions/          # Static bash + zsh completions
├── assets/               # Logo, icon, social preview and the README demos
├── .github/
│   ├── workflows/        # CI, release, CodeQL, fuzz, Scorecard, weekly live smoke test
│   ├── scripts/          # Release notes, live smoke test, demo recorder, brand assets
│   └── requirements/     # Hash-pinned CI tools
├── docs/
│   ├── json-schema.md    # --json output per command + stability policy
│   ├── python-api.md     # Using the toolkit as a typed Python library
│   └── releases.md       # How releases are built and verified
├── SECURITY.md           # Threat model + vulnerability reporting
├── CONTRIBUTING.md       # How changes are made and what they must include
├── CHANGELOG.md          # Every release, newest first
├── pyproject.toml
├── LICENSE               # MIT
└── README.md
```

Every subcommand shares one HTTP client (`api.py`) — a new command adds a module, a subcommand, its completions and tests; the HTTP layer stays untouched.

Zero external dependencies — Python standard library only (`urllib`, `json`, `argparse`).

## Reliability

- **Retry with backoff** — transient failures (HTTP 429, 500, 502, 503, 504 and network errors) get up to 3 attempts, with exponential backoff between them (0.5s, then 1s). Any other HTTP error (e.g. 400, 404) fails immediately.
- **Sovereignty** — `--api-url` points every command at your own Mempool instance; `--network` covers mainnet, testnet and signet.
- **Bounded waits** — `--timeout` (default 15s) applies to each network operation of each attempt, so with retries a command can wait longer than the timeout.
- **Exit codes** — `0` success, `1` network/API error (including a `verify` whose checks fail, or a transaction not confirmed yet), `2` invalid input. Script accordingly.
- **Verifiable releases** — since v1.5.0, published from GitHub Actions via PyPI Trusted Publishing, with PEP 740 attestations tying each file to this repo; since v1.6.1, every GitHub Release also carries Sigstore-signed files ([how to verify](https://github.com/devdavidejesus/btc-toolkit/blob/main/docs/releases.md)).

## Testing

```bash
python -m unittest discover -s tests -t . -v
```

Every command is tested with all API calls mocked — the suite runs offline, from the source tree, with nothing to install (`pytest` works too if you prefer it). Every pull request measures line and branch coverage and fails if it drops below 90%. The package is type-checked with `mypy --strict` and ships `py.typed`. A separate weekly job reads known on-chain facts from mainnet, and an [Atheris](https://github.com/google/atheris) fuzzer exercises every parser of untrusted data on each change.

## How balance is computed

The Mempool.space `/address` endpoint returns `chain_stats` (confirmed) and `mempool_stats` (unconfirmed), each with `funded_txo_sum` and `spent_txo_sum` in satoshis.

```
confirmed   = chain_stats.funded_txo_sum   - chain_stats.spent_txo_sum
unconfirmed = mempool_stats.funded_txo_sum - mempool_stats.spent_txo_sum
total       = confirmed + unconfirmed
```

This is the same model used by Esplora/Electrs. Don't trust this README — verify against `https://mempool.space/api/address/<address>` yourself.

## Automation

btc-toolkit is built to sit inside pipelines. Every command takes `--json`,
and the commands that take a txid, address or block read **one item per line**
from stdin (`-`) or a file (`--file`), emitting JSON Lines you can pipe straight
into `jq` (`decode -` reads a single raw transaction from stdin):

```bash
# many txids -> one JSON object per line
cat txids.txt | btc-toolkit tx - --json | jq -r '.fee_rate_sat_vb'

# or from a file (blank lines and lines starting with # are ignored)
btc-toolkit balance --file addresses.txt --json
```

Configuration through the environment — for Docker, CI, cron:

| Variable | Effect |
|---|---|
| `BTC_TOOLKIT_API_URL` | Default for `--api-url` (your own Mempool instance); ignored by `validate` and by `decode` without `--txid`. With it, the chain is `custom`: to name it, pass `--api-url` and `-n` together (`-n` alone switches to the public presets) |
| `BTC_TOOLKIT_NETWORK` | Default for `--network` (`mainnet`, `testnet`, `signet`; anything else is an error, exit 2; ignored when an API URL is set) |
| `BTC_TOOLKIT_TIMEOUT` | Default for `--timeout` (seconds, default 15) |
| `NO_COLOR` | Any non-empty value disables colors ([no-color.org](https://no-color.org)) |

Flags always win over environment variables. Exit codes are a contract
(`0` ok · `1` network/API failure · `2` invalid input) in both text and JSON
mode; in batch mode the worst code wins. Full output schemas and the
stability policy: [`docs/json-schema.md`](https://github.com/devdavidejesus/btc-toolkit/blob/main/docs/json-schema.md).

## Use it as a Python library

Every command is also a plain, typed function — the package ships `py.typed`, so your type checker sees real types:

```python
from btc_toolkit.opreturn import decode_op_return

for out in decode_op_return("c103de95817b43f2df635ec6f35ff126ca26a7c6d20570c4b01866b2b3e69a19"):
    print(out.decoded_text)   # we are whitehats. contact us on chain
```

Functions, result types and errors: [`docs/python-api.md`](https://github.com/devdavidejesus/btc-toolkit/blob/main/docs/python-api.md).

## Use your own Mempool instance

Every command accepts `--api-url` pointing to any self-hosted
[Mempool](https://github.com/mempool/mempool) instance, which runs on top of your
own Bitcoin node (Umbrel, Start9, RaspiBlitz and similar node stacks offer it as an app):

```bash
btc-toolkit balance <address> --api-url http://umbrel.local:3006/api -n mainnet
```

`-n` tells btc-toolkit which chain your instance serves. Without it the chain is
`custom` (unknown): addresses of any Bitcoin network (mainnet, testnet/signet,
regtest) are accepted, `tx` shows the API's addresses, and `verify` reports the
work as weak. Results never link to mempool.space when you use your own instance.

With your own instance, no third party sees your queries — the public
mempool.space API is the zero-setup default, not a requirement.

## What this is / What this isn't

The full threat model — what the tool protects against and what it does **not** — lives in [`SECURITY.md`](https://github.com/devdavidejesus/btc-toolkit/blob/main/SECURITY.md); how releases are built and how to verify one yourself is in [`docs/releases.md`](https://github.com/devdavidejesus/btc-toolkit/blob/main/docs/releases.md).

**This is** an explorer client for the terminal — a fast, scriptable way to
inspect the Bitcoin blockchain without running infrastructure. Ideal for
learning, scripting, quick lookups, and teaching how Bitcoin data is
structured.

**This isn't** a substitute for a full node. Data comes from a Mempool API
(mempool.space by default, or your own instance), and most commands report what
it says. Some checks don't trust it: addresses are validated offline, `decode`
works on raw bytes, and `verify` recomputes a transaction's inclusion in a block
— its Merkle proof and the block's proof of work — instead of taking "confirmed"
on faith. What no command does: validate blocks, follow the most-work chain, or
check consensus rules. For sovereign, trustless verification, run
[Bitcoin Core](https://bitcoincore.org) and query it directly.

## Roadmap

- [x] **Phase 1** — OP_RETURN Reader
- [x] **Phase 2** — Address Balance Checker
- [x] **Phase 3** — Fee Estimator (mempool-based)
- [x] **Phase 4** — Block Info Explorer
- [x] **Phase 5** — UTXO Set Inspector

The original roadmap shipped in v1.0.0; every release since is in the [CHANGELOG](https://github.com/devdavidejesus/btc-toolkit/blob/main/CHANGELOG.md). What's next lives in the [issues](https://github.com/devdavidejesus/btc-toolkit/issues) — one philosophy throughout: **zero dependencies, no Bitcoin Core, verify everything on-chain.**

## Don't Trust, Verify

Every txid, address, hex value, and technical claim in this README can be independently verified:
- Transaction data: `https://mempool.space/api/tx/<txid>`
- Address data: `https://mempool.space/api/address/<address>`
- Fee data: `https://mempool.space/api/v1/fees/recommended`
- Block data: `https://mempool.space/api/block/<hash>`
- UTXO data: `https://mempool.space/api/address/<address>/utxo`
- OP_RETURN spec: [learnmeabitcoin.com/technical/script/return](https://learnmeabitcoin.com/technical/script/return/)
- Esplora API model: [github.com/Blockstream/esplora/blob/master/API.md](https://github.com/Blockstream/esplora/blob/master/API.md)

## Support

btc-toolkit is free, MIT-licensed and has no sponsor. If it's useful to you, you can support its development on-chain:

**Bitcoin:** `bc1qulq8xfcmgxxumjx3yndkfktqgw2exh0rym45sn`

*(Public address — donations are visible on-chain, as everything here is.)*

## Contributing

Found a bug or want to propose or build a new command? Open an [issue](https://github.com/devdavidejesus/btc-toolkit/issues) or a PR. Every contribution keeps the core rules — stdlib only, tests with every change, claims verifiable on-chain. The process and requirements are in [`CONTRIBUTING.md`](https://github.com/devdavidejesus/btc-toolkit/blob/main/CONTRIBUTING.md).

---

<div align="center">

Licensed under [MIT](https://github.com/devdavidejesus/btc-toolkit/blob/main/LICENSE) · Built by [@devdavidejesus](https://github.com/devdavidejesus)

*"Don't Trust, Verify."*

</div>
