#!/usr/bin/env node
/**
 * Example: How to Send Signed Transactions to Besu RPC Nodes
 * 
 * This script demonstrates the correct way to send transactions to Besu,
 * which requires eth_sendRawTransaction instead of eth_sendTransaction.
 * 
 * Usage:
 *   node example-send-signed-transaction.js <rpc_url> <private_key> <to_address> <amount_eth>
 * 
 * Example:
 *   node example-send-signed-transaction.js http://192.168.11.250:8545 0x<private_key> 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb 0.01
 */

const https = require('https');
const http = require('http');
const { ethers } = require('ethers');

// Parse command line arguments
const args = process.argv.slice(2);
if (args.length < 4) {
    console.error('Usage: node example-send-signed-transaction.js <rpc_url> <private_key> <to_address> <amount_eth>');
    console.error('');
    console.error('Example:');
    console.error('  node example-send-signed-transaction.js http://192.168.11.250:8545 0x<private_key> 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb 0.01');
    process.exit(1);
}

const [rpcUrl, privateKey, toAddress, amountEth] = args;

async function sendSignedTransaction() {
    try {
        console.log('=== Besu Signed Transaction Example ===\n');
        
        // 1. Create wallet from private key
        console.log('1. Creating wallet from private key...');
        const wallet = new ethers.Wallet(privateKey);
        console.log(`   Address: ${wallet.address}\n`);
        
        // 2. Connect to RPC provider
        console.log('2. Connecting to RPC node...');
        const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
        
        // Verify connection
        const network = await provider.getNetwork();
        console.log(`   Chain ID: ${network.chainId}`);
        const balance = await provider.getBalance(wallet.address);
        console.log(`   Balance: ${ethers.utils.formatEther(balance)} ETH\n`);
        
        if (balance.lt(ethers.utils.parseEther(amountEth))) {
            console.error(`❌ Insufficient balance. Need ${amountEth} ETH, have ${ethers.utils.formatEther(balance)} ETH`);
            process.exit(1);
        }
        
        // 3. Get current gas price
        console.log('3. Getting gas price...');
        const gasPrice = await provider.getGasPrice();
        console.log(`   Gas Price: ${ethers.utils.formatUnits(gasPrice, 'gwei')} gwei\n`);
        
        // 4. Get nonce
        console.log('4. Getting transaction count (nonce)...');
        const nonce = await provider.getTransactionCount(wallet.address, 'pending');
        console.log(`   Nonce: ${nonce}\n`);
        
        // 5. Create transaction
        console.log('5. Creating transaction...');
        const tx = {
            to: toAddress,
            value: ethers.utils.parseEther(amountEth),
            gasLimit: 21000, // Standard transfer
            gasPrice: gasPrice,
            nonce: nonce,
            chainId: network.chainId
        };
        
        console.log(`   To: ${tx.to}`);
        console.log(`   Value: ${amountEth} ETH`);
        console.log(`   Gas Limit: ${tx.gasLimit}`);
        console.log(`   Gas Price: ${ethers.utils.formatUnits(tx.gasPrice, 'gwei')} gwei`);
        console.log(`   Nonce: ${tx.nonce}`);
        console.log(`   Chain ID: ${tx.chainId}\n`);
        
        // 6. Sign transaction
        console.log('6. Signing transaction...');
        const signedTx = await wallet.signTransaction(tx);
        console.log(`   Signed transaction length: ${signedTx.length} characters\n`);
        
        // 7. Send signed transaction via eth_sendRawTransaction
        console.log('7. Sending signed transaction via eth_sendRawTransaction...');
        const txResponse = await provider.sendTransaction(signedTx);
        console.log(`   ✅ Transaction hash: ${txResponse.hash}\n`);
        
        // 8. Wait for transaction to be mined
        console.log('8. Waiting for transaction to be mined...');
        const receipt = await txResponse.wait();
        
        if (receipt.status === 1) {
            console.log(`   ✅ Transaction successful!`);
            console.log(`   Block: ${receipt.blockNumber}`);
            console.log(`   Gas Used: ${receipt.gasUsed.toString()}`);
        } else {
            console.log(`   ❌ Transaction failed (status: ${receipt.status})`);
        }
        
        console.log('\n=== Transaction Complete ===');
        
    } catch (error) {
        console.error('\n❌ Error:', error.message);
        
        if (error.message.includes('eth_sendTransaction')) {
            console.error('\n⚠️  This error occurs if you try to use eth_sendTransaction.');
            console.error('   Besu requires eth_sendRawTransaction with signed transactions.');
        } else if (error.message.includes('insufficient funds')) {
            console.error('\n⚠️  Insufficient balance for this transaction.');
        } else if (error.message.includes('nonce')) {
            console.error('\n⚠️  Nonce error - transaction may already be pending.');
        }
        
        process.exit(1);
    }
}

// Run the example
sendSignedTransaction();
