const { Web3 } = require("web3");

// Initialize Web3 instance using a provider
const web3 = new Web3(
  new Web3.providers.HttpProvider("YOUR_CHAINSTACK_RPC_NODE")
);

/**
 * Sends the entire balance from a given account to another.
 *
 * @param {string} secretKey The private key of the sender's account.
 * @param {string} to The recipient address.
 */
async function sendEntireBalance(secretKey, to) {
  const account = web3.eth.accounts.privateKeyToAccount(secretKey);
  web3.eth.accounts.wallet.add(account);
  const senderAddress = account.address;

  console.log(
    `Attempting to send entire balance from ${senderAddress} to ${to}`
  );

  const MAX_RETRIES = 3; // Maximum number of retries
  const COOLDOWN = 5000; // Time waited between retries in ms
  let retries = 0; // Initialize retry counter

  async function sendTransaction() {
    try {
      const balance = await web3.eth.getBalance(senderAddress);
      console.log(
        `Current balance: ${web3.utils.fromWei(balance, "ether")} ETH`
      );

      const gasPrice = await web3.eth.getGasPrice();
      console.log(
        `Current gas price: ${web3.utils.fromWei(gasPrice, "gwei")} Gwei`
      );

      const gasLimit = await web3.eth.estimateGas({
        from: senderAddress,
        to: to,
      });
      console.log(`Estimated gas limit: ${gasLimit}`);

      const gasCost = BigInt(gasPrice) * BigInt(gasLimit);
      console.log(
        `Estimated gas cost: ${web3.utils.fromWei(
          gasCost.toString(),
          "ether"
        )} ETH`
      );

      const amountToSend = BigInt(balance) - gasCost;
      if (amountToSend > 0) {
        console.log(
          `Amount to send after deducting gas cost: ${web3.utils.fromWei(
            amountToSend.toString(),
            "ether"
          )} ETH`
        );

        const transaction = {
          to: to,
          value: amountToSend.toString(),
          gas: gasLimit,
          gasPrice: gasPrice,
          nonce: await web3.eth.getTransactionCount(senderAddress, "latest"),
        };

        console.log("Signing transaction...");
        const signedTx = await account.signTransaction(transaction);
        console.log("Transaction signed. Sending...");

        const receipt = await web3.eth.sendSignedTransaction(
          signedTx.rawTransaction
        );
        console.log(
          `Transaction successful with hash: ${receipt.transactionHash}`
        );
        console.log(
          `Find the transaction in the explorer: https://sepolia.etherscan.io/tx/${receipt.transactionHash}`
        );
      } else {
        console.log(
          "Not enough balance to cover the gas cost. Transaction aborted."
        );
      }
    } catch (error) {
      console.error(`Failed to send transaction: ${error.message}`);
      if (retries < MAX_RETRIES) {
        retries++;
        console.log(`Retrying... (${retries}/${MAX_RETRIES})`);
        await new Promise((resolve) => setTimeout(resolve, COOLDOWN)); // Wait for 5 seconds before retrying
        await sendTransaction(); // Retry the transaction
      } else {
        console.error("Maximum retries reached. Giving up.");
      }
    }
  }

  await sendTransaction();
}

// Replace with your secret key and recipient address
const secretKey = "0x_YOUR_PRIVATE_KEY";
const recipientAddress = "DESTINATION_ADDRESS";

sendEntireBalance(secretKey, recipientAddress);
Attempting to send entire balance from 0x8f8e7012F8F974707A8F11C7cfFC5d45EfF5c2Ae to 0xf25DADF841518A2cb516307876CE44F416661085
Current balance: 24.4635 ETH
Current gas price: 10.975813013 Gwei
Estimated gas limit: 21000
Estimated gas cost: 0.000230492073273 ETH
Amount to send after deducting gas cost: 24.463269507926727 ETH
Signing transaction...
Transaction signed. Sending...
Transaction successful with hash: 0xa88b579b2468d695a1f0b6af505a1be8a190d9982a33cae45593a832e7b08c77
Find the transaction in the explorer: https://sepolia.etherscan.io/tx/0xa88b579b2468d695a1f0b6af505a1be8a190d9982a33cae45593a832e7b08c77
const { Web3 } = require("web3");

