var express = require('express');
const crypto  = require('crypto');
const solanaWeb3 = require('@solana/web3.js');
const { TronWeb } = require('tronweb');
const Wallet = require('ethereumjs-wallet');
const { Web3 } = require('web3');
const cors = require('cors');




var app = express();
app.use(express.json());


app.use(express.urlencoded({ extended: true }));

const corsOptions = {
  methods: ['GET', 'POST'],
};

// Enable CORS for all routes with the specified options
app.use(cors(corsOptions));

app.get('/wallet', function (req, res) {
  res.send('Hello World!');
});

app.get('/wallet/get_address', function (req, res) {


const solanaWeb3 = require('@solana/web3.js');
const bip39 = require('bip39');
const { Keypair } = solanaWeb3;
const { derivePath } = require('ed25519-hd-key'); 
const bs58 = require('bs58');

// Generate a mnemonic phrase
const mnemonic = bip39.generateMnemonic();
//console.log("Mnemonic:", mnemonic);

// Derive the seed from the mnemonic
//const seed = bip39.mnemonicToSeedSync(mnemonic);

// Derive the keypair from the seed
//const keypair = Keypair.fromSeed(seed.slice(0, 32)); // Solana keys are 32 bytes

//console.log("Publickey:", keypair.publicKey.toBase58());
//console.log("SecretKey:", Buffer.from(keypair.secretKey).toString('base64'));


const seed = bip39.mnemonicToSeedSync(mnemonic);

const path = `m/44'/501'/0'/0'`;  // ${i} specifies which account to generate

 // Derive the private key using the derivation path and seed
const derived = derivePath(path, seed.toString('hex'));
const privateKey = Buffer.from(derived.key);

  // Create a Solana keypair from the derived private key
const keypair = Keypair.fromSeed(privateKey);


  //const privateKeyBase58 = keypair.secretKey.toString('base58');
const privateKeyBase58 = bs58.encode(keypair.secretKey);

/*const wallet_info = {
            address: keypair.publicKey.toBase58(),
            privateKey: Buffer.from(keypair.secretKey).toString('base64'),
            mnemonic:mnemonic
        };*/
const wallet_info = {
            address: keypair.publicKey.toBase58(),
            privateKey: privateKeyBase58,
            mnemonic:mnemonic
        };

        // Send wallet information in the response
res.json(wallet_info);

});


app.get('/wallet/test_address', function (req, res) {

  res.send('Hello World!');
    
});

app.get('/wallet/btc_address', function (req, res) {


const bip39 = require("bip39");
const bitcoin = require("bitcoinjs-lib");
const HDKey = require("hdkey");
const CoinKey = require("coinkey");
const network = bitcoin.networks.bitcoin; 

const mnemonic = bip39.generateMnemonic();

const seed = bip39.mnemonicToSeedSync(mnemonic);


const hdKey = HDKey.fromMasterSeed(Buffer.from(seed, "hex"));


const path = "m/44'/0'/0'/0/0";


const child = hdKey.derive(path);


const coinKey = new CoinKey(child.privateKey, bitcoin.networks.bitcoin);


const { address: p2wpkhAddress } = bitcoin.payments.p2wpkh({
  pubkey: coinKey.publicKey,
  network: network, // Specify Bitcoin mainnet
});


const info = {
  address: p2wpkhAddress,                          // SegWit (P2WPKH) address
  publickey :coinKey.publicKey,
  privateKey: coinKey.privateWif,   // Private key in hexadecimal
  WIF: coinKey.privateWif,                         // Wallet Import Format (WIF) private key
  mnemonic: mnemonic,  
};


res.json(info);


});


app.get('/wallet/eth_address', function (req, res) {


const { ethers } = require("ethers");
const wallet = ethers.Wallet.createRandom();


const wallet_info = {
            address: wallet.address,
            privateKey: wallet.privateKey,
            mnemonic:wallet.mnemonic.phrase
        };

        // Send wallet information in the response
res.json(wallet_info);
 
 

});


app.get('/wallet/tron-address', async (req, res) => {
    
    const TronWeb = require('tronweb');

    // Create an instance of TronWeb
    const tronWeb = new TronWeb({
        fullHost: 'https://api.trongrid.io'  // You can use other nodes as well
    });
    
    // Function to generate a wallet
    const generateWallet = () => {
        const wallet = tronWeb.createRandom();
        
        //console.log('Mnemonic Phrase:', wallet.mnemonic.phrase);
        //console.log('Wallet Address:', wallet.address);
        //console.log('Private Key:', wallet.privateKey);
        
        
        const wallet_info = {
            address: wallet.address,
            privateKey: wallet.privateKey,
            mnemonic:wallet.mnemonic.phrase
        };

        // Send wallet information in the response
    res.json(wallet_info);
        
    };
    
    // Call the function to generate the wallet
    generateWallet();
    
    
});


app.post('/wallet/validate-address', (req, res) => {
 

  const { address,network } = req.body;
  
  
   let web3;
    let baseUrl;
    let chainName;
    
    // Determine the network and set appropriate values
    if (network === '2') {
        // Ethereum Mainnet
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/api';
        web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd'));
        chainName = 'ethereum';
    } else if (network === '3') {
        // Binance Smart Chain (BSC)
        ETHERSCAN_API_KEY = 'GIZWMXXDJG1TCNE824K3EQ3WXNHK979SMP';
        baseUrl = 'https://api.bscscan.com/api';
        chainName = 'binancecoin';
        web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'));
    } else if (network === '6') {
        // Polygon Network (Matic)
        ETHERSCAN_API_KEY = 'NT2HBAZM5Z53S4VBX2XXR5V9XHBMK1EPVZ';
        baseUrl = 'https://api.polygonscan.com/api';
        chainName = 'polygon-ecosystem-token';
        web3 = new Web3(new Web3.providers.HttpProvider('https://polygon-rpc.com/'));
    } else {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }

//console.log(req.body);

/*res.json({
        message: 'Data received',
        receivedData: address
    });*/
  // Check if the address is provided
  if (!address) {
    return res.status(400).json({valid: false, message: 'The address is required.' });
  }

  // Validate Ethereum address using Web3
  const isValid = web3.utils.isAddress(address);

  if (isValid) {
    res.json({ valid: true, message: 'The address is valid.' });
  } else {
    res.json({ valid: false, message: 'Address not matched for that network.' });
  }
});


app.post('/wallet/validate-btc', (req, res) => {
 
 const bitcoinAddressValidation = require('bitcoin-address-validation');
  const { address } = req.body;


  if (!address) {
    return res.status(400).json({valid: false, message: 'The address is required.' });
  }

  // Validate Ethereum address using Web3

  
  const isValid = bitcoinAddressValidation.validate(address);

  if (isValid) {
    res.json({ valid: true, message: 'The address is valid.' });
  } else {
    res.json({ valid: false, message: 'Address not matched for that network.' });
  }
});


app.post('/wallet/validate-tron', (req, res) => {
 
    const TronWeb = require('tronweb');

    // Create an instance of TronWeb
    const tronWeb = new TronWeb({
        fullHost: 'https://api.trongrid.io'  // You can use other nodes as well
    });
    
  const { address } = req.body;

  if (!address) {
    return res.status(400).json({valid: false, message: 'The address is required.' });
  }

  // Validate Ethereum address using Web3

  
    const isValid = tronWeb.isAddress(address);
  if (isValid) {
    res.json({ valid: true, message: 'The address is valid.' });
  } else {
    res.json({ valid: false, message: 'Address not matched for that network.' });
  }
});


app.post('/wallet/validate-sol', (req, res) => {
 
 const { address } = req.body;

  if (!address) {
    return res.status(400).json({valid: false, message: 'The address is required.' });
  }
  
  function isValidSolanaAddress(address) {
    try {
        const publicKey = new solanaWeb3.PublicKey(address);
        return true; // If no error is thrown, it's a valid Solana address
    } catch (error) {
        return false; // If an error is thrown, it's not a valid Solana address
    }
}

  // Validate Ethereum address using Web3

  if (isValidSolanaAddress(address)) { 
    res.json({ valid: true, message: 'The address is valid.' });
  } else {
    res.json({ valid: false, message: 'Address not matched for that network.' });
  }
});



app.post('/wallet/validate-btcprivate', (req, res) => {
 
const bitcoin = require('bitcoinjs-lib');
const tinysecp = require('tiny-secp256k1');
const ECPairFactory = require('ecpair').default; // ECPairFactory from the 'ecpair' package

const network = bitcoin.networks.bitcoin;  // Bitcoin mainnet network

// Initialize ECPair with tiny-secp256k1
const ECPair = ECPairFactory(tinysecp); 

const { private_key } = req.body;

  if (!private_key) {
    return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
  }

  let keyPair;

  try {
    // Check if the input is in WIF format
    if (private_key.startsWith('L') || private_key.startsWith('K') || private_key.startsWith('5')) {
      // If it's in WIF format, use ECPair to decode it
      keyPair = ECPair.fromWIF(private_key, network);
    } else {
      throw new Error('Invalid private key format');
    }

    // Ensure the public key is compressed
    let pubKey = keyPair.publicKey;

    if (pubKey.length !== 33) {
      // If the public key is uncompressed (65 bytes), compress it
      pubKey = bitcoin.crypto.publicKeyConvert(pubKey, true);  // Compress the public key
    }

    // Derive Bitcoin address from the compressed public key (P2PKH address)
    const { address } = bitcoin.payments.p2wpkh({ pubkey: Buffer.from(pubKey, "hex"), network });

    // Respond with the valid address
    res.json({
      valid: true,
      message: address, // Bitcoin address
      privateKey: private_key, // Return the original private key (WIF)
    });

  } catch (error) {
    // Handle invalid private key or other errors
    res.status(400).json({ valid: false, message: error.message });
  }
 


  
});

app.post('/wallet/validate-btcsecret', (req, res) => {
 
const bip39 = require("bip39");
const bitcoin = require("bitcoinjs-lib");
const HDKey = require("hdkey");
const CoinKey = require("coinkey");
const network = bitcoin.networks.bitcoin;
 
  let { private_key } = req.body;

if (!private_key) {
  return res.status(400).json({valid: false, message: 'The privatekey is required.' });
}

if (typeof private_key === 'string') {
  private_key = private_key; // No need to change anything here if it's already a string.
} else {
  private_key = private_key.join(' ');
}
 
async function validateAndGenerateWallet(mnemonic) {
  try {
    // Step 1: Validate the mnemonic
    if (!bip39.validateMnemonic(mnemonic)) {
      throw new Error("Invalid mnemonic phrase");
    }

    // Step 2: Convert the mnemonic to a seed
    const seed = bip39.mnemonicToSeedSync(mnemonic);

    // Step 3: Create an HD wallet key from the seed
    const hdKey = HDKey.fromMasterSeed(Buffer.from(seed, "hex"));

    // Step 4: Define the BIP44 path for Bitcoin (m/44'/0'/0'/0/0)
    const path = "m/44'/0'/0'/0/0";

    // Step 5: Derive a child key from the HD key using the defined path
    const child = hdKey.derive(path);

    // Step 6: Create a CoinKey from the derived child private key and specify the Bitcoin network
    const coinKey = new CoinKey(child.privateKey, bitcoin.networks.bitcoin);

    // Step 7: Generate the P2WPKH (SegWit) address using the public key
    const { address: p2wpkhAddress } = bitcoin.payments.p2wpkh({
      pubkey: coinKey.publicKey,
      network: network,
    });

    // Step 8: Prepare the wallet information
    const walletInfo = {
      address: p2wpkhAddress, // SegWit address (P2WPKH)
      path,                   // BIP44 path
      privateKey: coinKey.privateKey.toString("hex"), // Private key in hexadecimal
      WIF: coinKey.privateWif, // Wallet Import Format (WIF) private key
    };

    // Step 9: Return the wallet info
    return { success: true, walletInfo };

  } catch (error) {
    // Return an error message if something went wrong
    return { success: false, message: error.message };
  }
}

// Example usage: Replace 'your-mnemonic-here' with an actual mnemonic
const mnemonic = private_key;

validateAndGenerateWallet(mnemonic).then(result => {
  if (result.success) {
    res.json({ valid: true, message: result.walletInfo.address, privatekey:result.walletInfo.WIF });
  } else {
    res.json({ valid: false, message: result.error });
  }

 
});

});

app.post('/wallet/validate-ethprivate', (req, res) => {
 
const web3 = new Web3();
  const { private_key } = req.body;


  if (!private_key) {
    return res.status(400).json({valid: false, message: 'The privatekey is required.' });
  }

 
 function getAddressFromPrivateKey(privateKey) {
  try {
      
        if (!privateKey.startsWith("0x")) {
      privateKey = "0x" + privateKey;
    }
    // Web3 will throw an error if the private key is invalid
    const account = web3.eth.accounts.privateKeyToAccount(privateKey);
    
    // Return the Ethereum address if valid
    return account.address;
  } catch (error) {
    // If the private key is invalid, return null or an error message
    return null;
  }
}
 
  
  const address = getAddressFromPrivateKey(private_key);

  if (address) {
    res.json({ valid: true, message: address });
  } else {
    res.json({ valid: false, message: 'privatekey not matched for that network.' });
  }
});






app.post('/wallet/validate-ethsecret', (req, res) => {
 
const { Web3 } = require('web3');
 const ethers = require('ethers');
 
 let { private_key } = req.body;

  if (!private_key) {
    return res.status(400).json({valid: false, message: 'The secret phase is required.' });
  }  



if (typeof private_key === 'string') {
  private_key = private_key; // No need to change anything here if it's already a string.
} else {
  private_key = private_key.join(' ');
}

 
function validateMnemonic(mnemonic) {
  try {
      
    const normalizedMnemonic = mnemonic.toLowerCase();
    // Check if mnemonic is valid using ethers.js
    const mnemonicWallet = ethers.Wallet.fromPhrase(normalizedMnemonic);
    
    // Return address and private key if valid
    return {
      success: true,
      address: mnemonicWallet.address,
      privateKey: mnemonicWallet.privateKey
    };
  } catch (error) {
    // Return error info if invalid mnemonic
    return {
      success: false,
      error: 'Invalid mnemonic phrase: ' + private_key
    };
  }
}



 
  
const result = validateMnemonic(private_key);

  if (result.success) {
    res.json({ valid: true, message: result.address, privatekey:result.privateKey });
  } else {
    res.json({ valid: false, message: result.error });
  }
});




app.post('/wallet/validate-solprivate', (req, res) => {
 
const { Keypair } = require('@solana/web3.js');
const bs58 = require('bs58');
 
  const { private_key } = req.body;

  if (!private_key) {
    return res.status(400).json({valid: false, message: 'The privatekey is required.' });
  }

 


    function getAddressFromPrivateKey(privateKey) 
    {
        try 
        {
            // Ensure privateKey is a Buffer or Uint8Array
                const decodedKey = bs58.decode(privateKey);

            if (decodedKey.length !== 64) {
                console.error("Invalid private key length. It should be 64 bytes.");
                
                res.json({ valid: true, message: "Invalid private key length. It should be 64 bytes." });
                return false;
            }

        const privateKeyBytes = bs58.decode(privateKey);
            // Try to create a Keypair using the private key
         const keypair = Keypair.fromSecretKey(privateKeyBytes);
        
         console.log("Valid private key. Public key:", keypair.publicKey.toBase58());
         
         res.json({ valid: true, message: keypair.publicKey.toBase58() });
           // return true;
        } 
        catch (error) 
        {
        console.error("Invalid private key:", error);
        
        res.json({ valid: false, message: error });
       // return false;
        }
    }
 
 const address = getAddressFromPrivateKey(private_key);

  /*if (address) {
    res.json({ valid: true, message: address });
  } else {
    res.json({ valid: false, message: 'privatekey not matched for that network.' });
  }*/
});



app.post('/wallet/validate-solsecret', (req, res) => {
 
const { Keypair } = require('@solana/web3.js');
const bip39 = require('bip39');
const { derivePath } = require('ed25519-hd-key');  // For Solana path
const bs58 = require('bs58');
 


  let { private_key } = req.body;

if (!private_key) {
  return res.status(400).json({valid: false, message: 'The privatekey is required.' });
}

if (typeof private_key === 'string') {
  private_key = private_key; // No need to change anything here if it's already a string.
} else {
  private_key = private_key.join(' ');
}
  
  
    // Example Solana mnemonic
    const mnemonic = private_key;

    function getPrivateKeyFromMnemonic(mnemonic) {
    // Step 1: Check if the mnemonic is valid using bip39.validateMnemonic
    if (!bip39.validateMnemonic(mnemonic)) {
        console.log("Invalid mnemonic.");
        return false;
    }

    try {
        // Step 2: Generate seed from the mnemonic
        const seed = bip39.mnemonicToSeedSync(mnemonic);
        
        // Step 3: Create a Solana keypair using the seed (first 32 bytes)
        /*const keypair = Keypair.fromSeed(seed.slice(0, 32)); // Solana keypair is 32 bytes
        
        // Step 4: Get the private key and public key
        const privateKey = keypair.secretKey;
        const publicKey = keypair.publicKey.toBase58();

        // Convert the private key to Base58 format
        const privateKeyBase58 = bs58.default.encode(privateKey);

        // Display the keys
        //console.log("Private Key (Base58):", privateKeyBase58);
        //console.log("Public Key (Base58):", publicKey);

        //return { privateKey: privateKeyBase58, publicKey };*/
        
         const path = `m/44'/501'/0'/0'`; 
         const derived = derivePath(path, seed.toString('hex'));
         const privateKey = Buffer.from(derived.key);
         // Create a Solana keypair from the derived private key
         const keypair = Keypair.fromSeed(privateKey);
        //const privateKeyBase58 = keypair.secretKey.toString('base58');
        const privateKeyBase58 = bs58.encode(keypair.secretKey);
        
         res.json({ valid: true, message: keypair.publicKey.toBase58(), privatekey:privateKeyBase58 });
    } catch (error) {
        //console.log("Error generating keypair from mnemonic:", error.message || error);
        
         res.json({ valid: false, message: error.message || error });
        //return false;
    }
}

// Get the private and public key from the mnemonic
getPrivateKeyFromMnemonic(mnemonic);


  
  

 
});


app.post('/wallet/validate-tronprivate/', (req, res) => {
 
    const TronWeb = require('tronweb');


  const { private_key } = req.body;

  if (!private_key) {
    return res.status(400).json({valid: false, message: 'The secret phase is required.' });
  }
  
  function validateTronPrivateKey(privateKey) 
  {
      
      
      if (privateKey.startsWith('0x')) {
        privateKey = privateKey.slice(2);
    }
      
    // Ensure private key is a valid hex string and exactly 64 characters (32 bytes)
    const privateKeyRegex = /^[a-fA-F0-9]{64}$/;
    if (!privateKeyRegex.test(privateKey)) {
        console.error("Invalid private key. It must be a 64-character hexadecimal string.");
        res.json({ valid: false, message: "Invalid private key. It must be a 64-character hexadecimal string"});
        return false;
    }

    try {
        // Correctly initialize TronWeb instance
        const fullHost = 'https://api.trongrid.io'; // Use any valid Tron node endpoint
        const tronWeb = new TronWeb({
            fullHost: fullHost, 
            solidityNode: fullHost, // Make sure solidity node and full node are set
            eventServer: fullHost   // Event server endpoint for TronWeb
        });

        // Now try to use the private key to generate the public address
        //const account = tronWeb.accounts.privateKeyToAccount(privateKey);
        const account = tronWeb.address.fromPrivateKey(privateKey);

        // Print the public address and return the success status
        console.log("Valid private key. Public address:", account);
         res.json({ valid: true, message: account});
        return true;
    } catch (error) {
        // Print out detailed error message
        console.error("Error validating private key:", error.message || error);
        res.json({ valid: false, message: error.message || error });
        return false;
    }
}



 const address = validateTronPrivateKey(private_key);

 
});


app.post('/wallet/validate-tronsecret/', (req, res) => {
     const TronWeb = require('tronweb');

    // Create an instance of TronWeb
    const tronWeb = new TronWeb({
        fullHost: 'https://api.trongrid.io'  // You can use other nodes as well
    });

  let { private_key } = req.body;

if (!private_key) {
  return res.status(400).json({valid: false, message: 'The privatekey is required.' });
}

if (typeof private_key === 'string') {
  private_key = private_key; // No need to change anything here if it's already a string.
} else {
  private_key = private_key.join(' ');
}
  
  
    
    // Function to validate and generate wallet from mnemonic
    const generateWalletFromMnemonic = (mnemonic) => {
        try {
            // Validate and generate account from the mnemonic
            const account = tronWeb.fromMnemonic(mnemonic);
    
            //console.log('Mnemonic Phrase:', mnemonic);
            //console.log('Wallet Address:', account.address);  // Wallet address (public key)
            //console.log('Private Key:', account.privateKey);  // Private key
            
            res.json({ valid: true, message: account.address, privatekey:account.privateKey });
        } catch (error) {
           // console.log('Invalid mnemonic!', error.message);
            res.json({ valid: false, message: error.message });
            
            
        }
    };
    
    // Example mnemonic to validate
    const mnemonic = private_key;
    generateWalletFromMnemonic(mnemonic);

});


app.post('/wallet/sendtrx/', async (req, res) => {
    const TronWeb = require('tronweb');

    let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode,  amount } = req.body;

    // Input validation
    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
    }

    if (!receiveraddress) {
        return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
    }

    if (!amount || isNaN(amount)) {
        return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
    }
    
    


    // Process private key (if it's an array, join it)
    if (Array.isArray(private_key)) {
        private_key = private_key.join(' ');
    }

    try {
        // Create an instance of TronWeb
        const tronWeb = new TronWeb({
            fullHost: 'https://api.trongrid.io',
            //fullHost: 'https://nile.trongrid.io',
            privateKey: private_key
        });

        // Convert amount to SUN (1 TRX = 1,000,000 SUN)
        const amountInSun = Math.floor(amount * 1000000);
        
        // Get the address from the private key
        const senderAddress = tronWeb.address.fromPrivateKey(private_key);
        
        // Check if the receiver address is valid
        if (!tronWeb.isAddress(receiveraddress)) {
            return res.status(400).json({ valid: false, message: 'Invalid receiver address' });
        }

        // Create transaction
        const transaction = await tronWeb.transactionBuilder.sendTrx(
            receiveraddress,
            amountInSun,
            senderAddress
        );
        
        // Sign transaction
        const signedTx = await tronWeb.trx.sign(transaction);
        
        // Broadcast transaction
        const result = await tronWeb.trx.sendRawTransaction(signedTx);
        
        return res.json({ 
            valid: true, 
            message: 'Transaction successful',
            txId: result.txid,
            details: result
        });
        
    } catch (error) {
      // console.error('Transaction error:', error);
        return res.status(500).json({ 
            valid: false, 
            message: error,
            error: error
        });
    }
});


app.post('/wallet/sendtrc/', async (req, res) => {
    const TronWeb = require('tronweb');

    let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode,  amount } = req.body;

    // Input validation
    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
    }

    if (!receiveraddress) {
        return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
    }

    if (!amount || isNaN(amount)) {
        return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
    }
    
    // Process private key (if it's an array, join it)
    if (Array.isArray(private_key)) {
        private_key = private_key.join(' ');
    }

    try {
        // Create an instance of TronWeb
        const tronWeb = new TronWeb({
            fullHost: 'https://api.trongrid.io',
            //fullHost: 'https://nile.trongrid.io',
            privateKey: private_key
        });

        // Convert amount to SUN (1 TRX = 1,000,000 SUN)
        const amountInSun = Math.floor(amount * 1000000);
        
        // Get the address from the private key
        const senderAddress = tronWeb.address.fromPrivateKey(private_key);
        
        // Check if the receiver address is valid
        if (!tronWeb.isAddress(receiveraddress)) {
            return res.status(400).json({ valid: false, message: 'Invalid receiver address' });
        }
        
        const usdtContract = tokenaddress;
        
        
        const tx = await tronWeb.transactionBuilder.triggerSmartContract(
            usdtContract,
            'transfer(address,uint256)',
            {
                feeLimit: 15000000, // 15 TRX in Sun
                callValue: 0
            },
            [
                {
                    type: 'address',
                    value: receiveraddress
                },
                {
                    type: 'uint256',
                    value: tronWeb.toSun(amount) // Amount in USDT (10 USDT here)
                }
            ],
            senderAddress // Sender address
        );
        

        // Create transaction
        /*const transaction = await tronWeb.transactionBuilder.sendTrx(
            receiveraddress,
            amountInSun,
            senderAddress
        );
        
        // Sign transaction
        const signedTx = await tronWeb.trx.sign(transaction);
        
        // Broadcast transaction
        const result = await tronWeb.trx.sendRawTransaction(signedTx);*/
        
        
        const signedTx = await tronWeb.trx.sign(tx.transaction);
        
        // Broadcast transaction
        const result = await tronWeb.trx.sendRawTransaction(signedTx);
        
        
        return res.json({ 
            valid: true, 
            message: 'Transaction successful',
            txId: result.txid,
            details: result
        });
        
    } catch (error) {
       // console.error('Transaction error:', error);
        return res.status(500).json({ 
            valid: false, 
            message: error,
            error: error
        });
    }
});


