Untitled

 avatar
Mike112
typescript
a year ago
3.5 kB
5
Indexable
Never
import { ethers } from "ethers";
import { Provider } from "zksync-web3";

// Providers for each chains

const zkSyncProvider = new Provider('https://mainnet.era.zksync.io');
const zkEvmProvider = new ethers.providers.JsonRpcProvider('https://zkevm-rpc.com');
const lineaProvider = new ethers.providers.JsonRpcProvider('https://rpc.linea.build');

// ABI for ERC20
const erc20ABI = [
    {
        "constant": false,
        "inputs": [
            { "name": "_spender", "type": "address" },
            { "name": "_value", "type": "uint256" }
        ],
        "name": "approve",
        "outputs": [{ "name": "", "type": "bool" }],
        "type": "function"
    }
];

// ABI for PancakeSwap Router
const routerABI = [
    'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] path, address to, uint deadline) external returns (uint[] amounts)',
];

// Router Address

const zkSyncRouter = "0x5aEaF2883FBf30f3D62471154eDa3C0c1b05942d";
const zkEvmRouter = "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb";
const lineaRouter = "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb";

// Wrapped ETH Addresses for each chains

const zkSyncWETH = "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91";
const zkEvmWETH = "0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9";
const lineaWETH = "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f";

// Swap Function

async function swapTokens(
    chain: string,
    privateKey: string,
    fromToken: string,
    toToken: string,
    amount: string,
    recipient: string
): Promise<ethers.providers.TransactionReceipt> {

    let provider: ethers.providers.JsonRpcProvider;
    let wethAddress: string;
    let routerAddress: string;
    let bestRoute: Array<string>;

    switch (chain) {
        case 'zkEvm':
            provider = zkEvmProvider;
            wethAddress = zkEvmWETH;
            routerAddress = zkEvmRouter;
            break;
        case 'zkSync':
            provider = zkSyncProvider;
            wethAddress = zkSyncWETH;
            routerAddress = zkSyncRouter;
            break;
        case 'linea':
            provider = lineaProvider;
            wethAddress = lineaWETH;
            routerAddress = lineaRouter;
            break;
        default:
            throw new Error('Unsupported Network');
    }

    const signer = new ethers.Wallet(privateKey, provider);

    // Get the best route from PancakeSwap API
    if(fromToken == wethAddress || toToken == wethAddress) {
        bestRoute = [fromToken, toToken];
    } else {
        bestRoute = [fromToken, wethAddress, toToken];
    }

    // Approve token usage
    const tokenContract = new ethers.Contract(fromToken, erc20ABI, signer);

    let tx = await tokenContract.approve(routerAddress, amount);
    await tx.wait();

    // Get contract instance
    const router = new ethers.Contract(routerAddress, routerABI, signer);

    // Set deadline
    const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 minutes

    // Construct transaction
    tx = await router.swapExactTokensForTokens(
        amount,
        0,
        bestRoute,
        recipient,
        deadline
    );

    return await tx.wait();
}

// example usage:

// swapTokens('zkSync', '0x4cf1434ed89d5ca852e95db9b3d586603e6bab17b2eed581fe7ca186313c0ff0', '0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4', '0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91', '136799694', '0x6516A658698b0EF490c3959546a14069b7831A89')