// Initialize Web3 instance using a provider
const web3 = new Web3(
  new Web3.providers.HttpProvider("YOUR_CHAINSTACK_RPC_NODE")
);

/**
 * Sends the entire balance from a given account to another.
 *
 * @param {string} secretKey The private key of the sender's account.
 * @param {string} to The recipient address.
 */
async function sendEntireBalance(secretKey, to) {
  const account = web3.eth.accounts.privateKeyToAccount(secretKey);
  web3.eth.accounts.wallet.add(account);
  const senderAddress = account.address;

  console.log(
    `Attempting to send entire balance from ${senderAddress} to ${to}`
  );

  const MAX_RETRIES = 3; // Maximum number of retries
  const COOLDOWN = 5000; // Time waited between retries in ms
  let retries = 0; // Initialize retry counter

  async function sendTransaction() {
    try {
      const balance = await web3.eth.getBalance(senderAddress);
      console.log(
        `Current balance: ${web3.utils.fromWei(balance, "ether")} ETH`
      );

      const gasPrice = await web3.eth.getGasPrice();
      console.log(
        `Current gas price: ${web3.utils.fromWei(gasPrice, "gwei")} Gwei`
      );

      const gasLimit = await web3.eth.estimateGas({
        from: senderAddress,
        to: to,
      });
      console.log(`Estimated gas limit: ${gasLimit}`);

      const gasCost = BigInt(gasPrice) * BigInt(gasLimit);
      console.log(
        `Estimated gas cost: ${web3.utils.fromWei(
          gasCost.toString(),
          "ether"
        )} ETH`
      );

      const amountToSend = BigInt(balance) - gasCost;
      if (amountToSend > 0) {
        console.log(
          `Amount to send after deducting gas cost: ${web3.utils.fromWei(
            amountToSend.toString(),
            "ether"
          )} ETH`
        );

        const transaction = {
          to: to,
          value: amountToSend.toString(),
          gas: gasLimit,
          gasPrice: gasPrice,
          nonce: await web3.eth.getTransactionCount(senderAddress, "latest"),
        };

        console.log("Signing transaction...");
        const signedTx = await account.signTransaction(transaction);
        console.log("Transaction signed. Sending...");

        const receipt = await web3.eth.sendSignedTransaction(
          signedTx.rawTransaction
        );
        console.log(
          `Transaction successful with hash: ${receipt.transactionHash}`
        );
        console.log(
          `Find the transaction in the explorer: https://sepolia.etherscan.io/tx/${receipt.transactionHash}`
        );
      } else {
        console.log(
          "Not enough balance to cover the gas cost. Transaction aborted."
        );
      }
    } catch (error) {
      console.error(`Failed to send transaction: ${error.message}`);
      if (retries < MAX_RETRIES) {
        retries++;
        console.log(`Retrying... (${retries}/${MAX_RETRIES})`);
        await new Promise((resolve) => setTimeout(resolve, COOLDOWN)); // Wait for 5 seconds before retrying
        await sendTransaction(); // Retry the transaction
      } else {
        console.error("Maximum retries reached. Giving up.");
      }
    }
  }

  await sendTransaction();
}

// Replace with your secret key and recipient address
const secretKey = "0x_YOUR_PRIVATE_KEY";
const recipientAddress = "DESTINATION_ADDRESS";

sendEntireBalance(secretKey, recipientAddress);
Attempting to send entire balance from 0x8f8e7012F8F974707A8F11C7cfFC5d45EfF5c2Ae to 0xf25DADF841518A2cb516307876CE44F416661085
Current balance: 24.4635 ETH
Current gas price: 10.975813013 Gwei
Estimated gas limit: 21000
Estimated gas cost: 0.000230492073273 ETH
Amount to send after deducting gas cost: 24.463269507926727 ETH
Signing transaction...
Transaction signed. Sending...
Transaction successful with hash: 0xa88b579b2468d695a1f0b6af505a1be8a190d9982a33cae45593a832e7b08c77
Find the transaction in the explorer: https://sepolia.etherscan.io/tx/0xa88b579b2468d695a1f0b6af505a1be8a190d9982a33cae45593a832e7b08c77