import requests import json import sys from datetime import datetime # --- Configuration --- # The base URL for your mempool API instance. BASE_URL = "https://mempool.mikoshi.de/api/tx/" def format_transaction_details(tx_data): """Formats the JSON data from the API into a human-readable string.""" txid = tx_data.get("txid", "N/A") fee = tx_data.get("fee", 0) size = tx_data.get("size", 0) weight = tx_data.get("weight", 0) # Status details status = tx_data.get("status", {}) confirmed = status.get("confirmed", False) if confirmed: block_height = status.get("block_height", "N/A") block_time_unix = status.get("block_time", 0) block_time_str = datetime.utcfromtimestamp(block_time_unix).strftime('%Y-%m-%d %H:%M:%S UTC') status_str = f"āœ… Confirmed in block {block_height} at {block_time_str}" else: status_str = "āŒ› Unconfirmed" # --- Start building the output string --- output = [] output.append("=" * 80) output.append(f"TRANSACTION DETAILS FOR: {txid}") output.append("=" * 80) # General Info output.append("\n--- General ---") output.append(f"Status: {status_str}") output.append(f"Fee: {fee} sats") output.append(f"Size: {size} bytes") output.append(f"Weight: {weight} vB") output.append(f"Fee Rate: {fee/(weight/4):.2f} sat/vB") # Inputs (vin) vin = tx_data.get("vin", []) output.append(f"\n--- Inputs ({len(vin)}) ---") if not vin: output.append("No inputs found (likely a coinbase transaction).") for i, an_input in enumerate(vin, 1): prev_txid = an_input.get("txid", "N/A") prev_vout = an_input.get("vout", "N/A") prevout = an_input.get("prevout", {}) value = prevout.get("value", "N/A") address = prevout.get("scriptpubkey_address", "Address not available") output.append(f" {i}. From TX: {prev_txid[:20]}... | Output Index: {prev_vout}") output.append(f" Value: {value} sats | Spent by: {address}") # Outputs (vout) vout = tx_data.get("vout", []) output.append(f"\n--- Outputs ({len(vout)}) ---") for i, an_output in enumerate(vout, 1): value = an_output.get("value", "N/A") address = an_output.get("scriptpubkey_address", "Address not available") output.append(f" {i}. Value: {value} sats | To Address: {address}") output.append("\n" * 2) # Add space before the next transaction return "\n".join(output) def main(): """Main function to run the script.""" if len(sys.argv) != 3: print("Usage: python fetch_tx_details.py ") sys.exit(1) input_filename = sys.argv[1] output_filename = sys.argv[2] try: with open(input_filename, 'r') as f: txids = [line.strip() for line in f if line.strip()] except FileNotFoundError: print(f"Error: Input file '{input_filename}' not found.") sys.exit(1) print(f"Found {len(txids)} transaction IDs. Fetching details...") with open(output_filename, 'w') as out_file: for i, txid in enumerate(txids): print(f"({i+1}/{len(txids)}) Fetching {txid}...") try: response = requests.get(f"{BASE_URL}{txid}", timeout=10) # Check if the request was successful if response.status_code == 200: data = response.json() formatted_data = format_transaction_details(data) out_file.write(formatted_data) else: error_message = f"Failed to fetch {txid}. Status Code: {response.status_code}. Response: {response.text}\n\n" print(error_message) out_file.write(error_message) except requests.RequestException as e: error_message = f"An error occurred while fetching {txid}: {e}\n\n" print(error_message) out_file.write(error_message) print(f"\nāœ… Done! All details have been saved to '{output_filename}'.") if __name__ == "__main__": main()