use blockchain::blocks::collateral::CollateralClaimTransaction; use blockchain::blocks::genesis::GenesisTransaction; use blockchain::blocks::loan_payment::ContractPaymentTransaction; use blockchain::blocks::loans::LoanContractTransaction; use blockchain::blocks::marketing::MarketingTransaction; use blockchain::blocks::nft::CreateNftTransaction; use blockchain::blocks::rewards::RewardsTransaction; use blockchain::blocks::swap::SwapTransaction; use blockchain::blocks::token::CreateTokenTransaction; use blockchain::blocks::transfer::TransferTransaction; use blockchain::blocks::vanity::VanityAddressTransaction; use blockchain::common::cli_prompts::{prompt_hidden_nonempty, prompt_wallet_path}; use blockchain::common::network_startup::get_connections; use blockchain::common::types::{ BORROWER_TYPE, COLLATERAL_TYPE, CREATE_NFT_TYPE, CREATE_TOKEN_TYPE, GENESIS_TYPE, LENDER_TYPE, MARKETING_TYPE, REWARDS_TYPE, SWAP_TYPE, TRANSFER_TYPE, VANITY_ADDRESS_TYPE, }; use blockchain::env; use blockchain::records::memory::response_channels::generate_uid; use blockchain::standalone_tools::connections::handshake; use blockchain::to_string_pretty; #[tokio::main] async fn main() { let hashmap_key = generate_uid(); // set the rpc command number let rpc_command = 17; // Get command-line arguments let args: Vec = env::args().collect(); // Check if a command-line argument is provided if args.len() != 2 { println!("Usage: ./lookup_transaction "); return; } // Extract the block number from the command-line argument let block_hash = match args[1].parse::() { Ok(num) => num, Err(_) => { println!("Please enter a hash"); return; } }; // Extract the encryption ley from the command-line argument 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; let json = block_hash.to_string(); let connections = get_connections().await; let mut connected: bool = false; // Iterate over the returned Vec and print each connection 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, json.clone(), rpc_command, handshake::HandshakeWallet::WalletKey { encryption_key: encryption_key.clone(), wallet_path: wallet_path.clone(), }, hashmap_key, ) .await; match result { Ok(response) => { if let Some(transaction_json) = decode_transaction_to_json(&response).await { println!("{transaction_json}"); connected = true; } else { 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!("{}", hex::encode(response)); connected = true; } } } Err(_) => connected = false, } } if !connected { eprintln!("failed to connect"); } } async fn decode_transaction_to_json(response: &[u8]) -> Option { if response.len() < 5 { return None; } let block_number = u32::from_le_bytes(response[0..4].try_into().ok()?); let txtype = response[4]; let body = &response[5..]; let json = match txtype { GENESIS_TYPE => { to_string_pretty(&GenesisTransaction::from_bytes(txtype, body).await.ok()?).ok()? } REWARDS_TYPE => { to_string_pretty(&RewardsTransaction::from_bytes(txtype, body).await.ok()?).ok()? } TRANSFER_TYPE => { to_string_pretty(&TransferTransaction::from_bytes(txtype, body).await.ok()?).ok()? } CREATE_TOKEN_TYPE => to_string_pretty( &CreateTokenTransaction::from_bytes(txtype, body) .await .ok()?, ) .ok()?, CREATE_NFT_TYPE => { to_string_pretty(&CreateNftTransaction::from_bytes(txtype, body).await.ok()?).ok()? } MARKETING_TYPE => { to_string_pretty(&MarketingTransaction::from_bytes(txtype, body).await.ok()?).ok()? } SWAP_TYPE => { to_string_pretty(&SwapTransaction::from_bytes(txtype, body).await.ok()?).ok()? } LENDER_TYPE => to_string_pretty( &LoanContractTransaction::from_bytes(txtype, body) .await .ok()?, ) .ok()?, BORROWER_TYPE => to_string_pretty( &ContractPaymentTransaction::from_bytes(txtype, body) .await .ok()?, ) .ok()?, COLLATERAL_TYPE => to_string_pretty( &CollateralClaimTransaction::from_bytes(txtype, body) .await .ok()?, ) .ok()?, VANITY_ADDRESS_TYPE => to_string_pretty( &VanityAddressTransaction::from_bytes(txtype, body) .await .ok()?, ) .ok()?, _ => return None, }; Some(format!("block: {block_number}\n{json}")) }