app.post('/wallet/sendinfura/', async (req, res) => {
    const { Web3 } = require('web3');

    let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode, amount, network, apkey } = req.body;

    //const adminaddress = '0x6409d4061AeDE4E22c71Fd3617C36E68F60443E4';

    // Input validation
    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
    }

    if (!receiveraddress) {
        return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
    }

    if (!amount || isNaN(amount)) {
        return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
    }

    const mode = 'live'; // Can also be 'production' if needed
    let provider;
    let chainid;

    // Define provider and chain ID based on the network and mode
    if (mode == 'test') {
        if (network == '2') {
            provider = 'https://sepolia.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
            chainid = '11155111';
        } else if (network == '3') {
            provider = 'https://bsc-testnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
            chainid = '97';
        } else {
            provider = 'https://polygon-amoy.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
            chainid = '80001';
        }
    } else {
        // if (network == '2') {
        //     // provider = 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
        //     provider = 'https://lb.drpc.live/ethereum/AtZ8VojBR0iGpeycwFQkvoCGIJWsyQIR8JWHQmlfqV1j';
        //     chainid = '1';
        // } else if (network == '3') {
        //     provider = 'https://lb.drpc.live/bsc/AtZ8VojBR0iGpeycwFQkvoCGIJWsyQIR8JWHQmlfqV1j';
        //     // provider = 'https://bsc-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
        //     chainid = '56';
        // } else {
        //     provider = 'https://lb.drpc.live/polygon/AtZ8VojBR0iGpeycwFQkvoCGIJWsyQIR8JWHQmlfqV1j';
        //     // provider = 'https://polygon-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
        //     chainid = '137';
        // }
        if (network == '2') {
    provider = `https://lb.drpc.live/ethereum/${apkey}`;
    chainid = '1';
} else if (network == '3') {
    provider = `https://lb.drpc.live/bsc/${apkey}`;
    chainid = '56';
} else {
    provider = `https://lb.drpc.live/polygon/${apkey}`;
    chainid = '137';
}
    }

    // Process private key (if it's an array, join it)
    if (Array.isArray(private_key)) {
        private_key = private_key.join(' ');
    }
    
    const config = {
        rpcUrl: provider, // Replace with your key
        privateKey: private_key // Must start with 0x
    };

    
        try {
            
            
        const web3 = new Web3(new Web3.providers.HttpProvider(config.rpcUrl));
       
        const privateKey = config.privateKey;
        const signer = web3.eth.accounts.privateKeyToAccount(privateKey);
        web3.eth.accounts.wallet.add(signer);
        const senderAddress = signer.address;
        const nonce = await web3.eth.getTransactionCount(senderAddress,'pending');
            // const gasLimit = 100000;
        const gasPrice = await web3.eth.getGasPrice();
        //const adjustedGasPrice = gasPrice * 1.3; // Increase by 30% to make sure your transaction is prioritized
const adjustedGasPrice = BigInt(gasPrice) * BigInt(200) / BigInt(100);

    
            // Build transaction
            const tx = {
                 from: senderAddress,
                 to: receiveraddress,
                 value: web3.utils.toWei(amount, "ether"),
                 nonce: nonce,
                 gasPrice: adjustedGasPrice,
                 chainId: chainid, // Sepolia chain ID
                 type: "0x0" // EIP-1559 transaction
            };

             const gasLimit = await web3.eth.estimateGas(tx);
             tx.gasLimit = gasLimit;
             
            // Sign and send
            const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
            console.log(`Transaction signed`);
            
            // const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
            //     .once("transactionHash", (txhash) => {
            //         //console.log(`Mining transaction: https://${network}.etherscan.io/tx/${txhash}`);
            //     });

            // //console.log(`Transaction mined in block ${receipt.blockNumber}`);
            // //return receipt;
            
            // return res.status(500).json({
            //     valid: true,
            //     message: 'Transaction successfull.. Fund loaded shortly',
                
            // });
             web3.eth.sendSignedTransaction(signedTx.rawTransaction)
            .once("transactionHash", (txHash) => {
                return res.status(200).json({
                    valid: true,
                    message: 'Transaction broadcasted successfully.',
                    txHash: txHash
                });
            })
            .on("error", (err) => {
                return res.status(500).json({
                    valid: false,
                    message: 'Transaction broadcast failed: ' + err.message
                });
            });

            
        } catch (error) {
            //console.error(error);
            return res.status(500).json({
                valid: false,
                message: 'Transaction failed:'+ error.message,
                error: error.message
            });
        }
 });
 
 app.post('/wallet/sendinfuratoken/', async (req, res) => {
    const { Web3 } = require('web3');
    const web3 = new Web3();
    let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode, amount, network, adminaddress, adminfee, apkey } = req.body;

    // Fast input validation
    if (!private_key || !receiveraddress || !amount || isNaN(amount)) {
        return res.status(400).json({ 
            valid: false, 
            message: !private_key ? 'The privatekey is required.' : 
                     !receiveraddress ? 'The receiver address is required.' : 
                     'A valid amount is required.' 
        });
    }

    // Pre-configured networks for faster lookup
    const networks = {
        test: {
            '2': { provider: 'https://sepolia.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '11155111' },
            '3': { provider: 'https://bsc-testnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '97' },
            'default': { provider: 'https://polygon-mumbai.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '80001' }
        },
        // live: {
        //     '2': { provider: 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '1' },
        //     '3': { provider: 'https://bsc-mainnet.infura.io/v3/6c15032eb44d44bab858c8bd992c37ef', chainid: '56' },
        //     'default': { provider: 'https://polygon-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '137' }
        // }
        live: {
            '2': { provider: `https://lb.drpc.live/ethereum/${apkey}`, chainid: '1' },
            '3': { provider: `https://lb.drpc.live/bsc/${apkey}`, chainid: '56' },
            'default': { provider: `https://lb.drpc.live/polygon/${apkey}`, chainid: '137' }
        }
    };

    const mode = 'live';
    const networkConfig = networks[mode][network] || networks[mode]['default'];
    const { provider, chainid } = networkConfig;

    if (Array.isArray(private_key)) {
        private_key = private_key.join(' ');
    }

    const config = {
        rpcUrl: provider,
        privateKey: private_key
    };

    try {
        // Initialize web3 with provider
        const web3 = new Web3(new Web3.providers.HttpProvider(config.rpcUrl));
        
        // Get sender address and set up account
        const signer = web3.eth.accounts.privateKeyToAccount(config.privateKey);
        web3.eth.accounts.wallet.add(signer);
        const senderAddress = signer.address;

        // Token ABI (minimal for transfer operations)
        const tokenAbi = [
            {
                "constant": false,
                "inputs": [
                    {"name": "_to", "type": "address"},
                    {"name": "_value", "type": "uint256"}
                ],
                "name": "transfer",
                "outputs": [{"name": "", "type": "bool"}],
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [{"name": "_owner", "type": "address"}],
                "name": "balanceOf",
                "outputs": [{"name": "balance", "type": "uint256"}],
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [],
                "name": "decimals",
                "outputs": [{"name": "", "type": "uint8"}],
                "type": "function"
            }
        ];

        const tokenContract = new web3.eth.Contract(tokenAbi, tokenaddress);

        // Execute all required calls in parallel for maximum speed
        const [decimals, balance, nativeBalance, nonce] = await Promise.all([
            tokenContract.methods.decimals().call(),
            tokenContract.methods.balanceOf(senderAddress).call(),
            web3.eth.getBalance(senderAddress),
            web3.eth.getTransactionCount(senderAddress, 'pending')
        ]);

        // FIX: Get proper gas price for Ethereum mainnet (ERC-20)
        let gasPrice;
        if (network === '2') { // Ethereum mainnet
            // For Ethereum, use higher gas price for faster confirmation
            const currentGasPrice = await web3.eth.getGasPrice();
            gasPrice = BigInt(currentGasPrice) * 150n / 100n; // 50% premium for Ethereum
        } else {
            // For BSC and Polygon, use normal gas price
            const currentGasPrice = await web3.eth.getGasPrice();
            gasPrice = BigInt(currentGasPrice) * 110n / 100n; // 10% premium for BSC/Polygon
        }

        // Convert to Gwei for logging
        const gasPriceGwei = Number(gasPrice) / 1e9;
        console.log(`Using gas price: ${gasPriceGwei.toFixed(2)} Gwei`);

        // Proper decimal handling for all amounts
        const tokenDecimals = parseInt(decimals);
        const multiplier = Math.pow(10, tokenDecimals);
        
        // Convert amount to token units with proper decimal precision
        const amountNumber = parseFloat(amount);
        const tokenAmount = BigInt(Math.floor(amountNumber * multiplier));

        // Validate balances
        if (BigInt(balance) < tokenAmount) {
            return res.status(400).json({ valid: false, message: "Insufficient token balance" });
        }

        // Use your original gas limits
        const tokenGasLimit = 100000;
        const nativeGasLimit = 21000;
        const totalGasLimit = tokenGasLimit + nativeGasLimit;
        const estimatedGasCost = BigInt(totalGasLimit) * gasPrice;
        
        // Convert admin fee to wei
        const adminFeeWei = web3.utils.toWei(adminfee.toString(), 'ether');
        const adminFeeBigInt = BigInt(adminFeeWei);
        const totalNativeRequired = adminFeeBigInt + estimatedGasCost;

        if (BigInt(nativeBalance) < totalNativeRequired) {
            return res.status(400).json({ valid: false, message: 'Insufficient native currency for gas fees + admin fee' });
        }

        // Prepare and send transactions in background
        const txData = tokenContract.methods.transfer(receiveraddress, tokenAmount.toString()).encodeABI();
        
        const tx = {
            from: senderAddress,
            to: tokenaddress,
            data: txData,
            nonce: Number(nonce),
            chainId: Number(chainid),
            gas: tokenGasLimit,
            gasPrice: gasPrice.toString() // Use the calculated gas price
        };

        const signedTx = await web3.eth.accounts.signTransaction(tx, config.privateKey);
        
        // Send admin fee transaction in background
        const adminTx = {
            from: senderAddress,
            to: adminaddress,
            value: web3.utils.toWei(adminfee, "ether"),
            nonce: Number(nonce) + 1,
            chainId: Number(chainid),
            gas: nativeGasLimit,
            gasPrice: gasPrice.toString() // Use same gas price
        };

        const signedAdminTx = await web3.eth.accounts.signTransaction(adminTx, config.privateKey);

        // Return immediately after sending, don't wait for confirmation
        Promise.all([
            web3.eth.sendSignedTransaction(signedTx.rawTransaction),
            web3.eth.sendSignedTransaction(signedAdminTx.rawTransaction)
        ]).then(([tokenResult, adminResult]) => {
            // This will execute in background
            console.log('Token TX Hash:', tokenResult.transactionHash);
            console.log('Admin Fee TX Hash:', adminResult.transactionHash);
        }).catch(error => {
            // Log error but don't affect response
            console.error('Transaction failed in background:', error);
        });

        // Return success immediately with the exact same format as sample code
        return res.json({
            valid: true,
            message: 'Transaction submitted successfully',
            txHash: signedTx.transactionHash // Return the hash from the signed transaction
        });

    } catch (error) {
        console.error('Transaction setup failed:', error);
        return res.status(500).json({
            valid: false,
            message: 'Token transfer setup failed: ' + error.message
        });
    }
});
 
//  app.post('/wallet/sendinfuratoken/', async (req, res) => {
//     const { Web3 } = require('web3');
//     const web3 = new Web3();
//     let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode, amount, network, adminaddress, adminfee } = req.body;

//     // Fast input validation
//     if (!private_key || !receiveraddress || !amount || isNaN(amount)) {
//         return res.status(400).json({ 
//             valid: false, 
//             message: !private_key ? 'The privatekey is required.' : 
//                      !receiveraddress ? 'The receiver address is required.' : 
//                      'A valid amount is required.' 
//         });
//     }

//     // Pre-configured networks for faster lookup
//     const networks = {
//         test: {
//             '2': { provider: 'https://sepolia.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '11155111' },
//             '3': { provider: 'https://bsc-testnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '97' },
//             'default': { provider: 'https://polygon-mumbai.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '80001' }
//         },
//         live: {
//             '2': { provider: 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '1' },
//             '3': { provider: 'https://bsc-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '56' },
//             'default': { provider: 'https://polygon-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '137' }
//         }
//     };

//     const mode = 'live';
//     const networkConfig = networks[mode][network] || networks[mode]['default'];
//     const { provider, chainid } = networkConfig;

//     if (Array.isArray(private_key)) {
//         private_key = private_key.join(' ');
//     }

//     const config = {
//         rpcUrl: provider,
//         privateKey: private_key
//     };

//     try {
//         // Initialize web3 with provider
//         const web3 = new Web3(new Web3.providers.HttpProvider(config.rpcUrl));
        
//         // Get sender address and set up account
//         const signer = web3.eth.accounts.privateKeyToAccount(config.privateKey);
//         web3.eth.accounts.wallet.add(signer);
//         const senderAddress = signer.address;

//         // Token ABI (minimal for transfer operations)
//         const tokenAbi = [
//             {
//                 "constant": false,
//                 "inputs": [
//                     {"name": "_to", "type": "address"},
//                     {"name": "_value", "type": "uint256"}
//                 ],
//                 "name": "transfer",
//                 "outputs": [{"name": "", "type": "bool"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [{"name": "_owner", "type": "address"}],
//                 "name": "balanceOf",
//                 "outputs": [{"name": "balance", "type": "uint256"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [],
//                 "name": "decimals",
//                 "outputs": [{"name": "", "type": "uint8"}],
//                 "type": "function"
//             }
//         ];

//         const tokenContract = new web3.eth.Contract(tokenAbi, tokenaddress);

//         // Execute all required calls in parallel for maximum speed
//         const [decimals, balance, nativeBalance, nonce, gasPrice] = await Promise.all([
//             tokenContract.methods.decimals().call(),
//             tokenContract.methods.balanceOf(senderAddress).call(),
//             web3.eth.getBalance(senderAddress),
//             web3.eth.getTransactionCount(senderAddress, 'pending'),
//             web3.eth.getGasPrice()
//         ]);

//         // FIXED: Proper decimal handling for all amounts (0.01, 5, 10, 100, etc.)
//         const tokenDecimals = parseInt(decimals);
//         const multiplier = Math.pow(10, tokenDecimals);
        
//         // Convert amount to token units with proper decimal precision
//         const amountNumber = parseFloat(amount);
//         const tokenAmount = BigInt(Math.floor(amountNumber * multiplier));

//         // Validate token balance
//         const userBalance = BigInt(balance);
//         if (userBalance < tokenAmount) {
//             return res.status(400).json({ 
//                 valid: false, 
//                 message: `Insufficient token balance. Required: ${amountNumber} USDT, Available: ${(Number(userBalance) / multiplier).toFixed(tokenDecimals)} USDT` 
//             });
//         }

//         // Calculate gas costs
//         const tokenGasLimit = 100000;
//         const nativeGasLimit = 21000;
//         const totalGasLimit = tokenGasLimit + nativeGasLimit;
//         const gasPriceBigInt = BigInt(gasPrice);
//         const estimatedGasCost = BigInt(totalGasLimit) * gasPriceBigInt;
        
//         // Convert admin fee to wei
//         const adminFeeWei = web3.utils.toWei(adminfee.toString(), 'ether');
//         const adminFeeBigInt = BigInt(adminFeeWei);
//         const totalNativeRequired = adminFeeBigInt + estimatedGasCost;

//         const userNativeBalance = BigInt(nativeBalance);
//         if (userNativeBalance < totalNativeRequired) {
//             const requiredEth = web3.utils.fromWei(totalNativeRequired.toString(), 'ether');
//             const availableEth = web3.utils.fromWei(nativeBalance.toString(), 'ether');
//             return res.status(400).json({ 
//                 valid: false, 
//                 message: `Insufficient native currency for gas fees + admin fee. Required: ${requiredEth}, Available: ${availableEth}` 
//             });
//         }

//         // Prepare and send transactions in background
//         const txData = tokenContract.methods.transfer(receiveraddress, tokenAmount.toString()).encodeABI();
        
//         const tx = {
//             from: senderAddress,
//             to: tokenaddress,
//             data: txData,
//             nonce: Number(nonce),
//             chainId: Number(chainid),
//             gas: tokenGasLimit,
//             gasPrice: gasPrice
//         };

//         const signedTx = await web3.eth.accounts.signTransaction(tx, config.privateKey);
        
//         // Send admin fee transaction in background
//         const adminTx = {
//             from: senderAddress,
//             to: adminaddress,
//             value: adminFeeWei,
//             nonce: Number(nonce) + 1,
//             chainId: Number(chainid),
//             gas: nativeGasLimit,
//             gasPrice: gasPrice
//         };

//         const signedAdminTx = await web3.eth.accounts.signTransaction(adminTx, config.privateKey);

//         // Return immediately after sending, don't wait for confirmation
//         Promise.all([
//             web3.eth.sendSignedTransaction(signedTx.rawTransaction),
//             web3.eth.sendSignedTransaction(signedAdminTx.rawTransaction)
//         ]).then(([tokenResult, adminResult]) => {
//             // This will execute in background
//             console.log('Token TX Hash:', tokenResult.transactionHash);
//             console.log('Admin Fee TX Hash:', adminResult.transactionHash);
//             console.log(`Sent ${amount} USDT to ${receiveraddress}`);
//             console.log(`Sent ${adminfee} native token fee to admin`);
//         }).catch(error => {
//             // Log error but don't affect response
//             console.error('Transaction failed in background:', error);
//         });

//         // Return success immediately with the exact same format as sample code
//         return res.json({
//             valid: true,
//             message: 'Transaction submitted successfully',
//             txHash: signedTx.transactionHash // Return the hash from the signed transaction
//         });

//     } catch (error) {
//         console.error('Transaction setup failed:', error);
//         return res.status(500).json({
//             valid: false,
//             message: 'Token transfer setup failed: ' + error.message
//         });
//     }
// });

// app.post('/wallet/sendinfuratoken/', async (req, res) => {
//     const { Web3 } = require('web3');
//     const web3 = new Web3();
//     let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode, amount, network } = req.body;

//     // Fast input validation
//     if (!private_key || !receiveraddress || !amount || isNaN(amount)) {
//         return res.status(400).json({ 
//             valid: false, 
//             message: !private_key ? 'The privatekey is required.' : 
//                      !receiveraddress ? 'The receiver address is required.' : 
//                      'A valid amount is required.' 
//         });
//     }

//     // Pre-configured networks for faster lookup
//     const networks = {
//         test: {
//             '2': { provider: 'https://sepolia.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '11155111' },
//             '3': { provider: 'https://bsc-testnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '97' },
//             'default': { provider: 'https://polygon-mumbai.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '80001' }
//         },
//         live: {
//             '2': { provider: 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '1' },
//             '3': { provider: 'https://bsc-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '56' },
//             'default': { provider: 'https://polygon-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd', chainid: '137' }
//         }
//     };

//     const mode = 'live';
//     const networkConfig = networks[mode][network] || networks[mode]['default'];
//     const { provider, chainid } = networkConfig;

//     if (Array.isArray(private_key)) {
//         private_key = private_key.join(' ');
//     }

//     const config = {
//         rpcUrl: provider,
//         privateKey: private_key
//     };

//     try {
//         // Initialize web3 with provider
//         const web3 = new Web3(new Web3.providers.HttpProvider(config.rpcUrl));
        
//         // Get sender address and set up account
//         const signer = web3.eth.accounts.privateKeyToAccount(config.privateKey);
//         web3.eth.accounts.wallet.add(signer);
//         const senderAddress = signer.address;

//         // Token ABI (minimal for transfer operations)
//         const tokenAbi = [
//             {
//                 "constant": false,
//                 "inputs": [
//                     {"name": "_to", "type": "address"},
//                     {"name": "_value", "type": "uint256"}
//                 ],
//                 "name": "transfer",
//                 "outputs": [{"name": "", "type": "bool"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [{"name": "_owner", "type": "address"}],
//                 "name": "balanceOf",
//                 "outputs": [{"name": "balance", "type": "uint256"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [],
//                 "name": "decimals",
//                 "outputs": [{"name": "", "type": "uint8"}],
//                 "type": "function"
//             }
//         ];

//         const tokenContract = new web3.eth.Contract(tokenAbi, tokenaddress);

//         // Execute all required calls in parallel for maximum speed
//         const [decimals, balance, nativeBalance, nonce, gasPrice] = await Promise.all([
//             tokenContract.methods.decimals().call(),
//             tokenContract.methods.balanceOf(senderAddress).call(),
//             web3.eth.getBalance(senderAddress),
//             web3.eth.getTransactionCount(senderAddress),
//             web3.eth.getGasPrice()
//         ]);

//         // Calculate token amount
//         const tokenDecimals = BigInt(decimals);
//         const multiplier = 10n ** tokenDecimals;
//         const tokenAmount = BigInt((Number(amount) * Number(multiplier)).toFixed(0));

//         // Validate balances
//         if (BigInt(balance) < tokenAmount) {
//             return res.status(400).json({ valid: false, message: "Insufficient token balance" });
//         }

//         const gasLimit = 100000;
//         const estimatedGasCost = BigInt(gasLimit) * BigInt(gasPrice);

//         if (BigInt(nativeBalance) < estimatedGasCost) {
//             return res.status(400).json({ valid: false, message: 'Insufficient native currency for gas fees' });
//         }

//         // Prepare and send transaction
//         const txData = tokenContract.methods.transfer(receiveraddress, tokenAmount.toString()).encodeABI();
        
//         const tx = {
//             from: senderAddress,
//             to: tokenaddress,
//             data: txData,
//             nonce: nonce,
//             chainId: chainid,
//             gas: gasLimit,
//             gasPrice: gasPrice
//         };

//         const signedTx = await web3.eth.accounts.signTransaction(tx, config.privateKey);
        
//         // Return immediately after sending, don't wait for confirmation
//         web3.eth.sendSignedTransaction(signedTx.rawTransaction)
//             .on('transactionHash', hash => {
//                 // This will execute in background
//                 console.log('TX Hash:', hash);
//             })
//             .on('error', error => {
//                 // Log error but don't affect response
//                 console.error('Transaction failed in background:', error);
//             });

//         // Return success immediately with the expected transaction structure
//         return res.json({
//             valid: true,
//             message: 'Transaction submitted successfully',
//             txHash: signedTx.transactionHash // Return the hash from the signed transaction
//         });

//     } catch (error) {
//         console.error('Transaction setup failed:', error);
//         return res.status(500).json({
//             valid: false,
//             message: 'Token transfer setup failed: ' + error.message
//         });
//     }
// });

//  app.post('/wallet/sendinfuratoken/', async (req, res) => {
//     const { Web3 } = require('web3');
//     const web3 = new Web3();
//     let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode, amount, network } = req.body;

//     // Input validation
//     if (!private_key) {
//         return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
//     }
//     if (!receiveraddress) {
//         return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
//     }
//     if (!amount || isNaN(amount)) {
//         return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
//     }

//     const mode = 'live'; 
//     let provider, chainid;

//     if (mode === 'test') {
//         if (network == '2') { 
//             provider = 'https://sepolia.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '11155111';
//         } else if (network == '3') { 
//             provider = 'https://bsc-testnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '97';
//         } else { 
//             provider = 'https://polygon-mumbai.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '80001';
//         }
//     } else { 
//         if (network == '2') { 
//             provider = 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '1';
//         } else if (network == '3') { 
//             provider = 'https://bsc-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '56';
//         } else { 
//             provider = 'https://polygon-mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd';
//             chainid = '137';
//         }
//     }
//     if (Array.isArray(private_key)) {
//         private_key = private_key.join(' ');
//     }

//     const config = {
//         rpcUrl: provider,
//         privateKey: private_key
//     };

//     try {
//         const web3 = new Web3(new Web3.providers.HttpProvider(config.rpcUrl));
//         const signer = web3.eth.accounts.privateKeyToAccount(config.privateKey);
//         web3.eth.accounts.wallet.add(signer);
//         const senderAddress = signer.address;

//         const tokenAbi = [
//             {
//                 "constant": false,
//                 "inputs": [
//                     {"name": "_to", "type": "address"},
//                     {"name": "_value", "type": "uint256"}
//                 ],
//                 "name": "transfer",
//                 "outputs": [{"name": "", "type": "bool"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [{"name": "_owner", "type": "address"}],
//                 "name": "balanceOf",
//                 "outputs": [{"name": "balance", "type": "uint256"}],
//                 "type": "function"
//             },
//             {
//                 "constant": true,
//                 "inputs": [],
//                 "name": "decimals",
//                 "outputs": [{"name": "", "type": "uint8"}],
//                 "type": "function"
//             }
//         ];

//         const tokenContract = new web3.eth.Contract(tokenAbi, tokenaddress);
//         // const decimals = await tokenContract.methods.decimals().call();
            
//         //   let tokenAmount;

//         //         if (Number.isInteger(Number(amount))) {
//         //             tokenAmount = BigInt(amount) * (10n ** BigInt(decimals));
//         //         } else {
//         //             const raw = web3.utils.toWei(amount.toString(), 'ether');
//         //             tokenAmount = BigInt(raw); // convert to BigInt for consistency
//         //         }
//         const decimals = await tokenContract.methods.decimals().call();
//          const tokenDecimals = BigInt(decimals);

//         // Convert amount to smallest unit using token decimals
//         const multiplier = 10n ** tokenDecimals;
//         const tokenAmount = BigInt((Number(amount) * Number(multiplier)).toFixed(0));


//         const balance = await tokenContract.methods.balanceOf(senderAddress).call();
//         if (BigInt(balance) < tokenAmount) {
//             return res.status(400).json({ valid: false, message: "Insufficient token balance" });
//         }

//         const nativeBalance = await web3.eth.getBalance(senderAddress);
//         const gasLimit = 100000;
//         const gasPrice = await web3.eth.getGasPrice();
//         const estimatedGasCost = BigInt(gasLimit) * BigInt(gasPrice);

//         if (BigInt(nativeBalance) < estimatedGasCost) {
//             return res.status(400).json({ valid: false, message: 'Insufficient native currency for gas fees' });
//         }
//         const txData = tokenContract.methods.transfer(receiveraddress, tokenAmount.toString()).encodeABI();
//         const tx = {
//             from: senderAddress,
//             to: tokenaddress,
//             data: txData,
//             nonce: await web3.eth.getTransactionCount(senderAddress),
//             chainId: chainid,
//             gas: gasLimit,
//             gasPrice: gasPrice
//         };
//         const signedTx = await web3.eth.accounts.signTransaction(tx, config.privateKey);
//         const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);

//         return res.json({
//             valid: true,
//             message: 'Transaction successful',
//             txHash: receipt.transactionHash
//         });
        
//     //     web3.eth.sendSignedTransaction(signedTx.rawTransaction)
//     // .on('transactionHash', hash => {
//     //     console.log('TX Hash:', hash);
//     //     res.json({ 
//     //         valid: true, 
//     //         message: 'Transaction successful', 
//     //         txHash: hash 
//     //     });
//     // });


//     } catch (error) {
//         console.error('Transaction failed:', error);
//         return res.status(500).json({
//             valid: false,
//             message: 'Token transfer failed: ' + error.message
//         });
//     }
// });


// app.post('/wallet/sendbtc/', async (req, res) => {
//   const bitcoin = require('bitcoinjs-lib');
//   const { initEccLib } = require('bitcoinjs-lib');
//   const ecc = require('tiny-secp256k1');
//   const ECPairFactory = require('ecpair').ECPairFactory;
//   const axios = require('axios');

//   initEccLib(ecc);
//   const ECPair = ECPairFactory(ecc);
//   const validator = (pubkey, msghash, signature) => ecc.verify(msghash, pubkey, signature);

//   // Get data from request
//   const { private_key, receiveraddress, amount, admin_address, admin_fee, wallet_mode } = req.body;

//   // Input validation
//   if (!private_key || !receiveraddress || !amount || isNaN(amount) || parseFloat(amount) <= 0) {
//     return res.status(400).json({ valid: false, message: 'Invalid user input.' });
//   }

//   if (!admin_address || !admin_fee || isNaN(admin_fee) || parseFloat(admin_fee) < 0) {
//     return res.status(400).json({ valid: false, message: 'Invalid admin address or fee.' });
//   }

//   try {
//     const network = wallet_mode === 'mainnet' ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
//     const chain = wallet_mode === 'mainnet' ? 'main' : 'test3';

//     // Clean private key
//     const cleanedKey = private_key.trim().replace(/\s+/g, '');
//     let keyPair;

//     if (/^[KL5]/.test(cleanedKey)) {
//       keyPair = ECPair.fromWIF(cleanedKey, network);
//     } else if (/^[0-9a-fA-F]{64}$/.test(cleanedKey)) {
//       keyPair = ECPair.fromPrivateKey(Buffer.from(cleanedKey, 'hex'), { network });
//     } else {
//       return res.status(400).json({ valid: false, message: 'Invalid private key format.' });
//     }

//     const { address: senderAddress } = bitcoin.payments.p2wpkh({
//       pubkey: keyPair.publicKey,
//       network
//     });

//     // Fetch UTXOs
//     const { data: utxoData } = await axios.get(
//       `https://api.blockcypher.com/v1/btc/${chain}/addrs/${senderAddress}?unspentOnly=true`
//     );
//     const utxos = utxoData.txrefs || [];
//     if (!utxos.length) return res.status(400).json({ valid: false, message: 'Insufficient balance.' });

//     // Fee estimate
//     const { data: feeEstimates } = await axios.get(`https://api.blockcypher.com/v1/btc/${chain}`);
//     const feeRate = Math.max(feeEstimates.low_fee_per_kb / 1000, 10); // sat/vB

//     const psbt = new bitcoin.Psbt({ network });
//     const userAmountSats = Math.floor(parseFloat(amount) * 1e8);
//     const adminFeeSats = Math.floor(parseFloat(admin_fee) * 1e8);
//     let inputSum = 0;

//     // Add inputs
//     for (const utxo of utxos) {
//       psbt.addInput({
//         hash: utxo.tx_hash,
//         index: utxo.tx_output_n,
//         witnessUtxo: {
//           script: bitcoin.address.toOutputScript(senderAddress, network),
//           value: utxo.value
//         }
//       });
//       inputSum += utxo.value;
//     }

//     // Estimate fee (3 outputs: user + admin + change)
//     const inputCount = utxos.length;
//     const outputCount = 3;
//     const txSize = inputCount * 68 + outputCount * 31 + 10;
//     const estimatedFee = Math.ceil(txSize * feeRate);

//     const totalRequired = userAmountSats + adminFeeSats + estimatedFee;
//     if (inputSum < totalRequired) {
//       return res.status(400).json({
//         valid: false,
//         message: `Insufficient funds. Need ${(totalRequired / 1e8).toFixed(8)} BTC, have ${(inputSum / 1e8).toFixed(8)} BTC`
//       });
//     }

//     const change = inputSum - userAmountSats - adminFeeSats - estimatedFee;

//     // Add outputs
//     psbt.addOutput({ address: receiveraddress, value: userAmountSats }); // User
//     psbt.addOutput({ address: admin_address, value: adminFeeSats });      // Admin
//     if (change > 0) psbt.addOutput({ address: senderAddress, value: change }); // Change

//     // Sign and finalize
//     psbt.signAllInputs(keyPair);
//     if (!psbt.validateSignaturesOfAllInputs(validator)) {
//       return res.status(500).json({ valid: false, message: 'Invalid signature.' });
//     }
//     psbt.finalizeAllInputs();
//     const txHex = psbt.extractTransaction().toHex();

//     // Broadcast
//     const { data: broadcastResult } = await axios.post(
//       `https://api.blockcypher.com/v1/btc/${chain}/txs/push`,
//       { tx: txHex }
//     );

//     return res.json({
//       valid: true,
//       message: 'Transaction successful.',
//       txId: broadcastResult.tx.hash,
//       explorerUrl: `https://live.blockcypher.com/btc${wallet_mode === 'mainnet' ? '' : '-testnet'}/tx/${broadcastResult.tx.hash}/`,
//       fee: (estimatedFee / 1e8).toFixed(8) + ' BTC'
//     });

//   } catch (error) {
//     return res.status(500).json({
//       valid: false,
//       message: error.response?.data?.error || error.message,
//       details: error.response?.data || error.stack
//     });
//   }
// });


app.post('/wallet/sendbtc/', async (req, res) => {
  const bitcoin = require('bitcoinjs-lib');
  const { initEccLib } = require('bitcoinjs-lib');
  const ecc = require('tiny-secp256k1');
  const ECPairFactory = require('ecpair').ECPairFactory;
  const axios = require('axios');

  initEccLib(ecc);
  const ECPair = ECPairFactory(ecc);
  const validator = (pubkey, msghash, signature) => ecc.verify(msghash, pubkey, signature);

  // Added admin_address and admin_fee in request body
  const { private_key, receiveraddress, amount, wallet_mode, admin_address, admin_fee } = req.body;

  if (!private_key || !receiveraddress || !amount || isNaN(amount) || parseFloat(amount) <= 0) {
    return res.status(400).json({ valid: false, message: 'Invalid input.' });
  }

  try {
    const network = wallet_mode === 'mainnet' ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
    const chain = wallet_mode === 'mainnet' ? 'main' : 'test3';

    const cleanedKey = private_key.trim().replace(/\s+/g, '');
    let keyPair;
    if (/^[KL5]/.test(cleanedKey)) {
      keyPair = ECPair.fromWIF(cleanedKey, network);
    } else if (/^[0-9a-fA-F]{64}$/.test(cleanedKey)) {
      const privBuf = Buffer.from(cleanedKey, 'hex');
      keyPair = ECPair.fromPrivateKey(privBuf, { network });
    } else {
      return res.status(400).json({ valid: false, message: 'Invalid private key format.' });
    }

    const { address: senderAddress } = bitcoin.payments.p2wpkh({
      pubkey: keyPair.publicKey,
      network
    });

    const { data: utxoData } = await axios.get(
      `https://api.blockcypher.com/v1/btc/${chain}/addrs/${senderAddress}?unspentOnly=true`
    );
    const utxos = utxoData.txrefs || [];
    if (utxos.length === 0) {
      return res.status(400).json({ valid: false, message: 'Insufficient balance' });
    }

    const { data: feeEstimates } = await axios.get(`https://api.blockcypher.com/v1/btc/${chain}`);
    const feeRate = Math.max(feeEstimates.low_fee_per_kb / 1000, 10); // sat/vB

    const psbt = new bitcoin.Psbt({ network });
    const amountSats = Math.floor(parseFloat(amount) * 1e8);
    const adminFeeSats = admin_fee ? Math.floor(parseFloat(admin_fee) * 1e8) : 0;
    let inputSum = 0;

    for (const utxo of utxos) {
      psbt.addInput({
        hash: utxo.tx_hash,
        index: utxo.tx_output_n,
        witnessUtxo: {
          script: bitcoin.address.toOutputScript(senderAddress, network),
          value: utxo.value
        }
      });
      inputSum += utxo.value;
    }

    const inputCount = utxos.length;
    const outputCount = adminFeeSats > 0 ? 3 : 2; // receiver + optional admin + change
    const txSize = inputCount * 68 + outputCount * 31 + 10;
    const estimatedFee = Math.ceil(txSize * feeRate);

    if (inputSum < amountSats + adminFeeSats + estimatedFee) {
      return res.status(400).json({
        valid: false,
        message: `Insufficient funds. Need ${(amountSats + adminFeeSats + estimatedFee)/1e8} BTC, have ${inputSum/1e8} BTC`
      });
    }

    const change = inputSum - amountSats - adminFeeSats - estimatedFee;

    // Add outputs
    psbt.addOutput({ address: receiveraddress, value: amountSats });
    if (adminFeeSats > 0 && admin_address) {
      psbt.addOutput({ address: admin_address, value: adminFeeSats });
    }
    if (change > 0) {
      psbt.addOutput({ address: senderAddress, value: change });
    }

    psbt.signAllInputs(keyPair);
    if (!psbt.validateSignaturesOfAllInputs(validator)) {
      return res.status(500).json({ valid: false, message: 'Invalid signature.' });
    }

    psbt.finalizeAllInputs();
    const txHex = psbt.extractTransaction().toHex();

    const { data: broadcastResult } = await axios.post(
      `https://api.blockcypher.com/v1/btc/${chain}/txs/push`,
      { tx: txHex }
    );

    return res.json({
      valid: true,
      message: 'Transaction successfully sent.',
      txId: broadcastResult.tx.hash,
      explorerUrl: `https://live.blockcypher.com/btc${wallet_mode === 'mainnet' ? '' : '-testnet'}/tx/${broadcastResult.tx.hash}/`,
      fee: estimatedFee / 1e8 + ' BTC'
    });

  } catch (error) {
    return res.status(500).json({
      valid: false,
      message: error.response?.data?.error || error.message,
      error: error.response?.data?.error || error.message,
      details: error.response?.data || error.stack
    });
  }
});

// app.post('/wallet/sendbtc/', async (req, res) => {
//   const bitcoin = require('bitcoinjs-lib');
//   const { initEccLib } = require('bitcoinjs-lib');
//   const ecc = require('tiny-secp256k1');
//   const ECPairFactory = require('ecpair').ECPairFactory;
//   const axios = require('axios');

//   initEccLib(ecc);
//   const ECPair = ECPairFactory(ecc);
//   const validator = (pubkey, msghash, signature) => ecc.verify(msghash, pubkey, signature);

//   const { private_key, receiveraddress, amount, wallet_mode } = req.body;

//   // Input validation
//   if (!private_key || !receiveraddress || !amount || isNaN(amount) || parseFloat(amount) <= 0) {
//     return res.status(400).json({ valid: false, message: 'Invalid input.' });
//   }

//   try {
//     const network = wallet_mode === 'mainnet' ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;
//     const chain = wallet_mode === 'mainnet' ? 'main' : 'test3';

//     // Clean private key
//     const cleanedKey = private_key.trim().replace(/\s+/g, '');
//     let keyPair;

//     // Detect key format
//     if (/^[KL5]/.test(cleanedKey)) {
//       keyPair = ECPair.fromWIF(cleanedKey, network);
//     } else if (/^[0-9a-fA-F]{64}$/.test(cleanedKey)) {
//       const privBuf = Buffer.from(cleanedKey, 'hex');
//       keyPair = ECPair.fromPrivateKey(privBuf, { network });
//     } else {
//       return res.status(400).json({ valid: false, message: 'Invalid private key format.' });
//     }

//     // Derive sender address (P2WPKH)
//     const { address: senderAddress } = bitcoin.payments.p2wpkh({
//       pubkey: keyPair.publicKey,
//       network
//     });

//     // Get UTXOs
//     const { data: utxoData } = await axios.get(
//       `https://api.blockcypher.com/v1/btc/${chain}/addrs/${senderAddress}?unspentOnly=true`
//     );

//     const utxos = utxoData.txrefs || [];
//     if (utxos.length === 0) {
//       return res.status(400).json({ valid: false, message: 'Insufficient balance' });
//     }

//     // Get fee estimate
//     const { data: feeEstimates } = await axios.get(`https://api.blockcypher.com/v1/btc/${chain}`);
//     const feeRate = Math.max(feeEstimates.low_fee_per_kb / 1000, 10); // sat/vB

//     const psbt = new bitcoin.Psbt({ network });
//     const amountSats = Math.floor(parseFloat(amount) * 1e8);
//     let inputSum = 0;

//     // Add UTXOs as inputs
//     for (const utxo of utxos) {
//       psbt.addInput({
//         hash: utxo.tx_hash,
//         index: utxo.tx_output_n,
//         witnessUtxo: {
//           script: bitcoin.address.toOutputScript(senderAddress, network),
//           value: utxo.value
//         }
//       });
//       inputSum += utxo.value;
//     }

//     const inputCount = utxos.length;
//     const outputCount = 2; 
//     const txSize = inputCount * 68 + outputCount * 31 + 10;
//     const estimatedFee = Math.ceil(txSize * feeRate); // in satoshis

//     if (inputSum < amountSats + estimatedFee) {
//       return res.status(400).json({
//         valid: false,
//         message: `Insufficient funds. Need ${(amountSats + estimatedFee) / 1e8} BTC, have ${inputSum / 1e8} BTC`
//       });
//     }

//     const change = inputSum - amountSats - estimatedFee;

//     // Add outputs
//     psbt.addOutput({ address: receiveraddress, value: amountSats });
//     if (change > 0) {
//       psbt.addOutput({ address: senderAddress, value: change });
//     }

//     // Sign
//     psbt.signAllInputs(keyPair);
//     if (!psbt.validateSignaturesOfAllInputs(validator)) {
//       return res.status(500).json({ valid: false, message: 'Invalid signature.' });
//     }

//     psbt.finalizeAllInputs();
//     const txHex = psbt.extractTransaction().toHex();

//     // Broadcast
//     const { data: broadcastResult } = await axios.post(
//       `https://api.blockcypher.com/v1/btc/${chain}/txs/push`,
//       { tx: txHex }
//     );

//     return res.json({
//       valid: true,
//       message: 'Transaction  successfully.',
//       txId: broadcastResult.tx.hash,
//       explorerUrl: `https://live.blockcypher.com/btc${wallet_mode === 'mainnet' ? '' : '-testnet'}/tx/${broadcastResult.tx.hash}/`,
//       fee: estimatedFee / 1e8 + ' BTC'
//     });

//   } catch (error) {
//     return res.status(500).json({
//       valid: false,
//       message: error.response.data.error,
//       error: error.response?.data?.error || error.message,
//       details: error.response?.data || error.stack
//     });
//   }
// });



app.post('/wallet/sendsol/', async (req, res) => {
  const {
  LAMPORTS_PER_SOL,
  SystemProgram,
  Transaction,
  sendAndConfirmTransaction,
  Keypair,
  Connection,
  PublicKey,
} = require("@solana/web3.js");
const bs58 = require("bs58");

    let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode,  amount } = req.body;

    // Input validation
    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
    }

    if (receiveraddress.length === 0) {
        return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
    }

    /*if (!amount || isNaN(amount)) {
        return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
    }*/
    
    


    // Process private key (if it's an array, join it)
    if (Array.isArray(private_key)) {
        private_key = private_key.join(' ');
    }

    try {
        
        const secretKeyBase58 =private_key;
        const recipientsCsv = receiveraddress;
        const amountsCsv = amount;
        const recipients = recipientsCsv.split(",").map((s) => s.trim());
        const amounts = amountsCsv.split(",").map((s) => parseFloat(s.trim()));

        /*if(recipients.length === 0) throw new Error("No recipient addresses provided");
        if (recipients.length !== amounts.length) throw new Error("Recipients and amounts count mismatch");*/

        for(const amt of amounts) 
        {
            if (isNaN(amt) || amt <= 0) 
            {
                return res.status(400).json({ valid: false, message: 'invalid Amount provided.' });
            }
        }

        const secretKeyArray = bs58.decode(secretKeyBase58);
        if(secretKeyArray.length !== 64) {

        return res.status(400).json({ valid: false, message: "Secret key must be 64 bytes" });
        }

        const sender = Keypair.fromSecretKey(secretKeyArray);
    
        // const connection = new Connection("https://api.devnet.solana.com", "confirmed");
         const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");

        const preBalanceSender = await connection.getBalance(sender.publicKey);

        const transaction = new Transaction();

        // Add one transfer instruction per recipient
        for (let i = 0; i < recipients.length; i++) {
          const recipientPubkey = new PublicKey(recipients[i]);
          const lamports = amounts[i] * LAMPORTS_PER_SOL;
          transaction.add(
            SystemProgram.transfer({
              fromPubkey: sender.publicKey,
              toPubkey: recipientPubkey,
              lamports,
            })
          );
        }

    // Send and confirm the transaction
        const signature = await sendAndConfirmTransaction(connection, transaction, [sender]);

    const postBalanceSender = await connection.getBalance(sender.publicKey);
        
        
        return res.json({ 
            valid: true, 
            message: 'Transaction successful',
            txId: signature
       
        });
        
    } catch (error) {
      // console.error('Transaction error:', error);
        return res.status(500).json({ 
            valid: false, 
            message: error,
            error: error
        });
    }
});


