i have this script that is essentially supposed to trade between token0 and token1 , can you fix all the flaws or missing functions or messed functions, following the uniswap v3 sdk newest version, const { ethers } = require('ethers');
const { Token, Percent, TradeType } = require('@uniswap/sdk-core');
const { Route, Trade, computePoolAddress } = require('@uniswap/v3-sdk');
const { abi: IUniswapV3PoolABI } = require('@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json');
const Quoter = require('@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json');

const SWAP_ROUTER_ADDRESS = `0xE592427A0AEce92De3Edee1F18E0157C05861564`;
const WALLET_ADDRESS = `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266`;
const WALLET_SECRET = `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`;
const INFURA_TEST_URL = `https://mainnet.infura.io/v3/<TRUFFLEHOG_REDACTED_INFURA>`;
const POOL_FACTORY_CONTRACT_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984';
const provider = new ethers.providers.JsonRpcProvider(INFURA_TEST_URL);

const chainId = 1;

const token0 = new Token(chainId, `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`, 18, `WETH`, `Wrapped Ether`);
const token1 = new Token(chainId, `0x1f9840a85d5af5bf1d1762f925bdaddc4201f984`, 18, `UNI`, `Uniswap Token`);

const fee = 3000; // Change the fee tier as required (500 for low, 3000 for medium, and 10000 for high)

async function getPoolInfo(tokenIn, tokenOut, fees) {
  const currentPoolAddress = computePoolAddress({
    factoryAddress: POOL_FACTORY_CONTRACT_ADDRESS,
    tokenA: tokenIn,
    tokenB: tokenOut,
    fee: fees,
  });

  const poolContract = new ethers.Contract(currentPoolAddress, IUniswapV3PoolABI.abi, provider);

  const [token0, token1, fee, tickSpacing, liquidity, slot0] = await Promise.all([
    poolContract.token0(),
    poolContract.token1(),
    poolContract.fee(),
    poolContract.tickSpacing(),
    poolContract.liquidity(),
    poolContract.slot0(),
  ]);

  return {
    token0,
    token1,
    fee,
    tickSpacing,
    liquidity,
    sqrtPriceX96: slot0[0],
    tick: slot0[1],
  };
}

async function getOutputQuote(tokenIn, tokenOut, fees) {
  const quoterContract = new ethers.Contract(QUOTER_CONTRACT_ADDRESS, Quoter.abi, provider);
  const quotedAmountOut = await quoterContract.quoteExactInputSingle(tokenIn, tokenOut, fees, fromReadableAmount('0.001', 18).toString(), 0);

  const quoteCallReturnData = await quoterContract.callStatic.quoteExactInputSingle(tokenIn, tokenOut, fees, fromReadableAmount('0.001', 18).toString(), 0);

  return ethers.utils.defaultAbiCoder.decode(['uint256'], quoteCallReturnData);
}

function fromReadableAmount(amount, decimals) {
  const value = ethers.utils.parseUnits(amount, decimals);
  return value.toString();
}

async function getTokenTransferApproval(tokenAddress) {
  const tokenContract = new ethers.Contract(tokenAddress, Token.abi, provider);
  const spender = SWAP_ROUTER_ADDRESS;
  const approvalAmount = ethers.constants.MaxUint256;

  // Approve the spender (swap router) to spend the tokens on behalf of the user
  const approvalTx = await tokenContract.approve(spender, approvalAmount);

  // Wait for the approval transaction to be mined
  const approvalReceipt = await approvalTx.wait();

  // Check if the approval transaction was successful
  if (approvalReceipt.status !== 1) {
    throw new Error('Token transfer approval failed');
  }

  // Return the approval transaction hash or any other relevant information
  return approvalReceipt.transactionHash;
}

async function sendTransaction(tx) {
  // Sign the transaction with the wallet's private key
  const wallet = new ethers.Wallet(WALLET_SECRET, provider);
  const signedTx = await wallet.signTransaction(tx);

  // Send the signed transaction
  const txResponse = await provider.sendTransaction(signedTx);

  // Wait for the transaction to be mined
  const txReceipt = await txResponse.wait();

  // Check if the transaction was successful
  if (txReceipt.status !== 1) {
    throw new Error('Transaction failed');
  }

  // Return the transaction hash or any other relevant information
  return txReceipt.transactionHash;
}

async function mainA(tokenIn, tokenOut, fees) {
  const poolInfo = await getPoolInfo(tokenIn, tokenOut, fees);

  const pool = new Pool(tokenIn, tokenOut, fees, poolInfo.sqrtPriceX96.toString(), poolInfo.liquidity.toString(), poolInfo.tick);

  const swapRoute = new Route([pool], tokenIn, tokenOut);
  const amountOut = await getOutputQuote(swapRoute, tokenIn, tokenOut, fees);

  const uncheckedTrade = Trade.createUncheckedTrade({
    route: swapRoute,
    inputAmount: CurrencyAmount.fromRawAmount(tokenIn, fromReadableAmount('0.001', 18).toString()),
    outputAmount: CurrencyAmount.fromRawAmount(tokenOut, JSBI.BigInt(amountOut)),
    tradeType: TradeType.EXACT_INPUT,
  });

  const tokenApproval = await getTokenTransferApproval(tokenIn);

  const options = {
    slippageTolerance: new Percent(50, 10_000), // 50 bips, or 0.50%
    deadline: Math.floor(Date.now() / 1000) + 60 * 20, // 20 minutes from the current Unix time
    recipient: WALLET_ADDRESS,
  };

  const methodParameters = SwapRouter.swapCallParameters([uncheckedTrade], options);

  const tx = {
    data: methodParameters.calldata,
    to: SWAP_ROUTER_ADDRESS,
    value: methodParameters.value,
    from: WALLET_ADDRESS,
    maxFeePerGas: MAX_FEE_PER_GAS,
    maxPriorityFeePerGas: MAX_PRIORITY_FEE_PER_GAS,
  };

  const res = await sendTransaction(tx);
  console.log(res);
}

mainA(token0, token1, 300);