satoshi-api 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. satoshi_api-0.1.0/.env.example +25 -0
  2. satoshi_api-0.1.0/.env.production.example +10 -0
  3. satoshi_api-0.1.0/.github/workflows/ci.yml +38 -0
  4. satoshi_api-0.1.0/.github/workflows/pages.yml +34 -0
  5. satoshi_api-0.1.0/.github/workflows/publish.yml +26 -0
  6. satoshi_api-0.1.0/.gitignore +10 -0
  7. satoshi_api-0.1.0/CHANGELOG.md +49 -0
  8. satoshi_api-0.1.0/CLAUDE.md +61 -0
  9. satoshi_api-0.1.0/Dockerfile +26 -0
  10. satoshi_api-0.1.0/LICENSE +21 -0
  11. satoshi_api-0.1.0/PKG-INFO +209 -0
  12. satoshi_api-0.1.0/README.md +175 -0
  13. satoshi_api-0.1.0/blog-post.md +191 -0
  14. satoshi_api-0.1.0/cloudflared-config.yml.example +12 -0
  15. satoshi_api-0.1.0/demo/dashboard.html +176 -0
  16. satoshi_api-0.1.0/docker-compose.prod.yml +22 -0
  17. satoshi_api-0.1.0/docker-compose.yml +16 -0
  18. satoshi_api-0.1.0/docs/BUSINESS_PLAN.md +373 -0
  19. satoshi_api-0.1.0/docs/COMPETITIVE_ANALYSIS.md +190 -0
  20. satoshi_api-0.1.0/docs/SCOPE_OF_WORK.md +483 -0
  21. satoshi_api-0.1.0/docs/bitcoin-conf-example.conf +16 -0
  22. satoshi_api-0.1.0/docs/self-hosting.md +154 -0
  23. satoshi_api-0.1.0/docs/website/index.html +458 -0
  24. satoshi_api-0.1.0/pyproject.toml +47 -0
  25. satoshi_api-0.1.0/scripts/create_api_key.py +45 -0
  26. satoshi_api-0.1.0/scripts/security_check.sh +99 -0
  27. satoshi_api-0.1.0/scripts/seed_db.py +23 -0
  28. satoshi_api-0.1.0/src/bitcoin_api/__init__.py +8 -0
  29. satoshi_api-0.1.0/src/bitcoin_api/auth.py +67 -0
  30. satoshi_api-0.1.0/src/bitcoin_api/cache.py +155 -0
  31. satoshi_api-0.1.0/src/bitcoin_api/config.py +42 -0
  32. satoshi_api-0.1.0/src/bitcoin_api/db.py +136 -0
  33. satoshi_api-0.1.0/src/bitcoin_api/dependencies.py +39 -0
  34. satoshi_api-0.1.0/src/bitcoin_api/l402.py +120 -0
  35. satoshi_api-0.1.0/src/bitcoin_api/lightning.py +97 -0
  36. satoshi_api-0.1.0/src/bitcoin_api/main.py +437 -0
  37. satoshi_api-0.1.0/src/bitcoin_api/models.py +195 -0
  38. satoshi_api-0.1.0/src/bitcoin_api/pricing.py +66 -0
  39. satoshi_api-0.1.0/src/bitcoin_api/rate_limit.py +92 -0
  40. satoshi_api-0.1.0/src/bitcoin_api/routers/__init__.py +0 -0
  41. satoshi_api-0.1.0/src/bitcoin_api/routers/blocks.py +325 -0
  42. satoshi_api-0.1.0/src/bitcoin_api/routers/fees.py +225 -0
  43. satoshi_api-0.1.0/src/bitcoin_api/routers/mempool.py +240 -0
  44. satoshi_api-0.1.0/src/bitcoin_api/routers/mining.py +100 -0
  45. satoshi_api-0.1.0/src/bitcoin_api/routers/network.py +201 -0
  46. satoshi_api-0.1.0/src/bitcoin_api/routers/prices.py +90 -0
  47. satoshi_api-0.1.0/src/bitcoin_api/routers/status.py +78 -0
  48. satoshi_api-0.1.0/src/bitcoin_api/routers/transactions.py +348 -0
  49. satoshi_api-0.1.0/start-api.bat +4 -0
  50. satoshi_api-0.1.0/static/index.html +516 -0
  51. satoshi_api-0.1.0/tests/conftest.py +273 -0
  52. satoshi_api-0.1.0/tests/locustfile.py +42 -0
  53. satoshi_api-0.1.0/tests/test_api.py +828 -0
  54. satoshi_api-0.1.0/tests/test_e2e.py +213 -0
  55. satoshi_api-0.1.0/tests/test_l402.py +285 -0