// app.post('/wallet/sendsoltoken/', async (req, res) => {
//   const {
//     LAMPORTS_PER_SOL,
//     SystemProgram,
//     Transaction,
//     sendAndConfirmTransaction,
//     Keypair,
//     Connection,
//     PublicKey,
//   } = require("@solana/web3.js");

//   const {
//     getOrCreateAssociatedTokenAccount,
//     createTransferInstruction,
//     getMint,
//   } = require("@solana/spl-token");

//   const bs58 = require("bs58");

//   let { private_key, receiveraddress, tokenaddress, amount, admin_address, admin_fee } = req.body;

//   // Input validation
//   if (!private_key) {
//     return res.status(400).json({ valid: false, message: 'The private key is required.' });
//   }

//   if (!receiveraddress) {
//     return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
//   }

//   if (!amount || isNaN(amount)) {
//     return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
//   }

//   try {
//     const tokenMint = new PublicKey(tokenaddress);
//     const tokenRecipient = new PublicKey(receiveraddress);
//     const solRecipient = new PublicKey(admin_address);

//     const tokenAmount = parseFloat(amount);
//     const solAmount = parseFloat(admin_fee);

//     // Connection to Solana Mainnet
//     const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
//     const secretKey = bs58.decode(private_key);
//     const sender = Keypair.fromSecretKey(secretKey);

//     // Create transaction
//     const transaction = new Transaction();

//     // SPL Token accounts
//     const senderTokenAccount = await getOrCreateAssociatedTokenAccount(
//       connection,
//       sender,
//       tokenMint,
//       sender.publicKey
//     );

//     const recipientTokenAccount = await getOrCreateAssociatedTokenAccount(
//       connection,
//       sender,
//       tokenMint,
//       tokenRecipient
//     );

//     // ✅ Get token decimals (important for USDT/USDC)
//     const mintInfo = await getMint(connection, tokenMint);
//     const decimals = mintInfo.decimals;

//     // ✅ Convert amount to smallest unit
//     const tokenAmountInSmallestUnit = BigInt(Math.floor(tokenAmount * 10 ** decimals));

//     // Add SPL Token transfer
//     transaction.add(
//       createTransferInstruction(
//         senderTokenAccount.address,
//         recipientTokenAccount.address,
//         sender.publicKey,
//         tokenAmountInSmallestUnit
//       )
//     );

//     // Add SOL admin fee transfer
//     transaction.add(
//       SystemProgram.transfer({
//         fromPubkey: sender.publicKey,
//         toPubkey: solRecipient,
//         lamports: Math.floor(solAmount * LAMPORTS_PER_SOL),
//       })
//     );

//     // Send transaction
//     const txHash = await sendAndConfirmTransaction(connection, transaction, [sender]);

//     return res.json({
//       valid: true,
//       message: 'Transaction successful',
//       txId: txHash
//     });

//   } catch (error) {
//     return res.status(500).json({
//       valid: false,
//       message: error.message,
//     });
//   }
// });




app.post('/wallet/sendsoltoken/', async (req, res) => {
  const {
    LAMPORTS_PER_SOL,
    SystemProgram,
    Transaction,
    sendAndConfirmTransaction,
    Keypair,
    Connection,
    PublicKey,
  } = require("@solana/web3.js");

  const {
    getAssociatedTokenAddress,
    createAssociatedTokenAccountInstruction,
    createTransferInstruction,
    getMint,
  } = require("@solana/spl-token");

  const bs58 = require("bs58");

  let { private_key, receiveraddress, tokenaddress, amount, admin_address, admin_fee } = req.body;

  // Input validation
  if (!private_key) {
    return res.status(400).json({ valid: false, message: 'The private key is required.' });
  }
  if (!receiveraddress) {
    return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
  }
  if (!amount || isNaN(amount)) {
    return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
  }

  try {
    const tokenMint = new PublicKey(tokenaddress);
    const tokenRecipient = new PublicKey(receiveraddress);
    const solRecipient = new PublicKey(admin_address);

    const tokenAmount = parseFloat(amount);
    const solAmount = parseFloat(admin_fee);

    // Connect to Solana mainnet
    const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
    const secretKey = bs58.decode(private_key);
    const sender = Keypair.fromSecretKey(secretKey);

    // ✅ Step 1: Get sender’s ATA (must exist)
    const senderATA = await getAssociatedTokenAddress(tokenMint, sender.publicKey);

    // ✅ Step 2: Get recipient’s ATA
    const recipientATA = await getAssociatedTokenAddress(tokenMint, tokenRecipient);

    // ✅ Step 3: Build a single transaction
    const transaction = new Transaction();

    // If recipient ATA does not exist, add an instruction to create it
    const ataInfo = await connection.getAccountInfo(recipientATA);
    if (!ataInfo) {
      transaction.add(
        createAssociatedTokenAccountInstruction(
          sender.publicKey,   // payer of account creation
          recipientATA,       // ATA address
          tokenRecipient,     // owner of ATA
          tokenMint           // token mint
        )
      );
    }

    // ✅ Step 4: Convert token amount using decimals
    const mintInfo = await getMint(connection, tokenMint);
    const decimals = mintInfo.decimals;
    const tokenAmountInSmallestUnit = BigInt(Math.floor(tokenAmount * 10 ** decimals));

    // Add token transfer
    transaction.add(
      createTransferInstruction(
        senderATA,
        recipientATA,
        sender.publicKey,
        tokenAmountInSmallestUnit
      )
    );

    // Add SOL fee transfer if applicable
    if (solAmount > 0) {
      transaction.add(
        SystemProgram.transfer({
          fromPubkey: sender.publicKey,
          toPubkey: solRecipient,
          lamports: Math.floor(solAmount * LAMPORTS_PER_SOL),
        })
      );
    }

    // ✅ Step 5: Send once
    const txHash = await sendAndConfirmTransaction(connection, transaction, [sender]);

    return res.json({
      valid: true,
      message: 'Transaction successful',
      txId: txHash,
    });

  } catch (error) {
    return res.status(500).json({
      valid: false,
      message: error.message,
    });
  }
});



