use serde_json::json;
fn main() -> anyhow::Result<()> {
println!("blvm-node Blockchain RPC Examples");
println!("====================================");
println!();
println!("These methods query blockchain state, blocks, and headers.");
println!("All methods are Bitcoin Core-compatible.");
println!();
let rpc_url = "http://127.0.0.1:18332";
println!("RPC Endpoint: {rpc_url}");
println!();
println!("Example RPC Requests:");
println!();
println!("1. getblockchaininfo - Get overall chain state");
let request = json!({
"jsonrpc": "2.0",
"method": "getblockchaininfo",
"params": [],
"id": 1
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Check chain, block height, best block hash, IBD status");
println!();
println!("2. getblockcount - Get current block height");
let request = json!({
"jsonrpc": "2.0",
"method": "getblockcount",
"params": [],
"id": 2
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Quick check of chain height without full chain info");
println!();
println!("3. getbestblockhash - Get the hash of the best (tip) block");
let request = json!({
"jsonrpc": "2.0",
"method": "getbestblockhash",
"params": [],
"id": 3
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Get the current chain tip hash for syncing");
println!();
println!("4. getblockhash - Get block hash at a given height");
let height = 800_000u64;
let request = json!({
"jsonrpc": "2.0",
"method": "getblockhash",
"params": [height],
"id": 4
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Translate a block height to its hash");
println!(" Note: Replace height with the block number you want");
println!();
println!("5. getblockheader - Get a block header by hash");
let block_hash = "000000000000000000024bead8df69990852c202db0e0097c1a12ea637d7e96d";
let request = json!({
"jsonrpc": "2.0",
"method": "getblockheader",
"params": [block_hash, true], "id": 5
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Get header metadata (time, difficulty, nonce) without full block data");
println!(" Note: Replace block_hash with actual hash; set verbose=false for raw hex");
println!();
println!("6. getblock - Get a full block by hash");
let request = json!({
"jsonrpc": "2.0",
"method": "getblock",
"params": [block_hash, 2], "id": 6
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Retrieve full block data including all transactions");
println!(" Note: verbosity=2 includes decoded transaction inputs and outputs");
println!();
println!("7. getdifficulty - Get the proof-of-work difficulty target");
let request = json!({
"jsonrpc": "2.0",
"method": "getdifficulty",
"params": [],
"id": 7
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Get current mining difficulty as a multiple of minimum difficulty");
println!();
println!("8. gettxoutsetinfo - Get statistics about the UTXO set");
let request = json!({
"jsonrpc": "2.0",
"method": "gettxoutsetinfo",
"params": [],
"id": 8
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Get total UTXO count, total supply, and database stats");
println!();
println!("9. loadtxoutset - Load a UTXO set snapshot for AssumeUTXO fast sync");
let request = json!({
"jsonrpc": "2.0",
"method": "loadtxoutset",
"params": ["/path/to/utxo-snapshot.dat"], "id": 9
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Bootstrap from a UTXO snapshot instead of replaying the full chain");
println!(" Note: Snapshot must match a hardcoded AssumeUTXO checkpoint hash");
println!();
println!("10. verifychain - Verify blockchain database integrity");
let request = json!({
"jsonrpc": "2.0",
"method": "verifychain",
"params": [3, 6], "id": 10
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(
" Use: Verify block and UTXO set consistency (checklevel 0-4, higher=more thorough)"
);
println!(" Note: checklevel 3 checks all transactions; numblocks=0 checks entire chain");
println!();
println!("11. getchaintips - List all known chain tips including orphaned blocks");
let request = json!({
"jsonrpc": "2.0",
"method": "getchaintips",
"params": [],
"id": 11
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(
" Use: Inspect main chain tip and any orphaned forks (status: active/valid/invalid)"
);
println!();
println!("12. getchaintxstats - Transaction throughput statistics for a block window");
let nblocks = 2016u64; let request = json!({
"jsonrpc": "2.0",
"method": "getchaintxstats",
"params": [nblocks], "id": 12
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Get tx rate and total tx count over the last N blocks (default: one difficulty period)");
println!(" Note: Omit params for default window; pass blockhash as second param to anchor the window");
println!();
println!("13. getblockstats - Compute statistics for a specific block");
let request = json!({
"jsonrpc": "2.0",
"method": "getblockstats",
"params": [800_000u64, ["txs", "total_size", "totalfee"]],
"id": 13
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Per-block stats (fees, sizes, tx count); pass height or hash");
println!(
" Note: Omit stats array for all fields; specify subset for efficient partial queries"
);
println!();
println!("14. pruneblockchain - Prune stored block data up to a given height or timestamp");
let request = json!({
"jsonrpc": "2.0",
"method": "pruneblockchain",
"params": [800_000u64], "id": 14
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(
" Use: Free disk space by pruning old block data (node must be started with prune=N)"
);
println!(" Note: Pass a height to prune up to that point; pass a timestamp to prune by time");
println!();
println!("15. getpruneinfo - Get pruning status and available range");
let request = json!({
"jsonrpc": "2.0",
"method": "getpruneinfo",
"params": [],
"id": 15
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Check if pruning is enabled and the earliest block still available");
println!();
println!("16. invalidateblock - Mark a block as permanently invalid");
let request = json!({
"jsonrpc": "2.0",
"method": "invalidateblock",
"params": [block_hash],
"id": 16
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Force the node to ignore a block and its descendants (useful for testing)");
println!(
" Note: Counterpart to reconsiderblock; requires node restart or reconsiderblock to undo"
);
println!();
println!("17. reconsiderblock - Undo the effect of a previous invalidateblock call");
let request = json!({
"jsonrpc": "2.0",
"method": "reconsiderblock",
"params": [block_hash],
"id": 17
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Re-enable a block previously marked invalid with invalidateblock");
println!();
println!("18. waitfornewblock - Long-poll until a new block arrives");
let request = json!({
"jsonrpc": "2.0",
"method": "waitfornewblock",
"params": [5000], "id": 18
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Block until the next block is received; returns {{hash, height}}");
println!(" Note: Timeout in milliseconds; use 0 for infinite wait");
println!();
println!("19. waitforblock - Long-poll until a specific block hash is seen");
let request = json!({
"jsonrpc": "2.0",
"method": "waitforblock",
"params": [block_hash, 5000], "id": 19
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(" Use: Block until the node sees the given block hash; returns {{hash, height}}");
println!();
println!("20. waitforblockheight - Long-poll until chain reaches a given height");
let request = json!({
"jsonrpc": "2.0",
"method": "waitforblockheight",
"params": [800_001u64, 5000], "id": 20
});
println!(" Request: {}", serde_json::to_string_pretty(&request)?);
println!(
" Use: Block until the chain reaches or exceeds the given height; returns {{hash, height}}"
);
println!(" Note: All wait* methods support long-polling for real-time chain monitoring");
println!();
println!("Method Summary:");
println!(" getblockchaininfo - Full chain state (height, hash, IBD, difficulty)");
println!(" getblockcount - Current block height (integer)");
println!(" getbestblockhash - Tip block hash");
println!(" getblockhash - Hash at a given height");
println!(" getblockheader - Block header by hash (JSON or hex)");
println!(" getblock - Full block by hash (hex, JSON, or JSON+tx details)");
println!(" getdifficulty - Current proof-of-work difficulty");
println!(" gettxoutsetinfo - UTXO set size and total supply");
println!(" loadtxoutset - Load a UTXO snapshot for AssumeUTXO fast sync");
println!(" verifychain - Verify blockchain database integrity");
println!(" getchaintips - All known chain tips (main + orphans)");
println!(" getchaintxstats - Transaction throughput over a block window");
println!(" getblockstats - Per-block statistics (fees, sizes, tx count)");
println!(" pruneblockchain - Prune block data up to a height or timestamp");
println!(" getpruneinfo - Pruning status and earliest available block");
println!(" invalidateblock - Mark a block permanently invalid");
println!(" reconsiderblock - Undo a previous invalidateblock");
println!(" waitfornewblock - Long-poll for the next block");
println!(" waitforblock - Long-poll for a specific block hash");
println!(" waitforblockheight - Long-poll until chain reaches a height");
println!();
println!("To test with a running node:");
println!(" 1. Start node: blvm-node --network testnet");
println!(" 2. Send requests with curl or any HTTP client");
Ok(())
}