@@ -0,0 +1,25 @@
1
+ # Bitcoin Core RPC connection
2
+ BITCOIN_RPC_HOST=127.0.0.1
3
+ BITCOIN_RPC_PORT=8332
4
+ # For testnet: BITCOIN_RPC_PORT=18332
5
+ # For signet: BITCOIN_RPC_PORT=38332
6
+ # For regtest: BITCOIN_RPC_PORT=18443
7
+ BITCOIN_RPC_USER=
8
+ BITCOIN_RPC_PASSWORD=
9
+ # Optional: path to Bitcoin Core data directory (for cookie auth)
10
+ BITCOIN_DATADIR=
11
+
12
+ # API settings
13
+ API_PORT=9332
14
+ API_HOST=0.0.0.0
15
+ API_DB_PATH=data/bitcoin_api.db
16
+
17
+ # CORS origins (comma-separated). Use * only for local/dev.
18
+ # Default: http://localhost:3000,http://localhost:9332
19
+ CORS_ORIGINS=http://localhost:3000,http://localhost:9332
20
+
21
+ # Rate limits (requests per minute)
22
+ RATE_LIMIT_ANONYMOUS=30
23
+ RATE_LIMIT_FREE=100
24
+ RATE_LIMIT_PRO=500
25
+ RATE_LIMIT_ENTERPRISE=2000
@@ -0,0 +1,10 @@
1
+ # Production environment for Satoshi API
2
+ # Copy to .env.production and fill in values
3
+
4
+ BITCOIN_RPC_HOST=host.docker.internal
5
+ BITCOIN_RPC_PORT=8332
6
+ BITCOIN_RPC_USER=satoshiapi
7
+ BITCOIN_RPC_PASSWORD=
8
+ CORS_ORIGINS=https://api.yourdomain.dev
9
+ API_HOST=0.0.0.0
10
+ API_PORT=9332
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ pip install git+https://github.com/Bortlesboat/bitcoinlib-rpc.git
27
+ pip install -e ".[dev]"
28
+
29
+ - name: Lint
30
+ run: ruff check src/ tests/
31
+
32
+ - name: Run tests with coverage
33
+ run: pytest -v --cov=bitcoin_api --cov-report=term-missing --cov-fail-under=70
34
+
35
+ - name: Docker build (smoke test)
36
+ if: matrix.python-version == '3.12'
37
+ continue-on-error: true
38
+ run: docker build -t bitcoin-api-test .
@@ -0,0 +1,34 @@
1
+ name: Deploy Landing Page
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ paths: ["docs/website/**"]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: pages
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ deploy:
20
+ environment:
21
+ name: github-pages
22
+ url: ${{ steps.deployment.outputs.page_url }}
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - uses: actions/configure-pages@v4
28
+
29
+ - uses: actions/upload-pages-artifact@v3
30
+ with:
31
+ path: docs/website
32
+
33
+ - id: deployment
34
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,26 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+ permissions:
15
+ id-token: write
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ - name: Install build tools
22
+ run: pip install build
23
+ - name: Build package
24
+ run: python -m build
25
+ - name: Publish to PyPI
26
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .env
7
+ *.db
8
+ data/
9
+ .venv/
10
+ tasks/
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ ## [0.2.1] - 2026-03-06
4
+
5
+ ### Added
6
+ - `GET /tx/{txid}/hex` — raw transaction hex string
7
+ - `GET /tx/{txid}/outspends` — spending status of each output (spent/unspent via UTXO set)
8
+ - `GET /blocks/{hash}/header` — block header as hex string
9
+ - `GET /fees/mempool-blocks` — projected next blocks from mempool, grouped by fee rate
10
+ - `GET /prices` — BTC price in 6 currencies from CoinGecko (60s cache)
11
+ - `GET /network/validate-address/{address}` — validate a Bitcoin address
12
+ - 9 new unit tests + 6 new e2e tests (80 unit + 21 e2e total)
13
+
14
+ ### Changed
15
+ - RPC whitelist: added `getblockheader`, `validateaddress` (now 19 commands)
16
+ - Total endpoints: 27 → 33
17
+
18
+ ## [0.2.0] - 2026-03-06
19
+
20
+ ### Added
21
+ - `GET /mempool/txids` — all transaction IDs in the mempool
22
+ - `GET /mempool/recent` — most recent mempool entries sorted by time (configurable count, max 100)
23
+ - `GET /blocks/tip/height` — chain tip height
24
+ - `GET /blocks/tip/hash` — chain tip block hash
25
+ - `GET /blocks/{hash}/txids` — transaction IDs in a block
26
+ - `GET /blocks/{hash}/txs` — full transactions in a block (paginated, default 25, max 100)
27
+ - `GET /tx/{txid}/status` — transaction confirmation status
28
+ - `GET /network/difficulty` — difficulty epoch progress, blocks remaining, estimated retarget date
29
+ - Competitive analysis document (vs mempool.space — 161 endpoints mapped)
30
+ - 12 new unit tests + 6 new e2e tests (71 unit + 15 e2e total)
31
+
32
+ ### Changed
33
+ - RPC whitelist: added `getrawmempool` (now 17 commands)
34
+ - Total endpoints: 19 → 27
35
+
36
+ ## [0.1.0] - 2026-03-05
37
+
38
+ ### Added
39
+ - REST API with 19 endpoints across 7 categories (blocks, transactions, fees, mempool, mining, network, status)
40
+ - Tiered API key authentication (anonymous, free, pro, enterprise)
41
+ - Sliding-window rate limiting (per-minute in-memory + daily DB-backed)
42
+ - TTL caching with reorg-safe depth awareness
43
+ - Input validation (txid format, block height range, fee target bounds)
44
+ - Structured error responses with request IDs
45
+ - Docker support with health checks
46
+ - 59 unit tests + 9 e2e tests with full endpoint coverage
47
+ - Security hardening: POST auth requirements, node fingerprint redaction, access logging, body size limits
48
+ - Production deployment support: Cloudflare Tunnel config, docker-compose.prod, self-hosting docs
49
+ - Bitcoin Core RPC whitelist configuration example
@@ -0,0 +1,61 @@
1
+ # Satoshi API -- Project Instructions
2
+
3
+ ## Scope of Work (MANDATORY)
4
+
5
+ **`docs/SCOPE_OF_WORK.md` is the canonical project document. It MUST be updated with every change.**
6
+
7
+ After any code change, documentation update, or architectural decision:
8
+ 1. Update the relevant section(s) in `docs/SCOPE_OF_WORK.md`
9
+ 2. If adding/removing endpoints: update Section 3 (API Surface)
10
+ 3. If adding/removing files: update Section 6 (Deliverables)
11
+ 4. If fixing bugs or addressing review findings: update Section 5.2 (Critical Issues Fixed)
12
+ 5. If changing security controls: update Section 4 (Security Model)
13
+ 6. If test count changes: update Section 6.1 (sprint table totals)
14
+ 7. If adding known limitations: update Section 5.3
15
+ 8. If deployment steps change: update Section 7
16
+
17
+ The SOW is the single source of truth for what this project is, what it does, and what state it's in. Treat it like a living design doc, not a one-time artifact.
18
+
19
+ ## Architecture
20
+
21
+ - **Stack:** FastAPI + bitcoinlib-rpc + SQLite (WAL mode)
22
+ - **Entry point:** `src/bitcoin_api/main.py`
23
+ - **Config:** Pydantic Settings from env vars (`config.py`), RPC password is `SecretStr`
24
+ - **Auth:** API key via `X-API-Key` header, tier-based (anonymous/free/pro/lightning/enterprise)
25
+ - **L402:** Lightning micropayments via HTTP 402 + macaroon challenge (disabled by default)
26
+ - **Rate limiting:** Sliding window (in-memory) + daily (DB-backed)
27
+ - **Caching:** Per-cache locks, reorg-safe depth awareness, bounded LRU for hash mappings
28
+
29
+ ## Testing
30
+
31
+ - Run tests: `python -m pytest tests/test_api.py tests/test_l402.py -q`
32
+ - E2E (requires running API): `python -m pytest tests/test_e2e.py -m e2e`
33
+ - Load test: `locust -f tests/locustfile.py --host http://localhost:9332`
34
+ - Security check: `SATOSHI_API_KEY=<key> bash scripts/security_check.sh`
35
+ - `authed_client` fixture for POST endpoint tests (requires API key in DB)
36
+ - `client` fixture is anonymous -- use for GET tests and auth rejection tests
37
+
38
+ ## Conventions
39
+
40
+ - Response envelope: `{ data, meta }` on success, `{ error }` on failure
41
+ - All errors include `request_id` for tracing
42
+ - POST endpoints require `free` tier or above (403 for anonymous)
43
+ - Node version info redacted for anonymous users on `/network`
44
+ - Secrets: never log, never commit. RPC password uses `SecretStr`.
45
+
46
+ ## Key Files
47
+
48
+ | File | Purpose |
49
+ |------|---------|
50
+ | `docs/SCOPE_OF_WORK.md` | Living project document (KEEP UPDATED) |
51
+ | `src/bitcoin_api/main.py` | App, middleware, exception handlers |
52
+ | `src/bitcoin_api/config.py` | Settings from env vars |
53
+ | `src/bitcoin_api/auth.py` | API key auth |
54
+ | `src/bitcoin_api/rate_limit.py` | Rate limiting |
55
+ | `src/bitcoin_api/cache.py` | TTL + LRU caching |
56
+ | `src/bitcoin_api/lightning.py` | Lightning client (Alby Hub + mock) |
57
+ | `src/bitcoin_api/l402.py` | L402 macaroon minting/verification |
58
+ | `src/bitcoin_api/pricing.py` | Endpoint pricing map (sats) |
59
+ | `tests/test_api.py` | Unit tests (80) |
60
+ | `tests/test_l402.py` | L402 tests (32) |
61
+ | `tests/test_e2e.py` | E2E tests (21) |
@@ -0,0 +1,26 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY pyproject.toml .
6
+ COPY src/ src/
7
+
8
+ RUN apt-get update && apt-get install -y --no-install-recommends git && \
9
+ pip install --no-cache-dir git+https://github.com/Bortlesboat/bitcoinlib-rpc.git && \
10
+ pip install --no-cache-dir . && \
11
+ rm -rf /var/lib/apt/lists/*
12
+
13
+ COPY scripts/ scripts/
14
+
15
+ RUN mkdir -p /app/data && \
16
+ adduser --disabled-password --no-create-home apiuser && \
17
+ chown -R apiuser:apiuser /app/data
18
+
19
+ USER apiuser
20
+
21
+ EXPOSE 9332
22
+
23
+ HEALTHCHECK --interval=30s --timeout=5s \
24
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:9332/healthz')" || exit 1
25
+
26
+ CMD ["python", "-m", "bitcoin_api.main"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andy Barnes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.4
2
+ Name: satoshi-api
3
+ Version: 0.1.0
4
+ Summary: Satoshi API — developer-friendly Bitcoin REST API powered by your own node
5
+ Project-URL: Homepage, https://bitcoinsapi.com
6
+ Project-URL: Documentation, https://bitcoinsapi.com/docs
7
+ Project-URL: Repository, https://github.com/Bortlesboat/bitcoin-api
8
+ Project-URL: Issues, https://github.com/Bortlesboat/bitcoin-api/issues
9
+ Author: Bortlesboat
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,bitcoin,blockchain,node,rest
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Office/Business :: Financial
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: bitcoinlib-rpc>=0.1.0
20
+ Requires-Dist: cachetools>=5.3
21
+ Requires-Dist: fastapi>=0.115.0
22
+ Requires-Dist: pydantic-settings>=2.0
23
+ Requires-Dist: uvicorn[standard]>=0.30.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: httpx; extra == 'dev'
26
+ Requires-Dist: locust; extra == 'dev'
27
+ Requires-Dist: pytest; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio; extra == 'dev'
29
+ Requires-Dist: pytest-cov; extra == 'dev'
30
+ Requires-Dist: ruff; extra == 'dev'
31
+ Provides-Extra: l402
32
+ Requires-Dist: httpx>=0.27.0; extra == 'l402'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Satoshi API
36
+
37
+ [![CI](https://github.com/Bortlesboat/bitcoin-api/actions/workflows/ci.yml/badge.svg)](https://github.com/Bortlesboat/bitcoin-api/actions/workflows/ci.yml)
38
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
40
+
41
+ The thinnest REST layer over your Bitcoin node. One `pip install`, instant API.
42
+
43
+ Powered by [bitcoinlib-rpc](https://github.com/Bortlesboat/bitcoinlib-rpc) for analyzed data (fees, mempool congestion, block stats) rather than raw RPC dumps. Part of the AI agent pipeline: **bitcoinlib-rpc** -> **satoshi-api** -> [bitcoin-mcp](https://github.com/Bortlesboat/bitcoin-mcp).
44
+
45
+ ## Prerequisites
46
+
47
+ - **Bitcoin Core** running with `server=1` in `bitcoin.conf` (RPC enabled)
48
+ - Python 3.10+
49
+
50
+ **Node configuration notes:**
51
+ - Transaction lookups (`/tx/{txid}`, `/tx/{txid}/raw`) for confirmed transactions require `txindex=1`
52
+ - Block template (`/mining/nextblock`) requires at least one connected peer on mainnet
53
+ - Block stats (`/blocks/{height}/stats`) is unavailable for pruned blocks below the prune height
54
+
55
+ ## Quick Start
56
+
57
+ ```bash
58
+ pip install bitcoin-api # or: pip install -e . for local dev
59
+
60
+ # Point at your node
61
+ export BITCOIN_RPC_USER=your_user
62
+ export BITCOIN_RPC_PASSWORD=your_password
63
+ # For testnet: export BITCOIN_RPC_PORT=18332
64
+ # For signet: export BITCOIN_RPC_PORT=38332
65
+
66
+ # Run
67
+ bitcoin-api # or: satoshi-api
68
+ # -> http://localhost:9332/docs
69
+ ```
70
+
71
+ ### Docker
72
+
73
+ ```bash
74
+ # Create .env with your node credentials
75
+ echo "BITCOIN_RPC_USER=your_user" > .env
76
+ echo "BITCOIN_RPC_PASSWORD=your_password" >> .env
77
+
78
+ docker compose up -d
79
+ ```
80
+
81
+ ## Endpoints
82
+
83
+ All endpoints are under `/api/v1/`. Interactive docs at `/docs`.
84
+
85
+ | Endpoint | Description |
86
+ |----------|-------------|
87
+ | `GET /health` | Node ping (no auth required) |
88
+ | `GET /status` | Sync progress, peers, disk usage |
89
+ | `GET /network` | Version, connections, relay fee |
90
+ | `GET /network/forks` | Chain tips / fork detection |
91
+ | `GET /network/difficulty` | Difficulty epoch progress, retarget estimate |
92
+ | `GET /blocks/latest` | Latest block analysis |
93
+ | `GET /blocks/tip/height` | Chain tip height |
94
+ | `GET /blocks/tip/hash` | Chain tip block hash |
95
+ | `GET /blocks/{height_or_hash}` | Block by height or hash |
96
+ | `GET /blocks/{height}/stats` | Raw block statistics |
97
+ | `GET /blocks/{hash}/txids` | Transaction IDs in a block |
98
+ | `GET /blocks/{hash}/txs` | Full transactions in a block (paginated) |
99
+ | `GET /blocks/{hash}/header` | Block header hex string |
100
+ | `GET /tx/{txid}` | Transaction analysis (fees, SegWit, Taproot, inscriptions) |
101
+ | `GET /tx/{txid}/raw` | Raw decoded transaction |
102
+ | `GET /tx/{txid}/status` | Confirmation status |
103
+ | `GET /tx/{txid}/hex` | Raw transaction hex string |
104
+ | `GET /tx/{txid}/outspends` | Spending status of each output |
105
+ | `GET /utxo/{txid}/{vout}` | UTXO lookup |
106
+ | `GET /mempool` | Mempool analysis (fee buckets, congestion) |
107
+ | `GET /mempool/info` | Raw mempool stats |
108
+ | `GET /mempool/tx/{txid}` | Mempool entry for a transaction |
109
+ | `GET /mempool/txids` | All transaction IDs in the mempool |
110
+ | `GET /mempool/recent` | Most recent mempool entries |
111
+ | `GET /fees` | Fee estimates (1, 3, 6, 25, 144 blocks) |
112
+ | `GET /fees/recommended` | Human-readable fee recommendation |
113
+ | `GET /fees/{target}` | Fee estimate for specific block target |
114
+ | `GET /fees/mempool-blocks` | Projected next blocks from mempool by fee rate |
115
+ | `GET /mining` | Hashrate, difficulty, retarget estimate |
116
+ | `GET /mining/nextblock` | Block template analysis |
117
+ | `GET /network/validate-address/{addr}` | Validate a Bitcoin address |
118
+ | `GET /prices` | BTC price in USD, EUR, GBP, JPY, CAD, AUD |
119
+ | `POST /decode` | Decode raw transaction hex |
120
+ | `POST /broadcast` | Broadcast signed transaction |
121
+
122
+ ## Examples
123
+
124
+ ```bash
125
+ # Health check
126
+ curl http://localhost:9332/api/v1/health
127
+
128
+ # Fee recommendation
129
+ curl http://localhost:9332/api/v1/fees/recommended
130
+
131
+ # Analyze a transaction
132
+ curl http://localhost:9332/api/v1/tx/a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d
133
+
134
+ # Latest block
135
+ curl http://localhost:9332/api/v1/blocks/latest
136
+
137
+ # With API key (higher rate limits)
138
+ curl -H "X-API-Key: your_key_here" http://localhost:9332/api/v1/mempool
139
+ ```
140
+
141
+ ## API Keys
142
+
143
+ Anonymous access works out of the box. For higher rate limits, create a key:
144
+
145
+ ```bash
146
+ python scripts/create_api_key.py --tier free --label "my-app"
147
+ python scripts/create_api_key.py --tier pro --label "production"
148
+ ```
149
+
150
+ Pass the key via `X-API-Key` header. Query parameter `?api_key=` is deprecated (sunset: 2026-09-01).
151
+
152
+ ## Rate Limits
153
+
154
+ | Tier | Req/min | Req/day |
155
+ |------|---------|---------|
156
+ | Anonymous | 30 | 1,000 |
157
+ | Free (API key) | 100 | 10,000 |
158
+ | Pro | 500 | 100,000 |
159
+ | Enterprise | 2,000 | Unlimited |
160
+
161
+ Rate limit info in response headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `X-RateLimit-Daily-Limit`, `X-RateLimit-Daily-Remaining`.
162
+
163
+ Every response includes `X-Request-ID` (UUID) and `X-Auth-Tier` headers.
164
+
165
+ ## Response Format
166
+
167
+ Standard envelope on all endpoints:
168
+
169
+ ```json
170
+ {
171
+ "data": { ... },
172
+ "meta": {
173
+ "timestamp": "2026-03-05T12:00:00+00:00",
174
+ "request_id": "550e8400-e29b-41d4-a716-446655440000",
175
+ "node_height": 880000,
176
+ "chain": "main"
177
+ }
178
+ }
179
+ ```
180
+
181
+ Errors:
182
+
183
+ ```json
184
+ {
185
+ "error": {
186
+ "status": 404,
187
+ "title": "Not Found",
188
+ "detail": "Transaction not found",
189
+ "request_id": "550e8400-e29b-41d4-a716-446655440000"
190
+ }
191
+ }
192
+ ```
193
+
194
+ ## Input Validation
195
+
196
+ - Transaction IDs and block hashes must be exactly 64 hex characters
197
+ - Invalid formats return 422 immediately (no wasted RPC calls)
198
+ - Invalid API keys return 401 (not silent downgrade to anonymous)
199
+
200
+ ## Development
201
+
202
+ ```bash
203
+ pip install -e ".[dev]"
204
+ pytest
205
+ ```
206
+
207
+ ## License
208
+
209
+ MIT