// app.post('/wallet/sendsoltoken/', async (req, res) => {
//   const {
//   LAMPORTS_PER_SOL,
//   SystemProgram,
//   Transaction,
//   sendAndConfirmTransaction,
//   Keypair,
//   Connection,
//   PublicKey,
// } = require("@solana/web3.js");

// const {
//   getOrCreateAssociatedTokenAccount,
//   createTransferInstruction,
// } = require("@solana/spl-token");

// const bs58 = require("bs58");

//     let { private_key, receiveraddress, tokenaddress, secret_key, wallet_mode,  amount ,admin_address, admin_fee } = req.body;

//     // Input validation
//     if (!private_key) {
//         return res.status(400).json({ valid: false, message: 'The privatekey is required.' });
//     }

//     if (receiveraddress.length === 0) {
//         return res.status(400).json({ valid: false, message: 'The receiver address is required.' });
//     }

//     /*if (!amount || isNaN(amount)) {
//         return res.status(400).json({ valid: false, message: 'A valid amount is required.' });
//     }*/
    
    


//     // Process private key (if it's an array, join it)
//     if (Array.isArray(private_key)) {
//         private_key = private_key.join(' ');
//     }

//     try {
        
//         const tokenMint = new PublicKey(tokenaddress);
//     const tokenRecipient = new PublicKey(receiveraddress);
//     const solRecipient = new PublicKey(admin_address);

//     const tokenAmount = parseFloat(amount);
//     const solAmount = parseFloat(admin_fee);


//     /*const connection = new Connection("https://api.devnet.solana.com", "confirmed");*/
//     const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
//     const secretKey = bs58.decode(private_key);
//     const sender = Keypair.fromSecretKey(secretKey);

//     const transaction = new Transaction();

//     // SPL Token Transfer
//     const senderTokenAccount = await getOrCreateAssociatedTokenAccount(
//       connection,
//       sender,
//       tokenMint,
//       sender.publicKey
//     );

//     const recipientTokenAccount = await getOrCreateAssociatedTokenAccount(
//       connection,
//       sender,
//       tokenMint,
//       tokenRecipient
//     );

//     transaction.add(
//       createTransferInstruction(
//         senderTokenAccount.address,
//         recipientTokenAccount.address,
//         sender.publicKey,
//         tokenAmount * LAMPORTS_PER_SOL // adjust decimals as needed
//       )
//     );

//     // SOL Transfer
//     transaction.add(
//       SystemProgram.transfer({
//         fromPubkey: sender.publicKey,
//         toPubkey: solRecipient,
//         lamports: solAmount * LAMPORTS_PER_SOL,
//       })
//     );

//     const txHash = await sendAndConfirmTransaction(connection, transaction, [sender]);
        
        
//         return res.json({ 
//             valid: true, 
//             message: 'Transaction successful',
//             txId: txHash
       
//         });
        
//     } catch (error) {
//       // console.error('Transaction error:', error);
//         return res.status(500).json({ 
//             valid: false, 
//             message: error.message,
         
//         });
//     }
// });

app.post('/wallet/hd_create/', (req, res) => {
    
    
    let { networks } = req.body;
    

    
    if (!Array.isArray(networks)) {
        return res.status(400).json({ valid: false, message: "Networks Must be array formats" });
    }

    
    const bip39 = require('bip39');
    
    const mnemonic = bip39.generateMnemonic();
    
    
    //const mnemonic='barrel later right snack brief village talk clutch pear used jealous index';
    const handleNetwork = (mnemonic, network) => {
        
         let address = '';
        let private_key = '';
        if(network=='1')
        {
            const bitcoin = require("bitcoinjs-lib");
            const HDKey = require("hdkey");
            const CoinKey = require("coinkey");
            const network = bitcoin.networks.bitcoin;
            
             const seed = bip39.mnemonicToSeedSync(mnemonic);

            // Step 3: Create an HD wallet key from the seed
            const hdKey = HDKey.fromMasterSeed(Buffer.from(seed, "hex"));
        
            // Step 4: Define the BIP44 path for Bitcoin (m/44'/0'/0'/0/0)
            const path = "m/44'/0'/0'/0/0";
        
            // Step 5: Derive a child key from the HD key using the defined path
            const child = hdKey.derive(path);
        
            // Step 6: Create a CoinKey from the derived child private key and specify the Bitcoin network
            const coinKey = new CoinKey(child.privateKey, bitcoin.networks.bitcoin);
        
            // Step 7: Generate the P2WPKH (SegWit) address using the public key
            const { address: p2wpkhAddress } = bitcoin.payments.p2wpkh({
              pubkey: coinKey.publicKey,
              network: network,
            });
            
            address =p2wpkhAddress; 
            private_key=coinKey.privateWif;
        }
        else if(network=='2' || network=='3' || network=='6')
        {
            const ethers = require('ethers');
            
            const mnemonicWallet = ethers.Wallet.fromPhrase(mnemonic);
    
            address =mnemonicWallet.address;
            private_key=mnemonicWallet.privateKey;
        }
        else if(network=='4')
        {
              const TronWeb = require('tronweb');
              const tronWeb = new TronWeb({
                    fullHost: 'https://api.trongrid.io'  // You can use other nodes as well
                });
                
             const account = tronWeb.fromMnemonic(mnemonic);
              address =account.address;
             private_key=account.privateKey;
        }
        else if(network=='5')
        {
            
            /*const solanaWeb3 = require('@solana/web3.js');
            const bs58 = require('bs58'); // Correct import for bs58
            const { Keypair } = solanaWeb3;
            const seeds = bip39.mnemonicToSeedSync(mnemonic);
        
            // Step 3: Create a Solana keypair using the seed (first 32 bytes)
            const keypair = Keypair.fromSeed(seeds.slice(0, 32)); // Solana keypair is 32 bytes
        
            // Step 4: Get the private key and public key
            const privateKey = keypair.secretKey;
            const publicKey = keypair.publicKey.toBase58();

                // Convert the private key to Base58 format
             const privateKeyBase58 = bs58.default.encode(privateKey);
             
             address =publicKey;
             private_key=privateKeyBase58;*/
             
             
             const { Keypair } = require('@solana/web3.js');
            const bip39 = require('bip39');
            const { derivePath } = require('ed25519-hd-key');  // For Solana path
            const bs58 = require('bs58');
            
             const seed = bip39.mnemonicToSeedSync(mnemonic);
            
            
             const path = `m/44'/501'/0'/0'`; 
             const derived = derivePath(path, seed.toString('hex'));
             const privateKey = Buffer.from(derived.key);
              // Create a Solana keypair from the derived private key
             const keypair = Keypair.fromSeed(privateKey);
             //const privateKeyBase58 = keypair.secretKey.toString('base58');
             const privateKeyBase58 = bs58.encode(keypair.secretKey);
        
         //res.json({ valid: true, message: keypair.publicKey.toBase58(), privatekey:privateKeyBase58 });
         
         address =keypair.publicKey.toBase58();
        private_key=privateKeyBase58;
            
        }
        
        const walletInfo = {
              network: network, 
              mnemonic:mnemonic,
              address:address,
              private_key:private_key
              
            };
        
        // Logic for other networks (3, 4, 5)
        return walletInfo;
    };

    
    let result = [];
    networks.forEach(network => {
            result.push(handleNetwork(mnemonic,network));
        
    });

    // Respond with the generated results for each network mode
    res.json({ valid: true, message: result });
    
});


app.post('/wallet/eth_balance/', async (req, res) => {
    // let { private_key, network, tokenAddress, timezone } = req.body;
     let { private_key, network, tokenAddress, timezone, apikey } = req.body;

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The address is required.' });
    }
    
    const axios = require('axios');
    const { Web3 } = require('web3');
    
    // let COVALENT_API_KEY = 'cqt_rQ4Xy6QBdYB6Y7bk6JwwHj9pj3qw';
    let COVALENT_API_KEY = apikey;
    let chainId;
    let chainName;
    let web3;
    
    // Network configuration for Covalent API
    if (network === '2') {
        // Ethereum Mainnet
        chainId = '1';
        chainName = 'eth-mainnet';
        web3 = new Web3('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd');
    } else if (network === '3') {
        // Binance Smart Chain (BSC)
        chainId = '56';
        chainName = 'bsc-mainnet';
        web3 = new Web3('https://bsc-dataseed.binance.org/');
    } else if (network === '6') {
        // Polygon Network (Matic)
        chainId = '137';
        chainName = 'matic-mainnet';
        web3 = new Web3('https://polygon-rpc.com/');
    } else {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }
    
    timezone = timezone || 'UTC';
    const ADDRESS = private_key.toLowerCase();

    const formatTransactionTime = (timestamp, tz) => {
        try {
            const date = new Date(timestamp);
        
            // Use Intl.DateTimeFormat for timezone conversion
            const formatter = new Intl.DateTimeFormat('en-US', {
                timeZone: tz,
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: true
            });
            
            // Format the date and split into parts
            const formatted = formatter.format(date);
            
            // Convert from MM/DD/YYYY to YYYY-MM-DD format
            const [datePart, timePart] = formatted.split(', ');
            const [month, day, year] = datePart.split('/');
            
            return `${day}-${month}-${year} ${timePart}`;
            
        } catch (e) {
            return 'Invalid Date';
        }
    };

    // Fetch transactions from Covalent API
    const getTransactions = async (address) => {
        const url = `https://api.covalenthq.com/v1/${chainId}/address/${address}/transactions_v2/?key=${COVALENT_API_KEY}`;
        
        try {
            const response = await axios.get(url);
            if (response.data.data && response.data.data.items) {
                return response.data.data.items.slice(0, 20); // Last 20 transactions
            }
            return [];
        } catch (error) {
            console.error('Error fetching transactions from Covalent:', error);
            return [];
        }
    };

    // Categorize and format transactions from Covalent response
    // const categorizeTransactions = (transactions, address) => {
    //     const allTransactions = transactions.map(tx => {
    //         // Skip transactions with empty to/from addresses
    //         if (!tx.to_address || !tx.from_address) return null;
            
    //         const isIncoming = tx.to_address.toLowerCase() === address;
    //         const isOutgoing = tx.from_address.toLowerCase() === address;
            
    //         // Convert value from wei to ether
    //         const valueInWei = tx.value || '0';
    //         const valueInEth = web3.utils.fromWei(valueInWei, 'ether');
            
    //         // Convert gas price from wei to gwei
    //         const gasPriceInGwei = web3.utils.fromWei(tx.gas_price || '0', 'gwei');
            
    //         return {
    //             hash: tx.tx_hash,
    //             from: tx.from_address 
    //                 ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-15) 
    //                 : 'Unknown',
    //             to: tx.to_address 
    //                 ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-15) 
    //                 : 'Unknown',
    //             time_display: new Date(tx.block_signed_at).getTime() / 1000, // Unix timestamp
    //             time: formatTransactionTime(tx.block_signed_at, timezone),
    //             value: valueInEth,
    //             type: isIncoming ? 'in' : (isOutgoing ? 'out' : 'unknown'),
    //             gasUsed: tx.gas_spent || 0,
    //             gasPrice: gasPriceInGwei + ' Gwei',
    //             blockNumber: tx.block_height,
    //             confirmations: tx.confirmations || 0,
    //             successful: tx.successful,
    //             value_quote: tx.value_quote || 0,
    //             pretty_value_quote: tx.pretty_value_quote || '$0.00'
    //         };
    //     }).filter(tx => tx !== null); // Remove skipped transactions

    //     const incomingTransactions = allTransactions.filter(tx => tx.type === 'in');
    //     const outgoingTransactions = allTransactions.filter(tx => tx.type === 'out');

    //     return {
    //         all: allTransactions,
    //         incoming: incomingTransactions,
    //         outgoing: outgoingTransactions,
    //     };
    // };
    const categorizeTransactions = (transactions, address) => {
    const allTransactions = transactions.map(tx => {
        if (!tx.to_address || !tx.from_address) return null;

        const checkAddress = address.toLowerCase();
        const fromAddr = tx.from_address.toLowerCase();
        const toAddr = tx.to_address.toLowerCase();

        // Determine transaction type
        const isIncoming = toAddr === checkAddress;
        const isOutgoing = fromAddr === checkAddress;

        // Display addresses (show short version)
        const displayFrom = tx.from_address
            ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-10)
            : 'Unknown';
        const displayTo = tx.to_address
            ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-10)
            : 'Unknown';

        return {
            hash: tx.tx_hash,
            from: displayFrom,
            to: displayTo,
            time_display: new Date(tx.block_signed_at).getTime() / 1000,
            time: formatTransactionTime(tx.block_signed_at, timezone),
            value: web3.utils.fromWei(tx.value || '0', 'ether'),
            type: isIncoming ? 'in' : (isOutgoing ? 'out' : 'unknown'),
            gasUsed: tx.gas_spent || 0,
            gasPrice: web3.utils.fromWei(tx.gas_price || '0', 'gwei') + ' Gwei',
            blockNumber: tx.block_height,
            confirmations: tx.confirmations || 0,
            successful: tx.successful !== undefined ? tx.successful : true,
            value_quote: tx.value_quote || 0,
            pretty_value_quote: tx.pretty_value_quote || '$0.00'
        };
    }).filter(tx => tx !== null);

    return {
        all: allTransactions,
        incoming: allTransactions.filter(tx => tx.type === 'in'),
        outgoing: allTransactions.filter(tx => tx.type === 'out')
    };
};


    try {
        const transactions = await getTransactions(ADDRESS);
        const categorizedTransactions = categorizeTransactions(transactions, ADDRESS);

        res.json({
            valid: true,
            message: {
                address: ADDRESS,
                network: chainName,
                chain_id: parseInt(chainId),
                url: `https://api.covalenthq.com/v1/${chainId}/address/${ADDRESS}/transactions_v2/`,
                transactions: {
                    all: categorizedTransactions.all,
                    incoming: categorizedTransactions.incoming,
                    outgoing: categorizedTransactions.outgoing,
                    count: {
                        all: categorizedTransactions.all.length,
                        incoming: categorizedTransactions.incoming.length,
                        outgoing: categorizedTransactions.outgoing.length
                    }
                }
            }
        });
    } catch (error) {
        console.error('Error:', error);
        res.status(500).json({ 
            valid: false, 
            message: 'Error fetching transactions:',
            error: error.message 
        });
    }
});

app.post('/wallet/pol_balance/', async (req, res) => {
    let { private_key, network, tokenAddress , timezone } = req.body;

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The address is required.' });
    }
    
    const axios = require('axios');
    const { Web3 } = require('web3');
    
    let ETHERSCAN_API_KEY;
    let web3;
    let baseUrl;
    let chainName;
    let url;
    // Network configuration
    if (network === '2') {
        // Ethereum Mainnet
        //ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        //baseUrl = 'https://api.etherscan.io/api';
         ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
         baseUrl = 'https://api.etherscan.io/v2/api?chainid=1',
         web3 = new Web3('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd');
        chainName = 'ethereum';
    } else if (network === '3') {
        // Binance Smart Chain (BSC)
        //ETHERSCAN_API_KEY = 'GIZWMXXDJG1TCNE824K3EQ3WXNHK979SMP';
         ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        //baseUrl = 'https://api.bscscan.com/api';
         baseUrl = 'https://api.etherscan.io/v2/api?chainid=56',
        chainName = 'binancecoin';
        web3 = new Web3('https://bsc-dataseed.binance.org/');
    } else if (network === '6') {
        // Polygon Network (Matic)
        //ETHERSCAN_API_KEY = 'NT2HBAZM5Z53S4VBX2XXR5V9XHBMK1EPVZ';
        //baseUrl = 'https://api.polygonscan.com/api';
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/v2/api?chainid=137',
        chainName = 'polygon-ecosystem-token';
        web3 = new Web3('https://polygon-rpc.com/');
    } else {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }
      timezone = timezone || 'UTC';
    const ADDRESS = private_key.toLowerCase();

    const formatTransactionTime = (timestamp, tz) => {
        try {
            const date = new Date(timestamp * 1000);
        
        // Use Intl.DateTimeFormat for timezone conversion
        const formatter = new Intl.DateTimeFormat('en-US', {
            timeZone: tz,
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
            hour12: true
        });
        
        // Format the date and split into parts
        const formatted = formatter.format(date);
        
        // Convert from MM/DD/YYYY to YYYY-MM-DD format
        const [datePart, timePart] = formatted.split(', ');
        const [month, day, year] = datePart.split('/');
        
        return `${day}-${month}-${year} ${timePart}`;
            
        } catch (e) {
            return 'Invalid Date';
        }
    };


    // Fetch transactions from blockchain explorer
    const getTransactions = async (address) => {
        /*url = `${baseUrl}?module=account&action=txlist&address=${address}&sort=desc&apikey=${ETHERSCAN_API_KEY}`;*/
        url = `${baseUrl}&module=account&action=txlist&address=${address}&sort=desc&apikey=${ETHERSCAN_API_KEY}`;
        try {
            const response = await axios.get(url);
            return response.data.result.slice(0, 20); // Last 20 transactions
        } catch (error) {
            console.error('Error fetching transactions:', error);
            return [];
        }
    };

    // Categorize and format transactions
    const categorizeTransactions = (transactions, address) => {
        const allTransactions = transactions.map(tx => {
            // Skip transactions with empty to/from addresses
            if (!tx.to || !tx.from) return null;
            
            const isIncoming = tx.to.toLowerCase() === address;
            const isOutgoing = tx.from.toLowerCase() === address;
            
            return {
                hash: tx.hash,
                // from: tx.from || 'Unknown',
                // to: tx.to || 'Unknown',
                 from: tx.from 
                    ? tx.from.slice(0, 13) + '...' + tx.from.slice(-15) 
                    : 'Unknown',
                to: tx.to 
                    ? tx.to.slice(0, 13) + '...' + tx.to.slice(-15) 
                    : 'Unknown',
                time_display: tx.timeStamp, // Original timestamp
                // time: formatTransactionTime(tx.timeStamp), // Formatted time
                time: formatTransactionTime(tx.timeStamp, timezone),
                value: web3.utils.fromWei(tx.value, 'ether'),
                type: isIncoming ? 'in' : (isOutgoing ? 'out' : 'unknown'),
                gasUsed: tx.gasUsed,
                gasPrice: web3.utils.fromWei(tx.gasPrice, 'gwei') + ' Gwei',
                blockNumber: tx.blockNumber,
                confirmations: tx.confirmations || 0
            };
        }).filter(tx => tx !== null); // Remove skipped transactions

        const incomingTransactions = allTransactions.filter(tx => tx.type === 'in');
        const outgoingTransactions = allTransactions.filter(tx => tx.type === 'out');

        return {
            all: allTransactions,
            incoming: incomingTransactions,
            outgoing: outgoingTransactions,
           
        };
    };

    try {
        const transactions = await getTransactions(ADDRESS);
        const categorizedTransactions = categorizeTransactions(transactions, ADDRESS);

        res.json({
            valid: true,
            message: {
                address: ADDRESS,
                network: chainName,
                url:url,
                transactions: {
                    all: categorizedTransactions.all,
                    incoming: categorizedTransactions.incoming,
                    outgoing: categorizedTransactions.outgoing,
                    count: {
                        all: categorizedTransactions.all.length,
                        incoming: categorizedTransactions.incoming.length,
                        outgoing: categorizedTransactions.outgoing.length
                    }
                }
            }
        });
    } catch (error) {
        console.error('Error:', error);
        res.status(500).json({ 
            valid: false, 
            message: 'Error fetching transactions:',
            error: error.message 
        });
    }
});

app.post('/wallet/eth_token/', async (req, res) => {
    let { private_key, network, tokenAddress, timezone, apikey } = req.body;

    if (!private_key || !tokenAddress) {
        return res.status(400).json({ valid: false, message: 'Both address and token address are required.' });
    }

    const axios = require('axios');
    const { Web3 } = require('web3');
    const BN = require('bn.js');

    // === Network Configuration ===
    const networks = {
        '2': { // Ethereum Mainnet
            rpcUrl: 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd',
            chainName: 'ethereum',
            chainId: 1
        },
        '3': { // Binance Smart Chain
            rpcUrl: 'https://bsc-dataseed.binance.org/',
            chainName: 'binancecoin',
            chainId: 56
        },
        '6': { // Polygon
            rpcUrl: 'https://polygon-rpc.com/',
            chainName: 'polygon-ecosystem-token',
            chainId: 137
        }
    };

    const networkConfig = networks[network];
    if (!networkConfig) {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }

    const { rpcUrl, chainName, chainId } = networkConfig;
    const web3 = new Web3(rpcUrl);
    const ADDRESS = private_key.toLowerCase();
    const TOKEN_ADDRESS = tokenAddress.toLowerCase();
    timezone = timezone || 'UTC';

    // === ERC-20 ABI ===
    const ERC20_ABI = [
        {
            "constant": true,
            "inputs": [{ "name": "account", "type": "address" }],
            "name": "balanceOf",
            "outputs": [{ "name": "", "type": "uint256" }],
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "decimals",
            "outputs": [{ "name": "", "type": "uint8" }],
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "symbol",
            "outputs": [{ "name": "", "type": "string" }],
            "type": "function"
        }
    ];

    // === Helper Functions ===
    const formatTransactionTime = (timestamp, tz) => {
        try {
            const date = new Date(timestamp * 1000);
            const formatter = new Intl.DateTimeFormat('en-US', {
                timeZone: tz,
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: true
            });

            const formatted = formatter.format(date);
            const [datePart, timePart] = formatted.split(', ');
            const [month, day, year] = datePart.split('/');

            return `${day}-${month}-${year} ${timePart}`;
        } catch (e) {
            return 'Invalid Date';
        }
    };

    const formatBalance = (rawBalance, decimals) => {
        try {
            const balance = new BN(rawBalance);
            const divisor = new BN(10).pow(new BN(decimals));
            const whole = balance.div(divisor);
            const fractional = balance.mod(divisor);

            const displayDecimals = Math.min(decimals, 8);
            let fractionalStr = fractional.toString(10).padStart(decimals, '0');
            fractionalStr = fractionalStr.substring(0, displayDecimals);

            let result = `${whole.toString(10)}.${fractionalStr}`;
            return result.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '');
        } catch (error) {
            console.error('Error formatting balance:', error);
            return '0';
        }
    };

    const getTokenData = async () => {
        const tokenContract = new web3.eth.Contract(ERC20_ABI, TOKEN_ADDRESS);
        try {
            const [balance, decimals, symbol] = await Promise.all([
                tokenContract.methods.balanceOf(ADDRESS).call(),
                tokenContract.methods.decimals().call(),
                tokenContract.methods.symbol().call()
            ]);

            return {
                rawBalance: balance.toString(),
                decimals: parseInt(decimals),
                symbol: symbol,
                formattedBalance: formatBalance(balance, decimals)
            };
        } catch (error) {
            console.error('Error fetching token data:', error);
            return {
                rawBalance: '0',
                decimals: 18,
                symbol: 'UNKNOWN',
                formattedBalance: '0'
            };
        }
    };

    // === 🔹 Updated: Covalent API for Token Transactions ===
    const getTokenTransactions = async () => {
        try {
            const chainMap = {
                1: 'eth-mainnet',
                56: 'bsc-mainnet',
                137: 'matic-mainnet'
            };

            const covalentChain = chainMap[chainId] || 'eth-mainnet';
            const covalentKey = apikey;
            // const covalentKey = 'cqt_rQ4Xy6QBdYB6Y7bk6JwwHj9pj3qw'; // 🔹 Replace with your Covalent API key

            const url = `https://api.covalenthq.com/v1/${covalentChain}/address/${ADDRESS}/transfers_v2/?contract-address=${TOKEN_ADDRESS}&page-size=20&key=${covalentKey}`;
            const response = await axios.get(url);

            if (!response.data?.data?.items) return [];

            const transactions = [];

           for (const item of response.data.data.items) {
    for (const tx of item.transfers) {
        if (tx.contract_address?.toLowerCase() === TOKEN_ADDRESS.toLowerCase()) {
            const fromAddr = tx.from_address?.toLowerCase() || '';
            const toAddr = tx.to_address?.toLowerCase() || '';
            const isIncoming = toAddr === ADDRESS.toLowerCase();

            transactions.push({
                hash: item.tx_hash,
                from: isIncoming
                    ? tx.from_address
                        ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-10)
                        : 'Unknown'
                    : tx.to_address
                        ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-10)
                        : 'Unknown',
                to: isIncoming
                    ? tx.to_address
                        ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-10)
                        : 'Unknown'
                    : tx.from_address
                        ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-10)
                        : 'Unknown',
                time: formatTransactionTime(
                    item.block_signed_at
                        ? Math.floor(new Date(item.block_signed_at).getTime() / 1000)
                        : 0,
                    timezone
                ),
                value: formatBalance(tx.delta, tx.contract_decimals || 18),
                symbol: tx.contract_ticker_symbol || '',
                type: isIncoming ? 'in' : 'out'
            });
        }
    }
}


            return transactions.slice(0, 20);
        } catch (error) {
            console.error('Error fetching token transactions (Covalent):', error.message);
            return [];
        }
    };

    const getTokenPrice = async () => {
        try {
            const url = `https://api.coingecko.com/api/v3/simple/token_price/${chainName}?contract_addresses=${TOKEN_ADDRESS}&vs_currencies=usd`;
            const response = await axios.get(url);
            return response.data[TOKEN_ADDRESS]?.usd || 0;
        } catch (error) {
            console.error('Error fetching token price:', error);
            return 0;
        }
    };

    // === Main Execution ===
    try {
        const [tokenData, transactions, tokenPrice] = await Promise.all([
            getTokenData(),
            getTokenTransactions(),
            getTokenPrice()
        ]);

        const tokenImage = `https://static.cx.metamask.io/api/v1/tokenIcons/${chainId}/${TOKEN_ADDRESS}.png`;
        const balanceInUSD = (parseFloat(tokenData.formattedBalance) * tokenPrice).toFixed(2);

        res.json({
            valid: true,
            message: {
                token: {
                    address: TOKEN_ADDRESS,
                    symbol: tokenData.symbol,
                    decimals: tokenData.decimals,
                    balance: tokenData.formattedBalance,
                    balanceUSD: balanceInUSD,
                    priceUSD: tokenPrice,
                    image: tokenImage
                },
                transactions: {
                    all: transactions,
                    incoming: transactions.filter(tx => tx.type === 'in'),
                    outgoing: transactions.filter(tx => tx.type === 'out'),
                    count: transactions.length
                }
            }
        });
    } catch (error) {
        console.error('Error:', error);
        res.status(500).json({
            valid: false,
            message: 'Error fetching token information',
            error: error.message
        });
    }
});


