🎵 ₿ 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
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 install
make build
make run [CONFIG=examples/testnet.toml]
make sync [CONFIG=examples/testnet.toml]
make serve [CONFIG=examples/testnet.toml]
make openapi
make compose-up
make compose-down
curl -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.
- Base Indexer
- Addresses
- Runes by address
- Runes by address and rune ID
- Runes by address and transaction ID
- Rune UTXOs by address
- Rune UTXOs by address and rune ID
- UTXOs by address
- Satoshi balance by address
- BRC20 by address
- Inscriptions by address
- Transactions by address
- Runes
- Rune info by rune ID
- Rune balance by rune ID and UTXO
- List runes
- Holders by rune
- UTXOs by rune
- Addresses
- Wallet activity
- Addresses
- Satoshi activity by address
- Metaprotocol activity by address
- Historical satoshi balance by address
- Inscription activity by address
- Address statistics
- Addresses
- Alkanes
- Webhook Notifications
This project is licensed under the Apache 2.0 License.