const ethers = require('ethers');

// Ethereum network configuration
// const provider = new ethers.getDefaultProvider('https://mainnet.infura.io/v3/<TRUFFLEHOG_REDACTED_INFURA>');
const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8545/');

const privateKey = 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';

// Uniswap V3 contract configuration
const uniswapV3ContractAddress = '0x1F98431c8aD98523631AE4a59f267346ea31F984';
const uniswapV3ContractABI = require('./abi.json');

// Token configuration
const tokenToSwapAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
const tokenToReceiveAddress = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984';
const tokenToSwapAmount = ethers.parseUnits('0.001', 'ether');

// Connect to wallet
const wallet = new ethers.Wallet(privateKey, provider);

// Load the Uniswap V3 contract
const uniswapV3Contract = new ethers.Contract(uniswapV3ContractAddress, uniswapV3ContractABI, wallet);

async function executeTrade() {
  // Approve Uniswap V3 to spend tokenToSwap
  const tokenToSwapContract = new ethers.Contract(tokenToSwapAddress, uniswapV3ContractABI, wallet);
  const approvalTx = await tokenToSwapContract.approve(uniswapV3ContractAddress, tokenToSwapAmount);
  await approvalTx.wait();

  // Prepare swap transaction
  const swapTx = await uniswapV3Contract.swap(
    tokenToSwapAddress,
    tokenToReceiveAddress,
    tokenToSwapAmount,
    0, // slippage tolerance (0 means no tolerance)
    ethers.MaxUint256, // deadline (set to maximum value)
    wallet.address, // recipient address
    0 // fee recipient (use zero address for default)
  );

  console.log('Swap transaction hash:', swapTx.hash);

  // Wait for transaction confirmation
  await swapTx.wait();
  console.log('Swap transaction confirmed!');
}

executeTrade().catch((error) => {
  console.error('Error executing trade:', error);
});
PS C:\Users\lidor\Desktop\Trade Bot> node index.js
Error executing trade: Error: insufficient funds for intrinsic transaction cost (transaction="0x02f8b2018201d8843b9aca00850f200002a882b3e494c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280b844095ea7b30000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98400000000000000000000000000000000000000000000000000038d7ea4c68000c001a0e12053e6d48e6d2b6f58db2a8b35bb3dc609ca0f4dfff74a4b41c8f53690d5dca07df5f64242fdf382aa0aa13e2571a10a13a519bf51e358903352cd6706157486", info={ "error": { "code": -32000, "message": "insufficient funds for gas * price + value" } }, code=INSUFFICIENT_FUNDS, version=6.4.1)
    at makeError (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\utils\errors.js:125:21)
    at JsonRpcProvider.getRpcError (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\providers\provider-jsonrpc.js:616:49)   
    at C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\providers\provider-jsonrpc.js:257:52
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'INSUFFICIENT_FUNDS',
98431c8ad98523631ae4a59f267346ea31f98400000000000000000000000000000000000000000000000000038d7ea4c68000c001a0e12053e6d48e6d2b6f58db2a8b35bb3dc609ca0f4dfff74a4b41c8f53690d5dca07df5f64242fdf382aa0aa13e2571a10a13a519bf51e358903352cd6706157486',
  info: {
    error: {
      code: -32000,
      message: 'insufficient funds for gas * price + value'
    }
  }
}
PS C:\Users\lidor\Desktop\Trade Bot> node index.js
Error executing trade: TypeError: no matching function (argument="key", value="swap", code=INVALID_ARGUMENT, version=6.4.1)
    at makeError (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\utils\errors.js:118:21)
    at assert (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\utils\errors.js:142:15)
    at assertArgument (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\utils\errors.js:154:5)
    at Interface.getFunctionName (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\abi\interface.js:433:39)
    at buildWrappedMethod (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\contract\contract.js:240:34)
    at Contract.getFunction (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\contract\contract.js:688:22)
    at Object.get (C:\Users\lidor\Desktop\Trade Bot\node_modules\ethers\lib.commonjs\contract\contract.js:598:39)
    at executeTrade (C:\Users\lidor\Desktop\Trade Bot\index.js:31:42)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'INVALID_ARGUMENT',
  argument: 'key',
  value: 'swap'
}