app.post('/wallet/pol_token/', async (req, res) => {
    let { private_key, network, tokenAddress, timezone  } = req.body;

    if (!private_key || !tokenAddress) {
        return res.status(400).json({ valid: false, message: 'Both address and token address are required.' });
    }
    
    const axios = require('axios');
    const { Web3 } = require('web3');
    const BN = require('bn.js');

    // Network configuration
    const networks = {
        '2': { // Ethereum Mainnet
          // apiKey: 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI',
            apiKey: 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI',
            //baseUrl: 'https://api.etherscan.io/api',
            baseUrl: 'https://api.etherscan.io/v2/api?chainid=1',
            rpcUrl: 'https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd',
            chainName: 'ethereum',
            chainId: 1
        },
        '3': { // Binance Smart Chain
            //apiKey: 'GIZWMXXDJG1TCNE824K3EQ3WXNHK979SMP',
            //baseUrl: 'https://api.bscscan.com/api',
            apiKey: 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI',
            baseUrl: 'https://api.etherscan.io/v2/api?chainid=56',
            rpcUrl: 'https://bsc-dataseed.binance.org/',
            chainName: 'binancecoin',
            chainId: 56
        },
        '6': { // Polygon
            //apiKey: 'NT2HBAZM5Z53S4VBX2XXR5V9XHBMK1EPVZ',
            //baseUrl: 'https://api.polygonscan.com/api',
            apiKey: 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI',
            baseUrl: 'https://api.etherscan.io/v2/api?chainid=137',
            rpcUrl: 'https://polygon-rpc.com/',
            chainName: 'polygon-ecosystem-token',
            chainId: 137
        }
    };

    const networkConfig = networks[network];
    if (!networkConfig) {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }

    const { baseUrl, apiKey, rpcUrl, chainName, chainId } = networkConfig;
    const web3 = new Web3(rpcUrl);
    const ADDRESS = private_key.toLowerCase();
    const TOKEN_ADDRESS = tokenAddress.toLowerCase();

    // ERC-20 ABI (simplified)
    const ERC20_ABI = [
        {
            "constant": true,
            "inputs": [{ "name": "account", "type": "address" }],
            "name": "balanceOf",
            "outputs": [{ "name": "", "type": "uint256" }],
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "decimals",
            "outputs": [{ "name": "", "type": "uint8" }],
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "symbol",
            "outputs": [{ "name": "", "type": "string" }],
            "type": "function"
        }
    ];
        timezone = timezone || 'UTC';
    // Helper functions
    // const formatTime = (timestamp) => {
    //     const date = new Date(timestamp * 1000);
    //     return `${date.getDate().toString().padStart(2, '0')}-${
    //         (date.getMonth()+1).toString().padStart(2, '0')}-${
    //         date.getFullYear()} ${
    //         date.getHours().toString().padStart(2, '0')}:${
    //         date.getMinutes().toString().padStart(2, '0')}:${
    //         date.getSeconds().toString().padStart(2, '0')}`;
    // };
    
      const formatTransactionTime = (timestamp, tz) => {
        try {
            /*const date = new Date(timestamp * 1000);
            const options = {
                day: '2-digit',
                month: '2-digit',
                year: 'numeric',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: true,
                timeZone: tz
            };
    
            return new Intl.DateTimeFormat('en-GB', options).format(date);*/
            
            const date = new Date(timestamp * 1000);
        
        // Use Intl.DateTimeFormat for timezone conversion
        const formatter = new Intl.DateTimeFormat('en-US', {
            timeZone: tz,
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
            hour12: true
        });
        
        // Format the date and split into parts
        const formatted = formatter.format(date);
        
        // Convert from MM/DD/YYYY to YYYY-MM-DD format
        const [datePart, timePart] = formatted.split(', ');
        const [month, day, year] = datePart.split('/');
        
        return `${day}-${month}-${year} ${timePart}`;
            
        } catch (e) {
            return 'Invalid Date';
        }
    };

  
const formatBalance = (rawBalance, decimals) => {
    try {
        const balance = new BN(rawBalance);
        const divisor = new BN(10).pow(new BN(decimals));
        const whole = balance.div(divisor);
        const fractional = balance.mod(divisor);
        
        const displayDecimals = Math.min(decimals, 8);
        let fractionalStr = fractional.toString(10).padStart(decimals, '0');
        fractionalStr = fractionalStr.substring(0, displayDecimals);
        
        // Remove trailing zeros after decimal
        let result = `${whole.toString(10)}.${fractionalStr}`;
        return result.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '');
    } catch (error) {
        console.error('Error formatting balance:', error);
        return '0';
    }
};

    const getTokenData = async () => {
        const tokenContract = new web3.eth.Contract(ERC20_ABI, TOKEN_ADDRESS);
        try {
            const [balance, decimals, symbol] = await Promise.all([
                tokenContract.methods.balanceOf(ADDRESS).call(),
                tokenContract.methods.decimals().call(),
                tokenContract.methods.symbol().call()
            ]);
            
            return {
                rawBalance: balance.toString(),
                decimals: parseInt(decimals),
                symbol: symbol,
                formattedBalance: formatBalance(balance, decimals)
            };
        } catch (error) {
            console.error('Error fetching token data:', error);
            return {
                rawBalance: '0',
                decimals: 18,
                symbol: 'UNKNOWN',
                formattedBalance: '0'
            };
        }
    };

    // const getTokenTransactions = async () => {
    //     try {
    //         /*const url = `${baseUrl}?module=account&action=tokentx&contractaddress=${TOKEN_ADDRESS}&address=${ADDRESS}&sort=desc&apikey=${apiKey}`;*/
            
    //          const url = `${baseUrl}&module=account&action=tokentx&contractaddress=${TOKEN_ADDRESS}&address=${ADDRESS}&sort=desc&apikey=${apiKey}`;
    //         const response = await axios.get(url);
    //         return response.data.result.slice(0, 20).map(tx => ({
    //             hash: tx.hash,
    //             // from: tx.from,
    //             // to: tx.to,
    //              from: tx.from 
    //                 ? tx.from.slice(0, 13) + '...' + tx.from.slice(-15) 
    //                 : 'Unknown',
    //             to: tx.to 
    //                 ? tx.to.slice(0, 13) + '...' + tx.to.slice(-15) 
    //                 : 'Unknown',
    //             // time: formatTime(tx.timeStamp),
    //             time: formatTransactionTime(tx.timeStamp, timezone),
    //             value: formatBalance(tx.value, tx.tokenDecimal),
    //             symbol: tx.tokenSymbol,
    //             type: tx.to.toLowerCase() === ADDRESS ? 'in' : 'out'
    //         }));
    //     } catch (error) {
    //         console.error('Error fetching token transactions:', error);
    //         return [];
    //     }
    // };
    const getTokenTransactions = async () => {
    try {
        const url = `${baseUrl}&module=account&action=tokentx&contractaddress=${TOKEN_ADDRESS}&address=${ADDRESS}&sort=desc&apikey=${apiKey}`;
        const response = await axios.get(url);
        const allTx = response.data.result || [];

        // Filter spam / irrelevant transactions
        const filteredTx = allTx.filter(tx => {
            // Skip zero or invalid value
            if (!tx.value || tx.value === "0") return false;

            // Skip if token symbol is missing or invalid
            if (!tx.tokenSymbol || tx.tokenSymbol.trim() === "" || tx.tokenSymbol === "UNKNOWN") return false;

            // Skip suspicious contract interactions (no to/from)
            if (!tx.to || !tx.from) return false;

            // Skip self transfers
            if (tx.from.toLowerCase() === tx.to.toLowerCase()) return false;

            return true;
        });

        // Take top 20 clean transactions
        return filteredTx.slice(0, 20).map(tx => ({
            hash: tx.hash,
            from: tx.from 
                ? tx.from.slice(0, 13) + '...' + tx.from.slice(-15) 
                : 'Unknown',
            to: tx.to 
                ? tx.to.slice(0, 13) + '...' + tx.to.slice(-15) 
                : 'Unknown',
            time: formatTransactionTime(tx.timeStamp, timezone),
            value: formatBalance(tx.value, tx.tokenDecimal),
            symbol: tx.tokenSymbol,
            type: tx.to.toLowerCase() === ADDRESS ? 'in' : 'out'
        }));
    } catch (error) {
        console.error('Error fetching token transactions:', error);
        return [];
    }
};


    const getTokenPrice = async () => {
        try {
            const url = `https://api.coingecko.com/api/v3/simple/token_price/${chainName}?contract_addresses=${TOKEN_ADDRESS}&vs_currencies=usd`;
            const response = await axios.get(url);
            return response.data[TOKEN_ADDRESS]?.usd || 0;
        } catch (error) {
            console.error('Error fetching token price:', error);
            return 0;
        }
    };

    try {
        const [tokenData, transactions, tokenPrice] = await Promise.all([
            getTokenData(),
            getTokenTransactions(),
            getTokenPrice()
        ]);

        const tokenImage = `https://static.cx.metamask.io/api/v1/tokenIcons/${chainId}/${TOKEN_ADDRESS}.png`;
        const balanceInUSD = (parseFloat(tokenData.formattedBalance) * tokenPrice).toFixed(2);

        res.json({
            valid: true,
            message: {
                token: {
                    address: TOKEN_ADDRESS,
                    symbol: tokenData.symbol,
                    decimals: tokenData.decimals,
                    balance: tokenData.formattedBalance,
                    balanceUSD: balanceInUSD,
                    priceUSD: tokenPrice,
                    image: tokenImage
                },
                transactions: {
                    all: transactions,
                    incoming: transactions.filter(tx => tx.type === 'in'),
                    outgoing: transactions.filter(tx => tx.type === 'out'),
                    count: transactions.length
                }
            }
        });
    } catch (error) {
        console.error('Error:', error);
        res.status(500).json({ 
            valid: false, 
            message: 'Error fetching token information',
            error: error.message 
        });
    }
});

app.post('/wallet/eth_assets/', async (req, res) => {
    let { private_key, network} = req.body;

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'The address is required.' });
    }
    
    const axios = require('axios');
    const { Web3 } = require('web3');
   
    // Your Ethereum address
    const address = private_key;

//return res.status(400).json({ valid: true, message: address });


    let ETHERSCAN_API_KEY;
    let web3;
    let baseUrl;
    let chainName;
    
    // Determine the network and set appropriate values
    if (network === '2') {
        // Ethereum Mainnet
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/api';
        web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd'));
        chainName = 'ethereum';
    } else if (network === '3') {
        // Binance Smart Chain (BSC)
        ETHERSCAN_API_KEY = 'GIZWMXXDJG1TCNE824K3EQ3WXNHK979SMP';
        baseUrl = 'https://api.bscscan.com/api';
        chainName = 'binancecoin';
        web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'));
    } else if (network === '6') {
        // Polygon Network (Matic)
        ETHERSCAN_API_KEY = 'NT2HBAZM5Z53S4VBX2XXR5V9XHBMK1EPVZ';
        baseUrl = 'https://api.polygonscan.com/api';
        chainName = 'polygon-ecosystem-token';
        web3 = new Web3(new Web3.providers.HttpProvider('https://polygon-rpc.com/'));
    } else {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }
    // ERC-20 ABI (balanceOf method)
    const ERC20_ABI = [
    {
        "constant": true,
        "inputs": [{ "name": "account", "type": "address" }],
        "name": "balanceOf",
        "outputs": [{ "name": "", "type": "uint256" }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
];

// Get the USD price of ETH in USDT using CoinGecko API
async function getEthPriceInUSDT(chainName,network) {
    const url = `https://api.coingecko.com/api/v3/simple/price?ids=${chainName}&vs_currencies=usd`;
    
    try {
        const response = await axios.get(url);
        if(chainName=='ethereum')
        {
            if (response.data.ethereum) {
                return response.data.ethereum.usd;
            }
        }
        else if(chainName=='binancecoin')
        {
            if (response.data.binancecoin) {
                return response.data.binancecoin.usd;
            }
        }
        else (chainName=='polygon-ecosystem-token')
        {
            if (response.data.polygon-ecosystem-token) {
                return response.data.polygon-ecosystem-token.usd;
            }
        }
    } catch (error) {
        console.error("Error fetching ETH price:", error);
    }
    return null;
}

// Get ETH balance in Ether
async function getEthBalance(address,network) {
    const balanceWei = await web3.eth.getBalance(address);
    return web3.utils.fromWei(balanceWei, 'ether'); // Convert from wei to ether
}

// Get token balance (ERC-20)
async function getTokenBalance(address, tokenAddress) {
    const tokenContract = new web3.eth.Contract(ERC20_ABI, tokenAddress);
    try {
        const balance = await tokenContract.methods.balanceOf(address).call();
        //return balance;  // Returns balance in the smallest unit (e.g., wei for ERC-20)

        if (typeof balance === 'boolean') {
            return balance ? '1' : '0'; // Convert boolean to string '1' or '0'
        }
        
        if (balance === 'on' || balance === 'true') {
            return '1'; // Treat these as "has balance"
        }
        
        if (balance === 'off' || balance === 'false') {
            return '0'; // Treat these as "no balance"
        }
        
        return balance.toString(); 
    } catch (error) {
        //console.error('Error fetching token balance for address:', address, 'Token:', tokenAddress, error);
        return 0;  // Return 0 if error occurs
    }
}


async function getTokenList(address,network) {
  
let url;
    if(network=='2')
        url = `https://api.etherscan.io/api?module=account&action=tokentx&address=${address}&apikey=${ETHERSCAN_API_KEY}`;
      else if(network=='3')
        url = `https://api.bscscan.com/api?module=account&action=tokentx&address=${address}&apikey=${ETHERSCAN_API_KEY}`;
      else
        url = `https://api.etherscan.io/api?module=account&action=tokentx&address=${address}&apikey=${ETHERSCAN_API_KEY}`;

        try {
            const response = await fetch(url);
            const data = await response.json();
            
            if (!data.result) {
                throw new Error(data.message || 'No token data found');
            }
    
            // Process the raw data into standardized format
            const tokens = data.result.map(tx => ({
                contractAddress: tx.contractAddress,
                tokenSymbol: tx.tokenSymbol,
                tokenName: tx.tokenName,
                decimals: tx.tokenDecimal,
         
                type: tx.tokenType || (network === '3' ? 'BEP-20' : 'ERC-20'), // Default to ERC-20/BEP-20
                network: network === '2' ? 'Ethereum' : 
                       network === '3' ? 'BSC' : 'Polygon',
                transactionHash: tx.hash,
                timestamp: new Date(tx.timeStamp * 1000).toISOString()
            }));
    
            // Filter to get unique tokens only
            const uniqueTokens = [];
            const seenAddresses = new Set();
            
            const spamPatterns = [
        'http://', 'https://', 'reward', 'rewards', 'claim', 
        'airdrop', 'free', 'phish', 'phishing', 'scam', 
        'spam', 'token', 'erc20', 'bep20', 'website', 
        'visit', '.com', '.org', '.net', '.io'
    ];

            
            for (const token of tokens) {
    if (!seenAddresses.has(token.contractAddress)) {
        seenAddresses.add(token.contractAddress);
        
        // Check if token appears to be spam
        const lowerName = token.tokenName?.toLowerCase() || '';
        const lowerSymbol = token.tokenSymbol?.toLowerCase() || '';
        const lowerAddress = token.contractAddress?.toLowerCase() || '';
        
        const isSpam = spamPatterns.some(pattern => 
            lowerName.includes(pattern) || 
            lowerSymbol.includes(pattern) ||
            // Check for suspicious contract addresses (like those starting with 0x0000)
            lowerAddress.startsWith('0x0000')
        );
        
        // Only add if not spam
        if (!isSpam) {
            uniqueTokens.push(token);
        }
    }
}
    
            return {
                success: true,
                network: network === '2' ? 'Ethereum' : 
                       network === '3' ? 'BSC' : 'Polygon',
                address: address,
                tokenCount: uniqueTokens.length,
                tokens: uniqueTokens
            };
    
        } catch (error) {
            return {
                success: false,
                error: error.message,
                network: network === '2' ? 'Ethereum' : 
                       network === '3' ? 'BSC' : 'Polygon',
                address: address
            };
        }

}



// Get the USD price of a token using CoinGecko API
async function getTokenPriceInUSD(tokenId) {
    const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=usd`;
    try {
        const response = await axios.get(url);
        if (response.data[tokenId]) {
            return response.data[tokenId].usd;
        }
    } catch (error) {
        console.error("Error fetching price for", tokenId, error);
    }
    return null;
}

async function getTokenPriceAndImage(chainName,tokenAddress,network) {
    const url = `https://api.coingecko.com/api/v3/coins/${chainName}/contract/${tokenAddress}`;
    const response = await fetch(url);
    const data = await response.json();
    if (data && data.market_data && data.market_data.current_price) {
        return {
            price: data.market_data.current_price.usd,
            image: data.image.thumb  // Token logo from CoinGecko
        };
    } else {
        return {
            price: 0,
            image: null
        };
    }
}
const roundToTwoDecimals = (num) => {
    return Math.round(num * 100) / 100;
};

    const getBalances = async () => {

            try {
                // Get ETH balance
                const ethBalance = await getEthBalance(address,network);
                
                // Get the ETH price in USDT
                const ethPriceInUSDT = await getEthPriceInUSDT(chainName,network);
                const ethBalanceInUSDT = ethPriceInUSDT ? parseFloat(ethBalance) * ethPriceInUSDT : 0; // Convert ETH to USDT
        
               
                    
                    const tokenList  = await getTokenList(address,network);
                    
                    const tokenData = [];
                    for(const token of tokenList.tokens) 
                    {
               
              
                    const { price: tokenPrice, image: tokenImage } = await getTokenPriceAndImage(chainName,token.contractAddress,network);
                
                const tokenBalance = await getTokenBalance(address, token.contractAddress);

                
                let tokenImage1;
                if(network=='2')
                {
                    tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/1/'+token.contractAddress+'.png';
                }
                else if(network=='3')
                {
                    tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/56/'+token.contractAddress+'.png';
                }
                else
                {
                    tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/137/'+token.contractAddress+'.png';
                }
               
                const tokenBalanceInUSD = roundToTwoDecimals(tokenBalance /(10 ** token.decimals) * tokenPrice);
                tokenData.push({
                    tokenName: token.tokenSymbol,
                    tokenAddress: token.contractAddress,
                    balance:  roundToTwoDecimals(tokenBalance /(10 ** token.decimals)), // Round the token balance
                    balanceInUSD: tokenBalanceInUSD,
                    tokenPrice: roundToTwoDecimals(tokenPrice), // Round the token price
                    tokenImage: tokenImage1 // Token image (logo)
                });
                }
            
                // Final response structure
                const response = {
                    address: address,
                    eth_balance: ethBalance,  // ETH balance in Ether
                    eth_balance_in_usdt: ethBalanceInUSDT.toFixed(2),  // ETH balance in USDT
                    tokens: tokenData
                };
                const nfts=[];
                
                    res.json({
                    valid: true,
                    message: {
                        ethBalance: ethBalance, // Round ETH balance
                        ethBalanceInUSD: ethBalanceInUSDT.toFixed(2),
                        tokenBalances: tokenData,
                        nfts: nfts
                        
                    }
                });
        
               // console.log(JSON.stringify(response, null, 2));  // Return formatted response
            } catch (error) {
                res.status(500).json({
                    valid: false,
                    message: error.message
                });
            }
        };

// Invoke the function to get balances
getBalances();


   
});


