🎵 ₿ from hash to harmony: an orchestrated Bitcoin indexing suite ₿ 🎵
Maestro Symphony is a fast, mempool-aware, and extensible Bitcoin indexer and API server. It provides a framework for indexing UTXOs, metaprotocols, and any other onchain activity.
Supported Networks
- mainnet
- testnet4
- regtest
Indexers
- Runes
- Transaction count by address
- UTXOs by address
- Charms
Endpoints: OpenAPI
Mempool Awareness: Query any endpoint with ?mempool=true to include pending transactions.
Rollback Handling: Always maintains an index of the longest chain.
- Bitcoin Core (22+) with RPC and P2P access
- Rust (stable)
Testnet4
- Disk: 4 GB
- CPU: 2 cores
- RAM: 4 GB
- Sync time: ~30 minutes
Mainnet
- Disk: 100 GB
- CPU: 4 cores
- RAM: 12 GB
- Sync time: ~4 days
NOTE: Deployment requirements are subject to change with new indexers and API endpoints.
Below is a table describing the main configuration options for maestro-symphony. See the example configuration for context.
| Section | Key/Field | Description | Example Value |
|---|---|---|---|
| root | db_path |
Path to the database directory | "tmp/symphony" |
[sync.node] |
p2p_address |
Host/IP and port for P2P connection to Bitcoin node | "localhost:8333" |
rpc_address |
URL of your Bitcoin node's RPC endpoint | "http://localhost:8332" |
|
rpc_user |
RPC username for your Bitcoin node | "bitcoin" |
|
rpc_pass |
RPC password for your Bitcoin node | "password" |
|
[sync] |
network |
Bitcoin network to connect to (mainnet, testnet4) |
"mainnet" |
max_rollback |
Number of rollbacked blocks from tip that can be handled | 32 |
|
mempool |
Enable mempool awareness | true |
|
utxo_cache_size |
Memory in GB to allocate to UTxO cache (default 40% RAM) | 1.0 |
|
[sync.indexers] |
transaction_indexers |
List of enabled indexers and their options | See example below |
[server] |
address |
Address and port for API server to listen on | "0.0.0.0:8080" |
[storage] |
rocksdb_memory_budget |
Bound RocksDB memory usage in GB (default 25% RAM + ~2% DB) | 3.0 |
See examples to quickly get started.
See instructions here.
Optionally, use mise to easily set up your environment:
mise installmake buildmake run [CONFIG=examples/testnet.toml]make sync [CONFIG=examples/testnet.toml]make serve [CONFIG=examples/testnet.toml]make openapimake install-hookspre-push hook runs make fmt-check and make lint, matching the CI formatting and clippy checks.
make compose-upmake compose-downcurl -X GET "http://localhost:8080/addresses/tb1pn9dzakm6egrv90c9gsgs63axvmn6ydwemrpuwljnmz9qdk38ueqsqae936/runes/utxos" | jq .{
"data": [
{
"tx_hash": "63937d48e35d15a7c5530469210c202104cc94a945cc848554f336b3f4f24121",
"output_index": 1,
"height": 30562,
"satoshis": "10000",
"runes": [
{
"id": "30562:50",
"amount": "100000000"
}
]
}
],
"indexer_info": {
"chain_tip": {
"block_hash": "000000002ec229e75c52e8e9adf95149fdde167b59c3271abb6bf541ef85249b",
"block_height": 87777
},
"mempool_timestamp": null,
"estimated_blocks": []
}
}curl -X POST "http://localhost:8080/runes/info" \
-H "Content-Type: application/json" \
-d '["30562:50", "ABCDEF"]' | jq .{
"data": {
"30562:50": {
"id": "30562:50",
"name": "BESTINSLOTXYZ",
"spaced_name": "BESTINSLOT•XYZ",
"symbol": "ʃ",
"divisibility": 8,
"etching_tx": "63937d48e35d15a7c5530469210c202104cc94a945cc848554f336b3f4f24121",
"etching_height": 30562,
"terms": {
"amount": "100000000",
"cap": "3402823669209384634633746074316",
"start_height": null,
"end_height": null
},
"premine": "100000000"
},
"ABCDEF": null
},
"indexer_info": {
"chain_tip": {
"block_hash": "00000000000000108a4cd9755381003a01bea7998ca2d770fe09b576753ac7ef",
"block_height": 31633
},
"mempool_timestamp": null,
"estimated_blocks": []
}
}curl -X GET "http://localhost:8080/addresses/tb1pn9dzakm6egrv90c9gsgs63axvmn6ydwemrpuwljnmz9qdk38ueqsqae936/runes/utxos?mempool=true" | jq .{
"data": [
{
"tx_hash": "63937d48e35d15a7c5530469210c202104cc94a945cc848554f336b3f4f24121",
"output_index": 1,
"height": 30562,
"satoshis": "10000",
"runes": [
{
"id": "30562:50",
"amount": "100000000"
}
]
}
],
"indexer_info": {
"chain_tip": {
"block_hash": "000000002ec229e75c52e8e9adf95149fdde167b59c3271abb6bf541ef85249b",
"block_height": 87777
},
"mempool_timestamp": "2025-06-23 22:04:31",
"estimated_blocks": [
{
"block_height": 87778
}
]
}
}curl -X GET "http://localhost:8080/addresses/<ADDRESS>/runes/tx/<TXID>" | jq .{
"data": [
{
"rune_id": "30562:50",
"amount": "100000000",
"output": 1,
"block_height": 30562
}
],
"indexer_info": {
"chain_tip": {
"block_hash": "0000000000000035ec326a15b2f81822962f786028f33205b74b47a9b7cf3caf",
"block_height": 38980
},
"mempool_timestamp": null,
"estimated_blocks": []
}
}Maestro Symphony has undergone professional security audits to ensure the safety and reliability of the codebase.
- Thesis Defense Security Audit (September 2025) - Independent security assessment of the core indexing and API components.
For reporting security vulnerabilities, please see our Security Policy.
Pull requests and issues are welcome! See the Kanban board for project status and tasks.
This project is licensed under the Apache 2.0 License.
