use blockchain::common::cli_prompts::{prompt_hidden_nonempty, prompt_wallet_path}; use blockchain::common::network_startup::get_connections; use blockchain::encode; use blockchain::env; use blockchain::json; use blockchain::records::memory::response_channels::generate_uid; use blockchain::standalone_tools::connections::handshake; #[tokio::main] async fn main() { // Command 33 asks a peer for one loan contract by its 32-byte hash. let hashmap_key = generate_uid(); let rpc_command = 33; // The hash is passed as text here and encoded into binary request bytes later. let args: Vec = env::args().collect(); if args.len() != 2 { println!("Usage: ./contract_lookup_by_hash "); return; } let contract_hash = match args[1].parse::() { Ok(hash) => hash, Err(_) => { println!("Please enter a contract hash"); return; } }; let wallet_path = prompt_wallet_path().await; let encryption_key = prompt_hidden_nonempty( "What is your wallet decryption key? ", "Wallet key cannot be empty. Please try again.", ) .await; // Try each configured peer until one returns a response. let connections = get_connections().await; let mut connected = false; for conn in connections { if connected { break; } let socket_address = conn.parse().expect("Failed to parse the socket address"); let result = handshake::connect_and_handshake( socket_address, contract_hash.clone(), rpc_command, handshake::HandshakeWallet::WalletKey { encryption_key: encryption_key.clone(), wallet_path: wallet_path.clone(), }, hashmap_key, ) .await; match result { Ok(response) => { // Contract lookup replies are usually text; fallback to hex if the peer sends raw bytes. let response_text = String::from_utf8_lossy(&response); let trimmed = response_text.trim(); if !trimmed.is_empty() { println!("{trimmed}"); connected = true; } else if !response.is_empty() { println!( "{}", serde_json::to_string_pretty(&json!({ "hex": encode(response) })).unwrap() ); connected = true; } } Err(_) => { connected = false; } } } if !connected { eprintln!("failed to connect"); } }