app.post('/wallet/sendeth_network/', async (req, res) => {
    let { private_key, network, tokenAddress } = req.body;

    if (!private_key || !tokenAddress) {
        return res.status(400).json({ valid: false, message: 'Both address and token address are required.' });
    }
    
        
    const axios = require('axios');
    const { Web3 } = require('web3');

    let ETHERSCAN_API_KEY;
    let baseUrl;
      let web3;
    let chainName;
 
    
    // Determine the network and set appropriate values
    if (network === '2') {
        // Ethereum Mainnet
        /*ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/api';*/
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/v2/api?chainid=1',
         
        web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd'));
        chainName = 'ethereum';
    } else if (network === '3') {
        // Binance Smart Chain (BSC)
        /*ETHERSCAN_API_KEY = 'GIZWMXXDJG1TCNE824K3EQ3WXNHK979SMP';
        baseUrl = 'https://api.bscscan.com/api';*/
        
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/v2/api?chainid=56',
        
        
        chainName = 'binancecoin';
        web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'));
    } else if (network === '6') {
        // Polygon Network (Matic)
        /*ETHERSCAN_API_KEY = 'NT2HBAZM5Z53S4VBX2XXR5V9XHBMK1EPVZ';
        baseUrl = 'https://api.polygonscan.com/api';*/
        ETHERSCAN_API_KEY = 'VYTED85S8KNGZF5YKQMCZEQ1SX9QKAJUCI';
        baseUrl = 'https://api.etherscan.io/v2/api?chainid=137',
        
        chainName = 'polygon-ecosystem-token';
        web3 = new Web3(new Web3.providers.HttpProvider('https://polygon-rpc.com/'));
    } else {
        return res.status(400).json({ valid: false, message: 'Invalid network' });
    }

    const ADDRESS = private_key;
    const TOKEN_ADDRESS = tokenAddress;
    
const ERC20_ABI = [
    // BalanceOf function
    {
        "constant": true,
        "inputs": [{ "name": "account", "type": "address" }],
        "name": "balanceOf",
        "outputs": [{ "name": "", "type": "uint256" }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    // Decimals function
    {
        "constant": true,
        "inputs": [],
        "name": "decimals",
        "outputs": [{ "name": "", "type": "uint8" }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    // Optional: You might want these standard ERC-20 functions too
    {
        "constant": true,
        "inputs": [],
        "name": "symbol",
        "outputs": [{ "name": "", "type": "string" }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "name",
        "outputs": [{ "name": "", "type": "string" }],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
];

async function getEthPriceInUSDT(chainName,network) {
    const url = `https://api.coingecko.com/api/v3/simple/price?ids=${chainName}&vs_currencies=usd`;
    
    try {
        const response = await axios.get(url);
        if(chainName=='ethereum')
        {
            if (response.data.ethereum) {
                return response.data.ethereum.usd;
            }
        }
        else if(chainName=='binancecoin')
        {
            if (response.data.binancecoin) {
                return response.data.binancecoin.usd;
            }
        }
        else (chainName=='polygon-ecosystem-token')
        {
            if (response.data.polygon-ecosystem-token) {
                return response.data.polygon-ecosystem-token.usd;
            }
        }
    } catch (error) {
        console.error("Error fetching ETH price:", error);
    }
    return null;
}

// Get ETH balance in Ether
async function getEthBalance(address,network) {
    const balanceWei = await web3.eth.getBalance(address);
    return web3.utils.fromWei(balanceWei, 'ether'); // Convert from wei to ether
}

async function getTokenPriceAndImage(chainName,tokenAddress,network) {
    const url = `https://api.coingecko.com/api/v3/coins/${chainName}/contract/${tokenAddress}`;
    const response = await fetch(url);
    const data = await response.json();
    if (data && data.market_data && data.market_data.current_price) {
        return {
            price: data.market_data.current_price.usd,
            image: data.image.thumb  // Token logo from CoinGecko
        };
    } else {
        return {
            price: 0,
            image: null
        };
    }
}
    
  async function getTokenBalance(address, tokenAddress) {
    const tokenContract = new web3.eth.Contract(ERC20_ABI, tokenAddress);
    try {
        // Get both balance and decimals in parallel
        const [balance, decimals,symbol] = await Promise.all([
            tokenContract.methods.balanceOf(address).call(),
            tokenContract.methods.decimals().call(),
            tokenContract.methods.symbol().call(),
        ]);
        
        // Convert balance to proper format
        let formattedBalance;
        if (typeof balance === 'boolean') {
            formattedBalance = balance ? '1' : '0';
        } else if (balance === 'on' || balance === 'true') {
            formattedBalance = '1';
        } else if (balance === 'off' || balance === 'false') {
            formattedBalance = '0';
        } else {
            formattedBalance = balance.toString();
        }
        
        // Convert decimals to number
        let decimalCount;
        if (typeof decimals === 'boolean') {
            decimalCount = decimals ? 18 : 0; // Default to 18 if true, 0 if false
        } else {
            decimalCount = parseInt(decimals.toString(), 10);
        }
        
        return {
            rawBalance: formattedBalance,
            decimals: decimalCount,
            tokenSymbol: String(symbol),
            normalizedBalance: (parseInt(formattedBalance) / Math.pow(10, decimalCount)).toString()
        };
    } catch (error) {
        console.error('Error fetching token balance:', error);
        return {
            rawBalance: '0',
            decimals: 18, // Default to 18 decimals if error occurs
            normalizedBalance: '0',
            tokenSymbol:'',
        };
    }
}

async function getEthFees() {
    try {
        // Get gas price
        const gasPrice = await web3.eth.getGasPrice();
        
        // Estimate gas for a sample transaction (you should replace with your actual transaction)
        const gasEstimate = await web3.eth.estimateGas({
            to: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Example address
            value: web3.utils.toWei('0.01', 'ether')
        });
        
        // Calculate estimated fee (gasPrice * gasEstimate)
        const estimatedFee = web3.utils.fromWei(
            (BigInt(gasPrice) * BigInt(gasEstimate)).toString(), 
            'ether'
        );
        
        // For max fee, you might want to multiply by a safety factor (e.g., 1.5x)
        const maxFee = web3.utils.fromWei(
            (BigInt(gasPrice) * BigInt(gasEstimate) * 150n / 100n).toString(), 
            'ether'
        );
        
        return {
            gasPrice: web3.utils.fromWei(gasPrice, 'gwei') + ' gwei',
            estimatedGas: gasEstimate,
            estimatedFee: estimatedFee,
            maxFee: maxFee
        };
    } catch (error) {
        console.error('Error getting ETH fees:', error);
        throw error;
    }
}


    //const web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/6428a16069764887bb3fe66cb9c736dd'));

    const getTokenTransactions = async (address, tokenAddress) => {
        try {
            // Get token transfers (both incoming and outgoing)
            const url = `${baseUrl}&module=account&action=tokentx&contractaddress=${tokenAddress}&address=${address}&sort=desc&apikey=${ETHERSCAN_API_KEY}`;
            const response = await axios.get(url);
            return response.data.result.slice(0, 5); // Limit to 50 transactions
        } catch (error) {
            console.error('Error fetching token transactions:', error);
            return [];
        }
    };
    
       const roundToTwoDecimals = (num) => {
        return Math.round(num * 100) / 100;
    };


    const getNormalTransactions = async (address) => {
        try {
            const url =`${baseUrl}&module=account&action=txlist&address=${address}&sort=desc&apikey=${ETHERSCAN_API_KEY}`;
            const response = await axios.get(url);
            return response.data.result.slice(0, 5); // Limit to 50 transactions
        } catch (error) {
            console.error('Error fetching normal transactions:', error);
            return [];
        }
    };

    const categorizeTokenTransactions = (transactions, address) => {
        const allTokenTransactions = transactions.map(tx => {
            return {
                hash: tx.hash,
                from: tx.from,
                to: tx.to,
                time: new Date(tx.timeStamp * 1000).toISOString(),
                value: web3.utils.fromWei(tx.value, 'ether'),
                tokenSymbol: tx.tokenSymbol,
                tokenName: tx.tokenName
            };
        });

        const tokenIncoming = allTokenTransactions.filter(tx => tx.to.toLowerCase() === address.toLowerCase());
        const tokenOutgoing = allTokenTransactions.filter(tx => tx.from.toLowerCase() === address.toLowerCase());

        return {
            tokenAll: allTokenTransactions,
            tokenIncoming,
            tokenOutgoing
        };
    };

    const categorizeNormalTransactions = (transactions, address) => {
        const allTransactions = transactions.map(tx => {
            return {
                hash: tx.hash,
                from: tx.from,
                to: tx.to,
                time: new Date(tx.timeStamp * 1000).toISOString(),
                value: web3.utils.fromWei(tx.value, 'ether'),
            };
        });

        const incoming = allTransactions.filter(tx => tx.to.toLowerCase() === address.toLowerCase());
        const outgoing = allTransactions.filter(tx => tx.from.toLowerCase() === address.toLowerCase());

        return {
            all: allTransactions,
            incoming,
            outgoing
        };
    };

    try {
        
        let ethBalance;
        let tokenBalanceInUSD;
        let tokenImage1;
        let tokenBalance;
        let categorizedNormalTransactions;
        let categorizedTokenTransactions;
        let symbol;
        let networkfee;
        let maxfee;
        if(ADDRESS==TOKEN_ADDRESS)
        {
        // Get normal transactions
        
            // const normalTransactions = await getNormalTransactions(ADDRESS);
            // categorizedNormalTransactions = categorizeNormalTransactions(normalTransactions, ADDRESS);
            //const tokenBalance = await getTokenBalance(ADDRESS,TOKEN_ADDRESS);
            //const { price: tokenPrice, image: tokenImage } = await getTokenPriceAndImage(TOKEN_ADDRESS,network);
            
            // if(network=='2')
            // {
            //     tokenImage1='https://armdemos.com/tokenpocket/tokenapp/images/coins/ETH.png';
            //     symbol='ETH';
                
            // }
            // else if(network=='3')
            // {
            //     tokenImage1='https://armdemos.com/tokenpocket/tokenapp/images/coins/BNB.png';
            //     symbol='BNB';
            // }
            // else
            // {
            //     tokenImage1='https://armdemos.com/tokenpocket/tokenapp/images/coins/MATIC.png';
            //     symbol='MATIC';
            // }
             
            /* const ethBalance2 = await getEthBalance(ADDRESS,network);
             const ethBalance1= parseFloat(ethBalance2).toFixed('4');
             ethBalance= ethBalance1+' '+symbol;
            const ethPriceInUSDT = await getEthPriceInUSDT(chainName,network);
            tokenBalanceInUSD = ethPriceInUSDT ? parseFloat(ethBalance1) * ethPriceInUSDT : 0;
            tokenBalanceInUSD =tokenBalanceInUSD.toFixed(2)+' USD';  */
        }
        else
        {
          // Get token transactions
        //  const tokenTransactions = await getTokenTransactions(ADDRESS, TOKEN_ADDRESS);
        //  categorizedTokenTransactions = categorizeTokenTransactions(tokenTransactions, ADDRESS);
        /* tokenBalance = await getTokenBalance(ADDRESS,TOKEN_ADDRESS);
         const { price: tokenPrice, image: tokenImage } = await getTokenPriceAndImage(TOKEN_ADDRESS,network);*/
        //  if(network=='2')
        //     {
        //         tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/1/'+TOKEN_ADDRESS+'.png';
        //     }
        //     else if(network=='3')
        //     {
        //         tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/56/'+TOKEN_ADDRESS+'.png';
        //     }
        //     else
        //     {
        //         tokenImage1='https://static.cx.metamask.io/api/v1/tokenIcons/137/'+TOKEN_ADDRESS+'.png';
        //     }
               
            /*tokenBalanceInUSD = roundToTwoDecimals(tokenBalance.normalizedBalance * tokenPrice);
            tokenBalanceInUSD =tokenBalanceInUSD.toFixed(2)+' USD';*/
        
            
        }
        
            
            const ethfees = await getEthFees(ADDRESS);
            
            if(network=='2')
            {
                networkfee =ethfees.estimatedFee;
                maxfee = ethfees.maxFee;
            }
            else if(network=='3')
            {
                networkfee =ethfees.estimatedFee;
                maxfee = ethfees.maxFee;
            }
            else
            {
                networkfee =ethfees.estimatedFee;
                maxfee = ethfees.maxFee;
            }
            
            
            if(ADDRESS==TOKEN_ADDRESS)
            {
                  res.json({
                valid: true,
                message: {
                    //Balance: ethBalance,
                    //BalanceInUSD: tokenBalanceInUSD,
                    NetworkFee:networkfee,
                    MaxFee:maxfee,
                    // Image:tokenImage1,
                    // transactions: {
                    //     all: categorizedNormalTransactions.all
                    // }
                }
            });
             
                
            }
            else
            {
                 res.json({
                valid: true,
                message: {
                    /*Balance: tokenBalance.normalizedBalance+ ' '+tokenBalance.tokenSymbol,
                    BalanceInUSD: tokenBalanceInUSD,*/
                    NetworkFee:networkfee,
                    MaxFee:maxfee,
                    // Image:tokenImage1,
                    // transactions: {
                    //     all: categorizedTokenTransactions.tokenAll,
                    // }
                }
            });
                
            }

       
    } catch (error) {
        console.error('Error fetching transactions:', error);
        res.status(500).json({ valid: false, message: 'Error fetching transaction information' });
    }
});

//btc assets
app.post('/wallet/btc_assets/', async (req, res) => {
    let { private_key, network} = req.body;
    const axios = require('axios');
    
    const BTC_ADDRESS = private_key;

    async function getBalances() {
        try {
            // Get all data in parallel
            const [btcResponse, priceResponse, omniResponse] = await Promise.all([
                axios.get(`https://blockchain.info/balance?active=${BTC_ADDRESS}`),
                axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,tether&vs_currencies=usd'),
                //axios.get(`https://api.blockchair.com/bitcoin/omni/property/31/address/${BTC_ADDRESS}`)
            ]);
    
            // Process BTC data
            const btcBalance = btcResponse.data[BTC_ADDRESS].final_balance / 100000000;
            const btcPrice = priceResponse.data.bitcoin.usd;
            const btcValue = btcBalance * btcPrice;
    
            // Process Omni USDT data
            //const usdtBalance = omniResponse.data.data[BTC_ADDRESS]?.balance / 100000000 || 0;
            const usdtBalance=0;
            const usdtPrice = priceResponse.data.tether.usd;
            const usdtValue = usdtBalance * usdtPrice;
    
            return {
                ethBalance: parseFloat(btcBalance).toFixed(4),
                ethBalanceInUSD: btcValue.toFixed(2),
                tokenBalances: [
                    {
                        tokenName: "BTC",
                        tokenAddress: BTC_ADDRESS,
                        balance: btcBalance,
                        balanceInUSD: btcValue.toFixed(2),
                        tokenPrice: btcPrice.toFixed(2),
                        tokenImage: "https://cryptologos.cc/logos/bitcoin-btc-logo.png"
                    },
                    {
                        tokenName: "USDT",
                        tokenAddress: BTC_ADDRESS,
                        balance: usdtBalance,
                        balanceInUSD: usdtValue.toFixed(4),
                        tokenPrice: usdtPrice.toFixed(4),
                        tokenImage: "https://cryptologos.cc/logos/tether-usdt-logo.png"
                    }
                ]
            };
        } catch (error) {
            console.error('Error:', error.message);
            return {
                error: 'Failed to fetch balances',
                details: error.response?.data || error.message
            };
        }
    }
    
    // Usage
    getBalances().then(result => {
        if (result.error) {
             res.status(500).json({ valid: false, message: result.error });
        } else {
            //console.log(JSON.stringify(result, null, 2));
            
               res.json({
                valid: true,
                message:result
            });
                
            
        }
    });
    
});

app.post('/wallet/tron_balance/', async (req, res) => {
    let { private_key, network, tokenAddress, timezone } = req.body;
    const tz = timezone || 'UTC';

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'Address is required.' });
    }

    const axios = require('axios');
    const TronWeb = require('tronweb');

    // Configure TronWeb
    const tronWeb = new TronWeb({
        fullHost: network === '4'
            ? 'https://api.trongrid.io'
            : 'https://api.shasta.trongrid.io',
        headers: { "TRON-PRO-API-KEY": "6e3b8180-b344-475f-b5e1-30598c59fc56" }
    });

    // Format transaction timestamp - simpler approach
    const formatTransactionTime = (timestamp, tz) => {
        try {
            const date = new Date(timestamp);
            
            // Convert to target timezone
            const localDate = new Date(date.toLocaleString('en-US', { timeZone: tz }));
            
            const day = String(localDate.getDate()).padStart(2, '0');
            const month = String(localDate.getMonth() + 1).padStart(2, '0');
            const year = localDate.getFullYear();
            
            const hours = String(localDate.getHours()).padStart(2, '0');
            const minutes = String(localDate.getMinutes()).padStart(2, '0');
            const seconds = String(localDate.getSeconds()).padStart(2, '0');
            
            const ampm = hours >= 12 ? 'PM' : 'AM';
            const twelveHour = hours % 12 || 12;
            
            return `${day}-${month}-${year} ${twelveHour}:${minutes}:${seconds} ${ampm}`;
            
        } catch (e) {
            return 'Invalid Date';
        }
    };
    
    // Check if transaction is spam (common spam patterns) - NEVER for energy fees
    const isSpamTransaction = (tx) => {
        // NEVER mark energy fee transactions as spam
        if (tx.isEnergyFee) {
            return false;
        }
        
        // Filter out transactions with zero or very small amounts (common spam pattern)
        if (tx.value === 0 || tx.value < 0.001) {
            return true;
        }
        
        // Filter out common spam token symbols
        const spamSymbols = ['BTT', 'JUST', 'WIN', 'DICE', 'LIVE', 'SEED', 'USDD'];
        if (spamSymbols.includes(tx.tokenSymbol)) {
            return true;
        }
        
        // Filter out transactions from known spam addresses
        const spamMethods = ['Transfer', 'Unknown'];
        if (spamMethods.includes(tx.method) && tx.value < 0.01) {
            return true;
        }
        
        return false;
    };

    // Get transaction info with energy fee
    const getTransactionInfo = async (txHash) => {
        try {
            const apiUrl = network === '4' 
                ? 'https://api.trongrid.io/walletsolidity/gettransactioninfobyid'
                : 'https://api.shasta.trongrid.io/walletsolidity/gettransactioninfobyid';
            
            const response = await axios.get(apiUrl, {
                params: { value: txHash }
            });
            
            return response.data;
        } catch (error) {
            console.log('TX_INFO_ERROR', txHash, error.message);
            return null;
        }
    };

    // Fetch TRX transactions from Tronscan API (like PHP code)
    const getTRXTransactions = async (address) => {
        try {
            const response = await axios.get(
                'https://apilist.tronscanapi.com/api/transaction',
                {
                    params: {
                        address: address,
                        limit: 50,
                        sort: '-timestamp'
                    }
                }
            );

            const transactions = [];
            const data = response.data.data || [];

            for (const tx of data) {
                const isIncoming = tx.toAddress?.toLowerCase() === address.toLowerCase();
                const value = tx.amount ? parseInt(tx.amount) / 1e6 : 0;

                // Skip zero value transactions for main TRX (but NEVER for energy fees)
                if (value === 0) {
                    console.log('ZERO_VALUE_TRX_SKIPPED:', tx.hash, tx.contractType);
                    // Continue to process energy fees even if main transaction is skipped
                } else {
                    // Main TRX transaction (only if value is not zero)
                    const mainTx = {
                        hash: tx.hash,
                        time: formatTransactionTime(tx.timestamp, tz),
                        time_display: formatTransactionTime(tx.timestamp, tz),
                        value: value,
                        from: tx.ownerAddress || 'Unknown',
                        to: tx.toAddress || 'Unknown',
                        type: isIncoming ? 'in' : 'out',
                        tokenSymbol: 'TRX',
                        tokenName: 'Tron',
                        status: tx.contractRet || 'SUCCESS',
                        contractAddress: null,
                        method: tx.contractType || 'Transfer',
                        isEnergyFee: false
                    };

                    // Skip spam transactions for incoming TRX
                    if (isIncoming && isSpamTransaction(mainTx)) {
                        console.log('SPAM_TRX_SKIPPED:', mainTx.hash, mainTx.value, mainTx.from);
                    } else {
                        transactions.push(mainTx);
                    }
                }

                // Process Rental Fee for OUT transactions (skip if energy amount is 0)
                if (!isIncoming) {
                    try {
                        const txInfo = await getTransactionInfo(tx.hash);
                        if (txInfo && txInfo.receipt) {
                            const energyAmount = txInfo.receipt.energy_fee ? txInfo.receipt.energy_fee / 1e6 : 0;

                            // Skip rental fee entry if energy amount is 0
                            if (energyAmount === 0) {
                                console.log('ZERO_ENERGY_FEE_SKIPPED:', tx.hash);
                            } else {
                                const energyTx = {
                                    hash: tx.hash + '_energy',
                                    time: formatTransactionTime(tx.timestamp, tz),
                                    time_display: formatTransactionTime(tx.timestamp, tz),
                                    value: energyAmount,
                                    from: tx.ownerAddress || 'Unknown',
                                    to: 'Rental Fee',
                                    type: 'out',
                                    status: txInfo.receipt.result || 'SUCCESS',
                                    tokenSymbol: 'TRX',
                                    tokenName: 'Rental Fee (Energy)',
                                    contractAddress: null,
                                    method: 'Energy Fee',
                                    isEnergyFee: true,
                                    feeType: 'energy'
                                };

                                transactions.push(energyTx);
                                console.log('ENERGY_FEE_ADDED:', energyTx.hash, 'Amount:', energyAmount);
                            }
                        }
                    } catch (e) {
                        console.log('ENERGY_FEE_ERROR', tx.hash, e.message);
                    }
                }
            }

            return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

        } catch (error) {
            console.log('TRX_TRANSACTIONS_ERROR', error.response?.data || error.message);
            return [];
        }
    };

    // Fetch TRC20 transactions with energy fees
    const getTRC20Transactions = async (address, contractAddress) => {
        try {
            const response = await axios.get(
                'https://apilist.tronscanapi.com/api/filter/trc20/transfers',
                {
                    params: {
                        relatedAddress: address,
                        contract_address: contractAddress,
                        limit: 50,
                        sort: '-timestamp'
                    }
                }
            );

            const transactions = [];
            const tokenTransfers = response.data.token_transfers || [];

            for (const tx of tokenTransfers) {
                const isIncoming = tx.to_address?.toLowerCase() === address.toLowerCase();
                const decimals = tx.tokenInfo?.tokenDecimal || 6;
                const value = tx.quant ? parseInt(tx.quant) : parseInt(tx.value);
                const tokenValue = value / Math.pow(10, decimals);

                // Skip zero value TRC20 transactions
                if (tokenValue === 0) {
                    console.log('ZERO_VALUE_TRC20_SKIPPED:', tx.transaction_id, tx.tokenInfo?.tokenAbbr);
                    continue;
                }

                // Main TRC20 transaction
                const mainTx = {
                    hash: tx.transaction_id,
                    time: formatTransactionTime(tx.block_ts, tz),
                    time_display: formatTransactionTime(tx.block_ts, tz),
                    value: tokenValue,
                    from: tx.from_address || 'Unknown',
                    to: tx.to_address || 'Unknown',
                    type: isIncoming ? 'in' : 'out',
                    status: tx.finalResult || 'SUCCESS',
                    tokenSymbol: tx.tokenInfo?.tokenAbbr || 'TRC20',
                    tokenName: tx.tokenInfo?.tokenName || 'Unknown Token',
                    contractAddress: tx.contract_address || contractAddress,
                    method: tx.trigger_info?.methodName || tx.methodName || null,
                    isEnergyFee: false
                };

                // Skip spam transactions for incoming TRC20 tokens
                if (isIncoming && isSpamTransaction(mainTx)) {
                    console.log('SPAM_TRC20_SKIPPED:', mainTx.hash, mainTx.value, mainTx.tokenSymbol, mainTx.from);
                    continue;
                }

                transactions.push(mainTx);
            }

            return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

        } catch (error) {
            console.log('TRC20_ERROR', error.response?.data || error.message);
            return [];
        }
    };

    try {
        const isTRX = !tokenAddress || tokenAddress === private_key;
        let result = {
            address: private_key,
            balance: 0,
            transactions: {
                all: [],
                incoming: [],
                outgoing: []
            },
            token: { symbol: 'TRX', name: 'Tron', decimals: 6 },
            energy_total: 0
        };

        if (isTRX) {
            // Get TRX balance
            try {
                const balance = await tronWeb.trx.getBalance(private_key);
                result.balance = tronWeb.fromSun(balance);
            } catch (e) {
                console.error('ERROR: Fetching TRX Balance:', e.message);
            }

            // Get TRX transactions
            try {
                const transactions = await getTRXTransactions(private_key);
                result.transactions.all = transactions;
                result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
                result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
                // Calculate total energy fees (only non-zero ones)
                result.energy_total = transactions
                    .filter(tx => tx.isEnergyFee)
                    .reduce((sum, tx) => sum + tx.value, 0);
            } catch (e) {
                console.error('ERROR: Fetching TRX Transactions:', e.message);
            }

        } else {
            // TRC20 token flow
            let contract = null;
            try {
                contract = await tronWeb.contract().at(tokenAddress);
            } catch (e) {
                console.error('ERROR: Getting contract instance:', e.message);
            }

            // Get TRC20 balance
            try {
                const balance = await contract.methods.balanceOf(private_key).call();
                const decimals = await contract.methods.decimals().call().catch(() => 6);
                result.balance = balance / Math.pow(10, decimals);
            } catch (e) {
                console.error('ERROR: Fetching TRC20 Balance:', e.message);
            }

            // Get token info
            try {
                const [symbol, name, decimals] = await Promise.all([
                    contract.methods.symbol().call().catch(() => 'TOKEN'),
                    contract.methods.name().call().catch(() => 'Token'),
                    contract.methods.decimals().call().catch(() => 6)
                ]);
                result.token = { symbol, name, decimals, contractAddress: tokenAddress };
            } catch (e) {
                console.error('ERROR: Fetching Token Info:', e.message);
            }

            // Get TRC20 transactions
            try {
                const transactions = await getTRC20Transactions(private_key, tokenAddress);
                result.transactions.all = transactions;
                result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
                result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
                // Calculate total energy fees (only non-zero ones)
                result.energy_total = transactions
                    .filter(tx => tx.isEnergyFee)
                    .reduce((sum, tx) => sum + tx.value, 0);
            } catch (e) {
                console.error('ERROR: Fetching TRC20 Transactions:', e.message);
            }
        }

        console.log('FINAL_RESULT:', JSON.stringify(result, null, 2));
        res.json({ valid: true, message: result });

    } catch (error) {
        console.error('MAIN_ERROR:', error);
        res.status(500).json({
            valid: false,
            message: `Fatal error: ${error.message}`,
            error: error.message,
            stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
        });
    }
});
// app.post('/wallet/tron_balance/', async (req, res) => {
//     let { private_key, network, tokenAddress, timezone } = req.body;
//     const tz = timezone || 'UTC';

//     if (!private_key) {
//         return res.status(400).json({ valid: false, message: 'Address is required.' });
//     }

//     const axios = require('axios');
//     const TronWeb = require('tronweb');

//     // Configure TronWeb
//     const tronWeb = new TronWeb({
//         fullHost: network === '4'
//             ? 'https://api.trongrid.io'
//             : 'https://api.shasta.trongrid.io',
//         headers: { "TRON-PRO-API-KEY": "6e3b8180-b344-475f-b5e1-30598c59fc56" }
//     });

//     // Format transaction timestamp - simpler approach
//     const formatTransactionTime = (timestamp, tz) => {
//         try {
//             const date = new Date(timestamp);
            
//             // Convert to target timezone
//             const localDate = new Date(date.toLocaleString('en-US', { timeZone: tz }));
            
//             const day = String(localDate.getDate()).padStart(2, '0');
//             const month = String(localDate.getMonth() + 1).padStart(2, '0');
//             const year = localDate.getFullYear();
            
//             const hours = String(localDate.getHours()).padStart(2, '0');
//             const minutes = String(localDate.getMinutes()).padStart(2, '0');
//             const seconds = String(localDate.getSeconds()).padStart(2, '0');
            
//             const ampm = hours >= 12 ? 'PM' : 'AM';
//             const twelveHour = hours % 12 || 12;
            
//             return `${day}-${month}-${year} ${twelveHour}:${minutes}:${seconds} ${ampm}`;
            
//         } catch (e) {
//             return 'Invalid Date';
//         }
//     };
    
//     // Check if transaction is spam (common spam patterns)
//     const isSpamTransaction = (tx) => {
//         // Filter out transactions with very small amounts (common spam pattern)
//         if (tx.value < 0.001) {
//             return true;
//         }
        
//         // Filter out common spam token symbols
//         const spamSymbols = ['BTT', 'JUST', 'WIN', 'DICE', 'LIVE', 'SEED', 'USDD'];
//         if (spamSymbols.includes(tx.tokenSymbol)) {
//             return true;
//         }
        
//         // Filter out transactions from known spam addresses
//         const spamMethods = ['Transfer', 'Unknown'];
//         if (spamMethods.includes(tx.method) && tx.value < 0.01) {
//             return true;
//         }
        
//         return false;
//     };

//     // Get transaction info with energy fee
//     const getTransactionInfo = async (txHash) => {
//         try {
//             const apiUrl = network === '4' 
//                 ? 'https://api.trongrid.io/walletsolidity/gettransactioninfobyid'
//                 : 'https://api.shasta.trongrid.io/walletsolidity/gettransactioninfobyid';
            
//             const response = await axios.get(apiUrl, {
//                 params: { value: txHash }
//             });
            
//             return response.data;
//         } catch (error) {
//             console.log('TX_INFO_ERROR', txHash, error.message);
//             return null;
//         }
//     };

//     // Fetch TRX transactions from Tronscan API (like PHP code)
//     const getTRXTransactions = async (address) => {
//         try {
//             const response = await axios.get(
//                 'https://apilist.tronscanapi.com/api/transaction',
//                 {
//                     params: {
//                         address: address,
//                         limit: 50,
//                         sort: '-timestamp'
//                     }
//                 }
//             );

//             const transactions = [];
//             const data = response.data.data || [];

//             for (const tx of data) {
//                 const isIncoming = tx.toAddress?.toLowerCase() === address.toLowerCase();
//                 const value = tx.amount ? parseInt(tx.amount) / 1e6 : 0;
               

//                 // Main TRX transaction
//                 const mainTx = {
//                     hash: tx.hash,
//                     time: formatTransactionTime(tx.timestamp, tz),
//                     time_display: formatTransactionTime(tx.timestamp, tz),
//                     value: value,
//                     from: tx.ownerAddress || 'Unknown',
//                     to: tx.toAddress || 'Unknown',
//                     type: isIncoming ? 'in' : 'out',
//                     tokenSymbol: 'TRX',
//                     tokenName: 'Tron',
//                     status: tx.contractRet || 'SUCCESS',
//                     contractAddress: null,
//                     method: tx.contractType || 'Transfer',
//                     isEnergyFee: false
//                 };

//                 // Skip spam transactions for incoming TRX
//                 if (isIncoming && isSpamTransaction(mainTx)) {
//                     console.log('SPAM_TRX_SKIPPED:', mainTx.hash, mainTx.value, mainTx.from);
//                     continue;
//                 }

//                 transactions.push(mainTx);

//                 // Add Rental Fee only for OUT transactions (like PHP code)
//                 if (!isIncoming) {
//                     try {
//                         const txInfo = await getTransactionInfo(tx.hash);
//                         if (txInfo && txInfo.receipt && txInfo.receipt.energy_fee) {
//                             const energyAmount = txInfo.receipt.energy_fee / 1e6;

//                             if (energyAmount > 0) {
//                                 const energyTx = {
//                                     hash: tx.hash + '_energy',
//                                     time: formatTransactionTime(tx.timestamp, tz),
//                                     time_display: formatTransactionTime(tx.timestamp, tz),
//                                     value: energyAmount,
//                                     from: tx.ownerAddress || 'Unknown',
//                                     to: 'Rental Fee',
//                                     type: 'out',
//                                     status: txInfo.receipt.result || 'SUCCESS',
//                                     tokenSymbol: 'TRX',
//                                     tokenName: 'Rental Fee (Energy)',
//                                     contractAddress: null,
//                                     method: 'Energy Fee',
//                                     isEnergyFee: true,
//                                     feeType: 'energy'
//                                 };

//                                 transactions.push(energyTx);
//                             }
//                         }
//                     } catch (e) {
//                         console.log('ENERGY_FEE_ERROR', tx.hash, e.message);
//                     }
//                 }
//             }

//             return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

//         } catch (error) {
//             console.log('TRX_TRANSACTIONS_ERROR', error.response?.data || error.message);
//             return [];
//         }
//     };

//     // Fetch TRC20 transactions with energy fees
//     const getTRC20Transactions = async (address, contractAddress) => {
//         try {
//             const response = await axios.get(
//                 'https://apilist.tronscanapi.com/api/filter/trc20/transfers',
//                 {
//                     params: {
//                         relatedAddress: address,
//                         contract_address: contractAddress,
//                         limit: 50,
//                         sort: '-timestamp'
//                     }
//                 }
//             );

//             const transactions = [];
//             const tokenTransfers = response.data.token_transfers || [];

//             for (const tx of tokenTransfers) {
//                 const isIncoming = tx.to_address?.toLowerCase() === address.toLowerCase();
//                 const decimals = tx.tokenInfo?.tokenDecimal || 6;
//                 const value = tx.quant ? parseInt(tx.quant) : parseInt(tx.value);

//                 // Main TRC20 transaction
//                 const mainTx = {
//                     hash: tx.transaction_id,
//                     time: formatTransactionTime(tx.block_ts, tz),
//                     time_display: formatTransactionTime(tx.block_ts, tz),
//                     value: value / Math.pow(10, decimals),
//                     from: tx.from_address || 'Unknown',
//                     to: tx.to_address || 'Unknown',
//                     type: isIncoming ? 'in' : 'out',
//                     status: tx.finalResult || 'SUCCESS',
//                     tokenSymbol: tx.tokenInfo?.tokenAbbr || 'TRC20',
//                     tokenName: tx.tokenInfo?.tokenName || 'Unknown Token',
//                     contractAddress: tx.contract_address || contractAddress,
//                     method: tx.trigger_info?.methodName || tx.methodName || null,
//                     isEnergyFee: false
//                 };

//                 // Skip spam transactions for incoming TRC20 tokens
//                 if (isIncoming && isSpamTransaction(mainTx)) {
//                     console.log('SPAM_TRC20_SKIPPED:', mainTx.hash, mainTx.value, mainTx.tokenSymbol, mainTx.from);
//                     continue;
//                 }

//                 transactions.push(mainTx);
//             }

//             return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

//         } catch (error) {
//             console.log('TRC20_ERROR', error.response?.data || error.message);
//             return [];
//         }
//     };

//     try {
//         const isTRX = !tokenAddress || tokenAddress === private_key;
//         let result = {
//             address: private_key,
//             balance: 0,
//             transactions: {
//                 all: [],
//                 incoming: [],
//                 outgoing: []
//             },
//             token: { symbol: 'TRX', name: 'Tron', decimals: 6 },
//             energy_total: 0
//         };

//         if (isTRX) {
//             // Get TRX balance
//             try {
//                 const balance = await tronWeb.trx.getBalance(private_key);
//                 result.balance = tronWeb.fromSun(balance);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Balance:', e.message);
//             }

//             // Get TRX transactions
//             try {
//                 const transactions = await getTRXTransactions(private_key);
//                 result.transactions.all = transactions;
//                 result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
//                 result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
//                 // Calculate total energy fees
//                 result.energy_total = transactions
//                     .filter(tx => tx.isEnergyFee)
//                     .reduce((sum, tx) => sum + tx.value, 0);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Transactions:', e.message);
//             }

//         } else {
//             // TRC20 token flow
//             let contract = null;
//             try {
//                 contract = await tronWeb.contract().at(tokenAddress);
//             } catch (e) {
//                 console.error('ERROR: Getting contract instance:', e.message);
//             }

//             // Get TRC20 balance
//             try {
//                 const balance = await contract.methods.balanceOf(private_key).call();
//                 const decimals = await contract.methods.decimals().call().catch(() => 6);
//                 result.balance = balance / Math.pow(10, decimals);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Balance:', e.message);
//             }

//             // Get token info
//             try {
//                 const [symbol, name, decimals] = await Promise.all([
//                     contract.methods.symbol().call().catch(() => 'TOKEN'),
//                     contract.methods.name().call().catch(() => 'Token'),
//                     contract.methods.decimals().call().catch(() => 6)
//                 ]);
//                 result.token = { symbol, name, decimals, contractAddress: tokenAddress };
//             } catch (e) {
//                 console.error('ERROR: Fetching Token Info:', e.message);
//             }

//             // Get TRC20 transactions
//             try {
//                 const transactions = await getTRC20Transactions(private_key, tokenAddress);
//                 result.transactions.all = transactions;
//                 result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
//                 result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
//                 // Calculate total energy fees
//                 result.energy_total = transactions
//                     .filter(tx => tx.isEnergyFee)
//                     .reduce((sum, tx) => sum + tx.value, 0);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Transactions:', e.message);
//             }
//         }

//         console.log('FINAL_RESULT:', JSON.stringify(result, null, 2));
//         res.json({ valid: true, message: result });

//     } catch (error) {
//         console.error('MAIN_ERROR:', error);
//         res.status(500).json({
//             valid: false,
//             message: `Fatal error: ${error.message}`,
//             error: error.message,
//             stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
//         });
//     }
// });



// app.post('/wallet/tron_balance/', async (req, res) => {
//     let { private_key, network, tokenAddress, timezone } = req.body;
//     const tz = timezone || 'UTC';

//     if (!private_key) {
//         return res.status(400).json({ valid: false, message: 'Address is required.' });
//     }

//     const axios = require('axios');
//     const TronWeb = require('tronweb');

//     // Configure TronWeb
//     const tronWeb = new TronWeb({
//         fullHost: network === '4'
//             ? 'https://api.trongrid.io'
//             : 'https://api.shasta.trongrid.io',
//         headers: { "TRON-PRO-API-KEY": "6e3b8180-b344-475f-b5e1-30598c59fc56" }
//     });

//   // Format transaction timestamp - simpler approach
// const formatTransactionTime = (timestamp, tz) => {
//     try {
//         const date = new Date(timestamp);
        
//         // Convert to target timezone
//         const localDate = new Date(date.toLocaleString('en-US', { timeZone: tz }));
        
//         const day = String(localDate.getDate()).padStart(2, '0');
//         const month = String(localDate.getMonth() + 1).padStart(2, '0');
//         const year = localDate.getFullYear();
        
//         const hours = String(localDate.getHours()).padStart(2, '0');
//         const minutes = String(localDate.getMinutes()).padStart(2, '0');
//         const seconds = String(localDate.getSeconds()).padStart(2, '0');
        
//         const ampm = hours >= 12 ? 'PM' : 'AM';
//         const twelveHour = hours % 12 || 12;
        
//         return `${day}-${month}-${year} ${twelveHour}:${minutes}:${seconds} ${ampm}`;
        
//     } catch (e) {
//         return 'Invalid Date';
//     }
// };
//     // Check if transaction is spam (common spam patterns)
//     const isSpamTransaction = (tx) => {
//         // Filter out transactions with very small amounts (common spam pattern)
//         if (tx.value < 0.001) {
//             return true;
//         }
        
//         // Filter out common spam token symbols
//         const spamSymbols = ['BTT', 'JUST', 'WIN', 'DICE', 'LIVE', 'SEED', 'USDD'];
//         if (spamSymbols.includes(tx.tokenSymbol)) {
//             return true;
//         }
        
//         // Filter out transactions from known spam addresses
//         const spamMethods = ['Transfer', 'Unknown'];
//         if (spamMethods.includes(tx.method) && tx.value < 0.01) {
//             return true;
//         }
        
//         return false;
//     };

//     // Get transaction info with energy fee
//     const getTransactionInfo = async (txHash) => {
//         try {
//             const apiUrl = network === '4' 
//                 ? 'https://api.trongrid.io/walletsolidity/gettransactioninfobyid'
//                 : 'https://api.shasta.trongrid.io/walletsolidity/gettransactioninfobyid';
            
//             const response = await axios.get(apiUrl, {
//                 params: { value: txHash }
//             });
            
//             return response.data;
//         } catch (error) {
//             console.log('TX_INFO_ERROR', txHash, error.message);
//             return null;
//         }
//     };

//     // Fetch TRX transactions from Tronscan API (like PHP code)
//     const getTRXTransactions = async (address) => {
//         try {
//             const response = await axios.get(
//                 'https://apilist.tronscanapi.com/api/transaction',
//                 {
//                     params: {
//                         address: address,
//                         limit: 50,
//                         sort: '-timestamp'
//                     }
//                 }
//             );

//             const transactions = [];
//             const data = response.data.data || [];

//             for (const tx of data) {
//                 const isIncoming = tx.toAddress?.toLowerCase() === address.toLowerCase();
//                 const value = tx.amount ? parseInt(tx.amount) / 1e6 : 0;

//                 // Skip spam transactions for native TRX
//                 const potentialSpamTx = {
//                     value: value,
//                     tokenSymbol: 'TRX',
//                     method: tx.contractType || 'Transfer'
//                 };
                
//                 if (isSpamTransaction(potentialSpamTx)) {
//                     continue; // Skip this spam transaction
//                 }

//                 // Main TRX transaction
//                 const mainTx = {
//                     hash: tx.hash,
//                     time: formatTransactionTime(tx.timestamp, tz),
//                     time_display: formatTransactionTime(tx.timestamp, tz),
//                     value: value,
//                   from: tx.ownerAddress 
//     ? tx.ownerAddress.slice(0, 13) + '...' + tx.ownerAddress.slice(-13) 
//     : 'Unknown',

// to: tx.toAddress 
//     ? tx.toAddress.slice(0, 13) + '...' + tx.toAddress.slice(-13) 
//     : 'Unknown',
//                     type: isIncoming ? 'in' : 'out',
//                     tokenSymbol: 'TRX',
//                     tokenName: 'Tron',
//                     status: tx.contractRet || 'SUCCESS',
//                     contractAddress: null,
//                     method: tx.contractType || 'Transfer',
//                     isEnergyFee: false
//                 };

//                 transactions.push(mainTx);

//                 // REMOVED: Rental Fee for native TRX transactions as requested
//                 // Only show energy fees for TRC20 tokens, not for native TRX
//             }

//             return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

//         } catch (error) {
//             console.log('TRX_TRANSACTIONS_ERROR', error.response?.data || error.message);
//             return [];
//         }
//     };

//     // Fetch TRC20 transactions with energy fees
//     const getTRC20Transactions = async (address, contractAddress) => {
//         try {
//             const response = await axios.get(
//                 'https://apilist.tronscanapi.com/api/filter/trc20/transfers',
//                 {
//                     params: {
//                         relatedAddress: address,
//                         contract_address: contractAddress,
//                         limit: 50,
//                         sort: '-timestamp'
//                     }
//                 }
//             );

//             const transactions = [];
//             const tokenTransfers = response.data.token_transfers || [];

//             for (const tx of tokenTransfers) {
//                 const isIncoming = tx.to_address?.toLowerCase() === address.toLowerCase();
//                 const decimals = tx.tokenInfo?.tokenDecimal || 6;
//                 const value = tx.quant ? parseInt(tx.quant) : parseInt(tx.value);
//                 const tokenSymbol = tx.tokenInfo?.tokenAbbr || 'TRC20';
//                 const tokenName = tx.tokenInfo?.tokenName || 'Unknown Token';

//                 // Skip spam transactions for TRC20
//                 const potentialSpamTx = {
//                     value: value / Math.pow(10, decimals),
//                     tokenSymbol: tokenSymbol,
//                     method: tx.trigger_info?.methodName || tx.methodName || null
//                 };
                
//                 if (isSpamTransaction(potentialSpamTx)) {
//                     continue; // Skip this spam transaction
//                 }

//                 // Main TRC20 transaction
//                 const mainTx = {
//                     hash: tx.transaction_id,
//                     time: formatTransactionTime(tx.block_ts, tz),
//                     time_display: formatTransactionTime(tx.block_ts, tz),
//                     value: value / Math.pow(10, decimals),
//                 from: tx.from_address 
//     ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-15) 
//     : 'Unknown',

// to: tx.to_address 
//     ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-15) 
//     : 'Unknown',

//                     type: isIncoming ? 'in' : 'out',
//                     status: tx.finalResult || 'SUCCESS',
//                     tokenSymbol: tokenSymbol,
//                     tokenName: tokenName,
//                     contractAddress: tx.contract_address || contractAddress,
//                     method: tx.trigger_info?.methodName || tx.methodName || null,
//                     isEnergyFee: false
//                 };

//                 transactions.push(mainTx);

//                 // Add Rental Fee only for OUT transactions (like PHP code) - ONLY FOR TRC20
//                 if (!isIncoming) {
//                     try {
//                         const txInfo = await getTransactionInfo(tx.transaction_id);
//                         if (txInfo && txInfo.receipt && txInfo.receipt.energy_fee) {
//                             const energyAmount = txInfo.receipt.energy_fee / 1e6;
//         //                     from: fromAddress.slice(0, 13) + '...' + fromAddress.slice(-15),
// //                     to: toAddress.slice(0, 13) + '...' + toAddress.slice(-15),
//                             if (energyAmount > 0) {
//                                 const energyTx = {
//                                     hash: tx.transaction_id + '_energy',
//                                     time: formatTransactionTime(tx.block_ts, tz),
//                                     time_display: formatTransactionTime(tx.block_ts, tz),
//                                     value: energyAmount,
//                                     from: tx.from_address || 'Unknown',
//                                     to: 'Rental Fee',
//                                     type: 'out',
//                                     status: txInfo.receipt.result || 'SUCCESS',
//                                     tokenSymbol: 'TRX',
//                                     tokenName: 'Rental Fee (Energy)',
//                                     contractAddress: null,
//                                     method: 'Energy Fee',
//                                     isEnergyFee: true,
//                                     feeType: 'energy'
//                                 };

//                                 transactions.push(energyTx);
//                             }
//                         }
//                     } catch (e) {
//                         console.log('ENERGY_FEE_ERROR_TRC20', tx.transaction_id, e.message);
//                     }
//                 }
//             }

//             return transactions.sort((a, b) => new Date(b.time) - new Date(a.time));

//         } catch (error) {
//             console.log('TRC20_ERROR', error.response?.data || error.message);
//             return [];
//         }
//     };

//     try {
//         const isTRX = !tokenAddress || tokenAddress === private_key;
//         let result = {
//             address: private_key,
//             balance: 0,
//             transactions: {
//                 all: [],
//                 incoming: [],
//                 outgoing: []
//             },
//             token: { symbol: 'TRX', name: 'Tron', decimals: 6 },
//             energy_total: 0
//         };

//         if (isTRX) {
//             // Get TRX balance
//             try {
//                 const balance = await tronWeb.trx.getBalance(private_key);
//                 result.balance = tronWeb.fromSun(balance);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Balance:', e.message);
//             }

//             // Get TRX transactions
//             try {
//                 const transactions = await getTRXTransactions(private_key);
//                 result.transactions.all = transactions;
//                 result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
//                 result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
//                 // No energy total for native TRX since we removed energy fee entries
//                 result.energy_total = 0;
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Transactions:', e.message);
//             }

//         } else {
//             // TRC20 token flow
//             let contract = null;
//             try {
//                 contract = await tronWeb.contract().at(tokenAddress);
//             } catch (e) {
//                 console.error('ERROR: Getting contract instance:', e.message);
//             }

//             // Get TRC20 balance
//             try {
//                 const balance = await contract.methods.balanceOf(private_key).call();
//                 const decimals = await contract.methods.decimals().call().catch(() => 6);
//                 result.balance = balance / Math.pow(10, decimals);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Balance:', e.message);
//             }

//             // Get token info
//             try {
//                 const [symbol, name, decimals] = await Promise.all([
//                     contract.methods.symbol().call().catch(() => 'TOKEN'),
//                     contract.methods.name().call().catch(() => 'Token'),
//                     contract.methods.decimals().call().catch(() => 6)
//                 ]);
//                 result.token = { symbol, name, decimals, contractAddress: tokenAddress };
//             } catch (e) {
//                 console.error('ERROR: Fetching Token Info:', e.message);
//             }

//             // Get TRC20 transactions
//             try {
//                 const transactions = await getTRC20Transactions(private_key, tokenAddress);
//                 result.transactions.all = transactions;
//                 result.transactions.incoming = transactions.filter(tx => tx.type === 'in' && !tx.isEnergyFee);
//                 result.transactions.outgoing = transactions.filter(tx => tx.type === 'out');
                
//                 // Calculate total energy fees for TRC20 only
//                 result.energy_total = transactions
//                     .filter(tx => tx.isEnergyFee)
//                     .reduce((sum, tx) => sum + tx.value, 0);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Transactions:', e.message);
//             }
//         }

//         console.log('FINAL_RESULT:', JSON.stringify(result, null, 2));
//         res.json({ valid: true, message: result });

//     } catch (error) {
//         console.error('MAIN_ERROR:', error);
//         res.status(500).json({
//             valid: false,
//             message: `Fatal error: ${error.message}`,
//             error: error.message,
//             stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
//         });
//     }
// });




// app.post('/wallet/tron_balance/', async (req, res) => {
//     let { private_key, network, tokenAddress, timezone } = req.body;
//     const tz = timezone || 'UTC';

//     if (!private_key) {
//         return res.status(400).json({ valid: false, message: 'Address is required.' });
//     }

//     const axios = require('axios');
//     const TronWeb = require('tronweb');
//     const moment = require('moment');

//     // Configure TronWeb (Mainnet/Shasta Testnet)
//     const tronWeb = new TronWeb({
//         fullHost: network === '4' 
//             ? 'https://api.trongrid.io' 
//             : 'https://api.shasta.trongrid.io',
//         headers: { "TRON-PRO-API-KEY": "6e3b8180-b344-475f-b5e1-30598c59fc56" }
//     });

//     const TRON_ADDRESS = tronWeb.address.toHex(private_key);
//     const TOKEN_ADDRESS = tokenAddress ? tronWeb.address.toHex(tokenAddress) : null;

//     // Debugging function
//     const debugLog = (type, data) => {
//         console.log(`[DEBUG ${type}]`, JSON.stringify(data, null, 2));
//     };

//     const formatTransactionTime = (timestamp, tz) => {
//         try {
//             /*const date = new Date(timestamp);
//             const options = {
//                 day: '2-digit',
//                 month: '2-digit',
//                 year: 'numeric',
//                 hour: '2-digit',
//                 minute: '2-digit',
//                 second: '2-digit',
//                 hour12: true,
//                 timeZone: tz
//             };
    
//             return new Intl.DateTimeFormat('en-US', options).format(date);*/
            
//             const date = new Date(timestamp);
        
//         // Use Intl.DateTimeFormat for timezone conversion
//         const formatter = new Intl.DateTimeFormat('en-US', {
//             timeZone: tz,
//             year: 'numeric',
//             month: '2-digit',
//             day: '2-digit',
//             hour: '2-digit',
//             minute: '2-digit',
//             second: '2-digit',
//             hour12: true
//         });
        
//         // Format the date and split into parts
//         const formatted = formatter.format(date);
        
//         // Convert from MM/DD/YYYY to YYYY-MM-DD format
//         const [datePart, timePart] = formatted.split(', ');
//         const [month, day, year] = datePart.split('/');
        
//         return `${day}-${month}-${year} ${timePart}`;
        
//         } catch (e) {
//             return 'Invalid Date';
//         }
//     };

// const getTRXTransactions = async (address) => {
//     try {
//         const response = await axios.get(
//             'https://apilist.tronscanapi.com/api/transaction',
//             {
//                 params: {
//                     sort: '-timestamp',
//                     count: true,
//                     limit: 100,
//                     start: 0,
//                     address: address
//                 }
//             }
//         );

//         if (!response.data?.data || response.data.data.length === 0) {
//             return [];
//         }

//         return response.data.data.map(tx => {
//             // Initialize variables
//             let value = 0;
//             let isIncoming = false;
//             let tokenSymbol = 'TRX';
//             let tokenDecimal = 6;
//             let fromAddress = tx.ownerAddress || 'Unknown';
//             let toAddress = 'Unknown';
            
//             // Handle TRC10 tokens
//             if (tx.tokenInfo && tx.tokenInfo.tokenType === 'trc10') {
//                 tokenSymbol = tx.tokenInfo.tokenAbbr || 'TRC10';
//                 tokenDecimal = tx.tokenInfo.tokenDecimal || 6;
//             }

//             // Get the actual recipient address (handles both toAddress and toAddressList)
//             const recipientAddress = tx.toAddress || 
//                                   (tx.toAddressList && tx.toAddressList[0]) || 
//                                   (tx.contractData && tx.contractData.to_address);

//             // Determine if this is an incoming transaction
//             isIncoming = recipientAddress === address;

//             // Set value and addresses based on transaction type
//             if (tx.contractData) {
//                 value = tx.contractData.amount || tx.amount || 0;
//                 fromAddress = tx.contractData.owner_address;
//                 toAddress = tx.contractData.to_address;
//             } else {
//                 value = tx.amount || 0;
//                 fromAddress = tx.ownerAddress;
//                 toAddress = recipientAddress;
//             }

//             // Format addresses for display
//             const formatAddress = (addr) => {
//                 if (!addr || addr === 'Unknown') return 'Unknown';
//                 return addr.length > 20 ? addr.slice(0, 13) + '...' + addr.slice(-15) : addr;
//             };

//             // Only include transactions where we could determine direction and value
//             if ((fromAddress === 'Unknown' && toAddress === 'Unknown') || value <= 0) {
//                 return null;
//             }

//             return {
//                 hash: tx.hash,
//                 block: tx.block,
//                 time: formatTransactionTime(tx.timestamp, tz),
//                 time_display: formatTransactionTime(tx.timestamp, tz),
//                 value: value / Math.pow(10, tokenDecimal),
//                 from: formatAddress(fromAddress),
//                 to: formatAddress(toAddress),
//                 type: isIncoming ? 'in' : 'out',
//                 tokenSymbol: tokenSymbol,
//                 tokenName: tx.tokenInfo?.tokenName || 'Tron',
//                 tokenDecimal: tokenDecimal,
//                 status: tx.contractRet || tx.result || 'UNKNOWN',
//                 confirmed: tx.confirmed,
//                 fee: tx.fee ? tronWeb.fromSun(tx.fee) : 0,
//                 contractType: tx.contractType,
//                 riskTransaction: tx.riskTransaction || false,
//                 tokenType: tx.tokenInfo?.tokenType || 'trx',
//                 tokenInfo: tx.tokenInfo || null
//             };
//         }).filter(tx => tx !== null) // Filter out null transactions
//           .sort((a, b) => new Date(b.time) - new Date(a.time));

//     } catch (error) {
//         debugLog('TRX_ERROR', error.response?.data || error.message);
//         return [];
//     }
// };
//     // Updated TRC20 transaction fetcher with complete field mapping
//     const getTRC20Transactions = async (address, contractAddress) => {
//         try {
//             const response = await axios.get(
//                 'https://apilist.tronscanapi.com/api/filter/trc20/transfers',
//                 {
//                     params: {
//                         limit: 50,
//                         start: 0,
//                         sort: '-timestamp',
//                         count: true,
//                         filterTokenValue: 0,
//                         relatedAddress: address,
//                         contract_address: contractAddress || undefined
//                     }
//                 }
//             );

//             if (!response.data?.token_transfers || response.data.token_transfers.length === 0) {
//                 return [];
//             }

//             return response.data.token_transfers.map(tx => {
//                 const isIncoming = tx.to_address.toLowerCase() === address.toLowerCase();
//                 const decimals = tx.tokenInfo?.tokenDecimal || 6;
//                 const value = tx.quant ? parseInt(tx.quant) : parseInt(tx.value);
                
//                 return {
//                     hash: tx.transaction_id,
//                     time: formatTransactionTime(tx.block_ts, tz),
//                     time_display: formatTransactionTime(tx.block_ts, tz),
//                     value: value / Math.pow(10, decimals),
//                     from: tx.from_address ? tx.from_address.slice(0, 13) + '...' + tx.from_address.slice(-15) : 'Unknown',
//                     to: tx.to_address ? tx.to_address.slice(0, 13) + '...' + tx.to_address.slice(-15) : 'Unknown',
//                     type: isIncoming ? 'in' : 'out',
//                     status: tx.finalResult || tx.contractRet || 'SUCCESS',
//                     confirmed: tx.confirmed,
//                     block: tx.block,
//                     tokenSymbol: tx.tokenInfo?.tokenAbbr || 'TRC20',
//                     tokenName: tx.tokenInfo?.tokenName || 'Unknown Token',
//                     tokenDecimal: decimals,
//                     contractAddress: tx.contract_address || contractAddress,
//                     method: tx.trigger_info?.methodName || tx.methodName,
//                     riskTransaction: tx.riskTransaction || false
//                 };
//             }).sort((a, b) => new Date(b.time) - new Date(a.time));

//         } catch (error) {
//             debugLog('TRC20_ERROR', error.response?.data || error.message);
//             return [];
//         }
//     };

//     try {
//         const isTRX = !tokenAddress || tokenAddress === private_key;
//         let result;

//         if (isTRX) {
//             let balance = 0;
//             let transactions = [];

//             try {
//                 balance = await tronWeb.trx.getBalance(private_key);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Balance:', e.message);
//             }

//             try {
//                 transactions = await getTRXTransactions(private_key);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRX Transactions:', e.message);
//             }

//             result = {
//                 address: private_key,
//                 balance: tronWeb.fromSun(balance),
//                 transactions: {
//                     all: transactions,
//                     incoming: transactions.filter(tx => tx.type === 'in'),
//                     outgoing: transactions.filter(tx => tx.type === 'out')
//                 },
//                 token: {
//                     symbol: 'TRX',
//                     name: 'Tron',
//                     decimals: 6
//                 }
//             };

//         } else {
//             let contract = null;
//             let transactions = [];

//             try {
//                 contract = await tronWeb.contract().at(tokenAddress);
//             } catch (e) {
//                 console.error('ERROR: Getting contract instance:', e.message);
//             }

//             try {
//                 transactions = await getTRC20Transactions(private_key, tokenAddress);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Transactions:', e.message);
//             }

//             let tokenBalance = 0;
//             try {
//                 const balance = await contract.methods.balanceOf(private_key).call();
//                 const decimals = await contract.methods.decimals().call().catch(() => 6);
//                 tokenBalance = balance / Math.pow(10, decimals);
//             } catch (e) {
//                 console.error('ERROR: Fetching TRC20 Balance:', e.message);
//             }

//             let tokenInfo = { symbol: 'TOKEN', name: 'Token', decimals: 6 };
//             try {
//                 const [symbol, name, decimals] = await Promise.all([
//                     contract.methods.symbol().call().catch(() => 'TOKEN'),
//                     contract.methods.name().call().catch(() => 'Token'),
//                     contract.methods.decimals().call().catch(() => 6)
//                 ]);
//                 tokenInfo = { symbol, name, decimals };
//             } catch (e) {
//                 console.error('ERROR: Fetching Token Info:', e.message);
//             }

//             result = {
//                 address: private_key,
//                 balance: tokenBalance,
//                 transactions: {
//                     all: transactions,
//                     incoming: transactions.filter(tx => tx.type === 'in'),
//                     outgoing: transactions.filter(tx => tx.type === 'out')
//                 },
//                 token: {
//                     ...tokenInfo,
//                     contractAddress: tokenAddress
//                 }
//             };
//         }

//         console.log('FINAL_RESULT:', JSON.stringify(result, null, 2));
//         res.json({ valid: true, message: result });

//     } catch (error) {
//         console.error('MAIN_ERROR:', error);
//         res.status(500).json({ 
//             valid: false, 
//             message: `Fatal error: ${error.message}`,
//             error: error.message,
//             stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
//         });
//     }
// });






app.post('/wallet/sendbtc_network/', async (req, res) => {
    let { private_key, network, tokenAddress } = req.body;

    if (!private_key || !tokenAddress) {
        return res.status(400).json({ valid: false, message: 'Both address and token address are required.' });
    }

    const BTC_ADDRESS = private_key;
    const USDT_ADDRESS = tokenAddress;
    const axios = require('axios');

    try {
        const [btcResponse, priceResponse, txsResponse] = await Promise.all([
            axios.get(`https://blockchain.info/balance?active=${BTC_ADDRESS}`),
            axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,tether&vs_currencies=usd'),
            axios.get(`https://blockchain.info/rawaddr/${BTC_ADDRESS}?limit=10`)
        ]);

        const btcPrice = priceResponse.data.bitcoin.usd;
        const usdtPrice = priceResponse.data.tether.usd;

        const result = {
            btc: {
                balance: btcResponse.data[BTC_ADDRESS].final_balance / 100000000,
                balanceInUSD: (btcResponse.data[BTC_ADDRESS].final_balance / 100000000) * btcPrice,
                transactions: []
            }
        };

        // Process transactions to include from/to addresses
        const transactions = txsResponse.data.txs.map(tx => {
            // Extract input addresses (senders)
            const from_addresses = tx.inputs
                .filter(input => input.prev_out && input.prev_out.addr)
                .map(input => input.prev_out.addr);

            // Extract output addresses (receivers)
            const to_addresses = tx.out
                .filter(output => output.addr)
                .map(output => output.addr);

            // Determine if the transaction was incoming or outgoing
            const isIncoming = to_addresses.includes(BTC_ADDRESS);
            const type = isIncoming ? 'in' : 'out';

            return {
                hash: tx.hash,
                time: tx.time,
                value: Math.abs(tx.result) / 100000000, // Absolute value
                type: type,
                from: [...new Set(from_addresses)], // Remove duplicates
                to: [...new Set(to_addresses)], // Remove duplicates
                fee: tx.fee / 100000000
            };
        });

        result.btc.transactions = transactions;

        res.json({
            valid: true,
            message: {
                Balance: `${result.btc.balance.toFixed(8)} BTC`,
                BalanceInUSD: `${result.btc.balanceInUSD.toFixed(2)} USD`,
                NetworkFee: "0.0000013 BTC",
                MaxFee: "0.00001 BTC",
                transactions: 
                {
                    all:result.btc.transactions
                }
            }
        });

    } catch (error) {
        res.status(500).json({ 
            valid: false, 
            message: error.message,
            details: error.response?.data || "Internal server error"
        });
    }
});

app.post('/wallet/sendtron_network/', async (req, res) => {
    let { private_key, network, tokenAddress } = req.body;

    if (!private_key || !tokenAddress) {
        return res.status(400).json({ valid: false, message: 'Both address and token address are required.' });
    }
    const axios = require('axios');

    
    const BTC_ADDRESS = private_key;
    const USDT_ADDRESS = tokenAddress;
    
    async function getBalancesAndTransactions() {
    try {
        // Get all data in parallel
        const [btcResponse, priceResponse, txsResponse] = await Promise.all([
            axios.get(`https://blockchain.info/balance?active=${BTC_ADDRESS}`),
            axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,tether&vs_currencies=usd'),
            axios.get(`https://blockchain.info/rawaddr/${BTC_ADDRESS}?limit=10`)
        ]);

        // Process price data
        const btcPrice = priceResponse.data.bitcoin.usd;
        const usdtPrice = priceResponse.data.tether.usd;

        // Initialize result objects
        const result = {
            btc: {
                balance: 0,
                balanceInUSD: 0,
                transactions: {
                    all: [],
                    incoming: [],
                    outgoing: []
                }
            },
            usdt: {
                balance: 0,
                balanceInUSD: 0,
                transactions: {
                    all: [],
                    incoming: [],
                    outgoing: []
                }
            }
        };

        // Process BTC data
        if (BTC_ADDRESS == USDT_ADDRESS) {
            result.btc.balance = btcResponse.data[BTC_ADDRESS].final_balance / 100000000;
            result.btc.balanceInUSD = result.btc.balance * btcPrice;

            const allTransactions = txsResponse.data.txs;
            
            result.btc.transactions.all = allTransactions.map(tx => ({
                
                to_address: tx.out[0].addr,
                hash: tx.hash,
                time: tx.time,
                value: tx.result / 100000000,
                type: tx.result > 0 ? 'in' : 'out'
            }));

            result.btc.transactions.incoming = result.btc.transactions.all.filter(tx => tx.type === 'in');
            result.btc.transactions.outgoing = result.btc.transactions.all.filter(tx => tx.type === 'out');

            return {
               
                    Balance: parseFloat(result.btc.balance).toFixed(8)+' BTC',
                    BalanceInUSD: parseFloat(result.btc.balanceInUSD).toFixed(2)+' USD',
                     NetworkFee: "0.0000013 BTC",
                    MaxFee:"0.0000019 BTC",
                    transactions: {
                        all: result.btc.transactions.all
                        //incoming: result.btc.transactions.incoming,
                        //outgoing: result.btc.transactions.outgoing
                    }
                
            };
        }

        // Process USDT data (placeholder - would need proper Omni API)
        if (BTC_ADDRESS != USDT_ADDRESS) {
            // Note: Currently using same transactions as BTC which is incorrect
            // USDT would need separate API calls to get Omni layer transactions
            result.usdt.balance = 0; // Placeholder - would need Omni API
            result.usdt.balanceInUSD = result.usdt.balance * usdtPrice;
            
            // USDT transactions would need to be fetched separately
            // Currently using empty arrays as initialized

            return {
               
                    Balance: parseFloat(result.usdt.balance).toFixed(2)+' USDT',
                    BalanceInUSD: parseFloat(result.usdt.balanceInUSD).toFixed(2)+' USD',
                    NetworkFee: "0.0000013 BTC",
                    MaxFee:"0.0000019 BTC",
                    transactions: {
                        all: result.usdt.transactions.all,
                        //incoming: result.usdt.transactions.incoming,
                        //outgoing: result.usdt.transactions.outgoing
                    }
                
            };
        }

    } catch (error) {
       // console.error('Error:', error.message);
        return {
            error: error.message,
            details: error.response?.data || error.message
        };
    }
}

// Usage
getBalancesAndTransactions().then(result => {
    if (result.error) {
        res.status(500).json({ valid: false, message: result.error });
    } else {
        res.json({
                valid: true,
                message:result
            });
    }
    
    });

    
});



app.post('/wallet/sendtron_network/', async (req, res) => {
    const { private_key, tokenAddress } = req.body;

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'TRON address is required.' });
    }
   const axios = require('axios');
   const TronWeb = require('tronweb');

    const TRON_ADDRESS = private_key;
    const TRON_API = 'https://api.trongrid.io';
    const tronWeb = new TronWeb({ fullHost: TRON_API });

    try {
        // Fetch TRX balance
        const trxBalance = await tronWeb.trx.getBalance(TRON_ADDRESS);
        const trxInSun = tronWeb.fromSun(trxBalance);

        // Fetch transactions (last 10)
        const transactions = await axios.get(`${TRON_API}/v1/accounts/${TRON_ADDRESS}/transactions?limit=10`);

        // Fetch TRX price (USD)
        const priceResponse = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=tron&vs_currencies=usd');
        const trxPrice = priceResponse.data.tron.usd;

        // Process transactions
        const formattedTxs = transactions.data.data.map(tx => ({
            hash: tx.txID,
            from: tx.raw_data.contract[0].parameter.value.owner_address || 'unknown',
            to: tx.raw_data.contract[0].parameter.value.to_address || 'unknown',
            value: tx.raw_data.contract[0].parameter.value.amount ? tronWeb.fromSun(tx.raw_data.contract[0].parameter.value.amount) : 0,
            fee: tx.ret[0].fee ? tronWeb.fromSun(tx.ret[0].fee) : 0,
            timestamp: tx.raw_data.timestamp,
            type: tx.raw_data.contract[0].type === 'TransferContract' ? 'TRX' : 'Token'
        }));

        res.json({
            valid: true,
            message: {
                Balance: `${trxInSun} TRX`,
                BalanceInUSD: `${(trxInSun * trxPrice).toFixed(2)} USD`,
                NetworkFee: "1-5 TRX (dynamic)",
                transactions: {
                    
                    all :formattedTxs
                }
            }
        });

    } catch (error) {
        res.status(500).json({ valid: false, message: error.message });
    }
});

app.post('/wallet/sendsol_network/', async (req, res) => {
    const { Connection, PublicKey } = require('@solana/web3.js');
    const { private_key } = req.body;

    if (!private_key) {
        return res.status(400).json({ valid: false, message: 'Solana address is required.' });
    }

    // 1. Validate Solana address format
    let publicKey;
    try {
        publicKey = new PublicKey(private_key);
    } catch (err) {
        return res.status(400).json({ valid: false, message: "Invalid Solana address" });
    }

    // 2. Use a reliable RPC
    const SOLANA_RPC = 'https://api.mainnet-beta.solana.com'; // Replace with private RPC if needed
    const connection = new Connection(SOLANA_RPC, 'confirmed');

    try {
        // 3. Fetch balance (lamports → SOL)
        const solBalance = await connection.getBalance(publicKey);
        const solInSOL = solBalance / 1e9;

        // 4. Fetch recent transactions (modern method)
        const signatures = await connection.getSignaturesForAddress(publicKey, { limit: 5 });
        const txs = await Promise.all(
            signatures.map(sig => connection.getTransaction(sig.signature))
        );

        // 5. Format transactions
        const formattedTxs = txs.map(tx => {
            if (!tx) return null;
            return {
                hash: tx.transaction.signatures[0],
                from: tx.transaction.message.accountKeys[0]?.toString(),
                to: tx.transaction.message.accountKeys[1]?.toString(),
                value: tx.meta?.postBalances[1] ? (tx.meta.postBalances[1] - tx.meta.preBalances[1]) / 1e9 : 0,
                fee: tx.meta?.fee ? tx.meta.fee / 1e9 : 0,
                timestamp: tx.blockTime,
            };
        }).filter(tx => tx !== null);

        // 6. Get SOL price (USD)
        const priceResponse = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd');
        const solPrice = priceResponse.data.solana.usd;

        res.json({
            valid: true,
            message: {
                address: publicKey.toString(),
                balance: `${solInSOL.toFixed(6)} SOL`,
                balanceUSD: `$${(solInSOL * solPrice).toFixed(2)}`,
                transactions: formattedTxs,
            }
        });

    } catch (err) {
        res.status(500).json({ 
            valid: false, 
            message: "Solana RPC Error",
            error: err.message 
        });
    }
});

//tron wallet
app.post('/wallet/tron_assets/', async (req, res) => {
let { private_key, network} = req.body;
  const axios = require('axios');
const TronWeb = require('tronweb');

// Configure TronWeb
const tronWeb = new TronWeb({
    fullHost: 'https://api.trongrid.io'
});

const TRON_ADDRESS = private_key; // Example: 'TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL'
const USDT_TRON_CONTRACT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; // USDT contract on TRON

async function getTronBalances() {
    try {
        // Get current prices
        const priceResponse = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=tron,tether&vs_currencies=usd');
        const trxPrice = priceResponse.data.tron.usd;
        const usdtPrice = priceResponse.data.tether.usd;

        // Get TRX balance
        const trxBalance = await tronWeb.trx.getBalance(TRON_ADDRESS);
        const trxValue = trxBalance / 1000000 * trxPrice;

        // Get USDT-TRON balance
        const contract = await tronWeb.contract().at(USDT_TRON_CONTRACT);
        //const usdtBalance = await contract.balanceOf(TRON_ADDRESS).call();
        const usdtBalance =0;
        const usdtValue = usdtBalance / 1000000 * usdtPrice;

        return {
            ethBalance: trxBalance / 1000000,
            ethBalanceInUSD: trxValue,
            tokenBalances: [
                {
                    tokenName: "TRX",
                    tokenAddress: TRON_ADDRESS,
                    balance: trxBalance / 1000000, // Convert from sun to TRX
                    balanceInUSD: trxValue,
                    tokenPrice: trxPrice,
                    tokenImage: "https://cryptologos.cc/logos/tron-trx-logo.png"
                },
                {
                    tokenName: "USDT",
                    tokenAddress: USDT_TRON_CONTRACT,
                    balance: usdtBalance / 1000000, // USDT has 6 decimals
                    balanceInUSD: usdtValue,
                    tokenPrice: usdtPrice,
                    tokenImage: "https://cryptologos.cc/logos/tether-usdt-logo.png"
                }
            ]
        };
    } catch (error) {
        console.error('Error:', error.message);
        return {
            error: error.message,
            details: error.response?.data || error.message
        };
    }
}

// Usage
getTronBalances().then(result => {
    if (result.error) 
    {
            res.status(500).json({ valid: false, message: result.error });
    } 
    else 
    {
        res.json({
                valid: true,
                message:result
            });
            
            
    }
});
    
});

// sol wallet

app.post('/wallet/sol_assets/', async (req, res) => {
let { private_key, network} = req.body;
const axios = require('axios');
const { Connection, PublicKey } = require('@solana/web3.js');

// Configure Solana connection
const connection = new Connection('https://api.mainnet-beta.solana.com');
const SOL_ADDRESS = private_key; // Example: '9gHXZv9Hdu6Pm2QZ1kLq6JY8t7Rv5J2R9X6kzKX7sN4q'
const USDT_SOLANA_MINT = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'; // USDT mint address on Solana

async function getSolanaBalances() {
    try {
        // Get current prices
        const priceResponse = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=solana,tether&vs_currencies=usd');
        const solPrice = priceResponse.data.solana.usd;
        const usdtPrice = priceResponse.data.tether.usd;

        // Get SOL balance
        const solBalance = await connection.getBalance(new PublicKey(SOL_ADDRESS));
        const solValue = solBalance / 1000000000 * solPrice; // Convert lamports to SOL (9 decimals)

        // Get USDT-SPL balance
        const tokenAccounts = await connection.getTokenAccountsByOwner(
            new PublicKey(SOL_ADDRESS),
            { mint: new PublicKey(USDT_SOLANA_MINT) }
        );

        let usdtBalance = 0;
        if (tokenAccounts.value.length > 0) {
            const accountInfo = await connection.getTokenAccountBalance(tokenAccounts.value[0].pubkey);
            usdtBalance = accountInfo.value.uiAmount || 0;
        }
        const usdtValue = usdtBalance * usdtPrice;

        return {
            ethBalance: solBalance / 1000000000,
            ethBalanceInUSD: solValue,
            tokenBalances: [
                {
                    tokenName: "SOL",
                    tokenAddress: SOL_ADDRESS,
                    balance: solBalance / 1000000000, // Convert lamports to SOL
                    balanceInUSD: solValue,
                    tokenPrice: solPrice,
                    tokenImage: "https://cryptologos.cc/logos/solana-sol-logo.png"
                },
                {
                    tokenName: "USDT",
                    tokenAddress: USDT_SOLANA_MINT,
                    balance: usdtBalance,
                    balanceInUSD: usdtValue,
                    tokenPrice: usdtPrice,
                    tokenImage: "https://cryptologos.cc/logos/tether-usdt-logo.png"
                }
            ]
        };
    } catch (error) {
        console.error('Error:', error.message);
        return {
            error: 'Failed to fetch Solana balances',
            details: error.response?.data || error.message
        };
    }
}

// Usage
getSolanaBalances().then(result => {
     if (result.error) 
    {
            res.status(500).json({ valid: false, message: result.error });
    } 
    else 
    {
        res.json({
                valid: true,
                message:result
            });
            
            
    }
});
    

});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});