I'm trying to execute swap on Pancakeswap with web3.js but I get error

I am new at ethereum development and I am working on a simple script to execute swaps using Pancakeswap.
The code:

const ethers = require('ethers');

const {ChainId, Token, TokenAmount, Fetcher, Pair, Route, Trade, TradeType, Percent} = 

require('@pancakeswap-libs/sdk');

const Web3 = require('web3');

const {JsonRpcProvider} = require("@ethersproject/providers");

require("dotenv").config();

const provider = new JsonRpcProvider('https://bsc-dataseed1.binance.org/');

const web3 = new Web3('wss://apis.ankr.com/wss/c40792ffe3514537be9fb4109b32d257/946dd909d324e5a6caa2b72ba75c5799/binance/full/main');

const { address: admin } = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY);

console.log(`Modulos cargados`);

// Command Line Input

const InputTokenAddr = web3.utils.toChecksumAddress(process.argv[2]);

// var BUSD = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56';

const OutputTokenAddr = web3.utils.toChecksumAddress(process.argv[3]);

// var WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';

const InputTokenAmount = process.argv[4]

const Slipage = process.argv[5];

const PANCAKE_ROUTER = process.argv[6];

// const PANCAKE_ROUTER_V2 = '0x10ed43c718714eb63d5aa57b78b54704e256024e';

// const PANCAKE_ROUTER_V1 = '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F';

// 1/1000 = 0.001

const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1'));//BN->(BIG NUMBER) || toWei -> Converts any ether value value into wei.

const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('1000'));//tradeAmount = ONE_ETH_IN_WEI/1000

console.log(`tradeAmount ` + tradeAmount );

const init = async () => {

    const [INPUT_TOKEN, OUTPUT_TOKEN] = await Promise.all(

        [InputTokenAddr, OutputTokenAddr].map(tokenAddress => (

            new Token(

                ChainId.MAINNET,

                tokenAddress,

                18

            )

        )));

    console.log(` <<<<<------- pair-------->>>>>`);

    const pair = await Fetcher.fetchPairData(INPUT_TOKEN, OUTPUT_TOKEN, provider);

    //console.log(JSON.stringify(pair));

    console.log(` <<<<<------- route-------->>>>>`);

    const route = await new Route([pair], INPUT_TOKEN);

    //console.log(JSON.stringify(route));

    console.log(` <<<<<------- Trade-------->>>>>`);

    const trade = await new Trade(route, new TokenAmount(INPUT_TOKEN, tradeAmount), TradeType.EXACT_INPUT);

    //console.log(JSON.stringify(trade));

    //https://uniswap.org/docs/v2/javascript-SDK/trading/

    const slippageTolerance = new Percent(Slipage, '100'); // 

    console.log("slippageTolerance: " + JSON.stringify(slippageTolerance));

    // create transaction parameters

    const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw;

    const path = [INPUT_TOKEN.address, OUTPUT_TOKEN.address];

    const to = admin;

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

    // Create signer

    const wallet = new ethers.Wallet(

        Buffer.from(

        process.env.PRIVATE_KEY, 

        "hex"

        )

    );

    const signer = wallet.connect(provider);

    // Create Pancakeswap ethers Contract

    const pancakeswap = new ethers.Contract(

        PANCAKE_ROUTER,

        ['function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'],

        signer

    );

    //Allow input token

    if(true)

    {

        console.log(`Allow Pancakeswap <<<<<------- START-------->>>>>`);

        let abi = ["function approve(address _spender, uint256 _value) public returns (bool success)"];

        let contract = new ethers.Contract(INPUT_TOKEN.address, abi, signer);

        let aproveResponse = await contract.approve(PANCAKE_ROUTER, ethers.utils.parseUnits('1000.0', 18), {gasLimit: 100000, gasPrice: 5e9});

        console.log(JSON.stringify(aproveResponse));

        console.log(`Allow Pancakeswap <<<<<------- END-------->>>>>`);

        

    }

    

    if(true)

    {   

        console.log(`Ejecutando transaccion`);      

        var amountInParam = ethers.utils.parseUnits(InputTokenAmount, 18);

        var amountOutMinParam = ethers.utils.parseUnits(web3.utils.fromWei(amountOutMin.toString()), 18);

        

        console.log("amountInParam: " + amountInParam);

        console.log("amountOutMinParam: " + amountOutMinParam);

        console.log("amountOutMin: " + amountOutMin);

                        

        const tx = await pancakeswap.swapExactTokensForTokens(

            amountInParam,

            amountOutMinParam,

            path,

            to,

            deadline,

            { gasLimit: ethers.utils.hexlify(300000), gasPrice: ethers.utils.parseUnits("9", "gwei") }

        );

        console.log(`Tx-hash: ${tx.hash}`)

            const receipt = await tx.wait();

            console.log(`Tx was mined in block: ${receipt.blockNumber}`);

    }

        

}

init();

Normally I set BUSD as input token
And I use pancakeswap v1 or v2 router as router.
When output token is WBNB or BCH, it seems working well on both v1 and v2 router.
But when I set other token as an output token, I get error.
Plz help me.

Dexes such as PancakeSwap and Uniswap operate on pairs in their liquidity pool.

For example BNB/CAKE. When doing a swap with these tokens, you can swap between any token to any token and the router should do it automatically.

Are you sure that you are using the BUSD address correctly?

Are you sure that you are sending in the correct parameters for the Path? You will need to swap to multiple addresses if you plan to do that.

For example BUSD → BNB → CAKE.

Before writing code, you should test to see if your function works on the Test Net.

Can you show me transactions that verify what you are doing makes sense?

This is Pancake Swap’s testnet router.

Thanks for your response.
Of course, BUSD address is correct.
this:
0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56
I use follow command and parameters are correct.

npm run start 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3 0.001 16 0x10ed43c718714eb63d5aa57b78b54704e256024e

I didnt test on testnet. Can we test on testnet?
I tried to test on testnet but I got error so I gave up.
Could you tell me the way to test code above on testnet?

You can do it on a testnet to make sure the contract function works the way you think it does before doing it with Web3.js

I think you understand the basics of Web3 and have gotten some functions to work, so it’s probably a specific contract function. If you can make a contract function work on chain (on the test net) then you can make it work with web3.js

of course, it works on testnet
But on mainnet in case of some tokens, it doesnt works well

dude i use your code … but this line seems not working on my side

  const wallet = new ethers.Wallet(

    Buffer.from(

    process.env.PRIVATE_KEY, 

    "hex"

    )

);

So I remove the hex and buffer, after i receive I keep receiving Error: transaction failed (transactionHash=“0xe3440188b2dc3dd9bb311d765df67da05631f4d24c6d9bd244bca16bb48305e1”,
do you have any ideas ==

can you show me your error?

Hi Stepan,
You can check this working example that swaps with pancakeswap.finance:

// Helper script that buys ONLYONE token from a specified address specified on text file SPECIFY_ACCOUNTS_YOU_WANT_TO_BUY_FOR_HERE.json
// The amount is specified with 'originalAmountToBuyWith' variable in the source
// The JSON file should have an array with objects with 'address' field and 'privateKey' field.
// Buys ONLYONE for ${bnbAmount} BNB from pancakeswap for address ${targetAccounts[targetIndex].address}
// targetIndex is passed as an argument: process.argv.splice(2)[0]

var fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction;
var Web3 = require('web3')
var Common = require('ethereumjs-common').default;

var web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'))
var BSC_FORK = Common.forCustomChain(
    'mainnet',
    {
        name: 'Binance Smart Chain Mainnet',
        networkId: 56,
        chainId: 56,
        url: 'https://bsc-dataseed.binance.org/'
    },
    'istanbul',
);

// SPECIFY_THE_AMOUNT_OF_BNB_YOU_WANT_TO_BUY_FOR_HERE
var originalAmountToBuyWith = '0.007' + Math.random().toString().slice(2,7);
var bnbAmount = web3.utils.toWei(originalAmountToBuyWith, 'ether');

var targetAccounts = JSON.parse(fs.readFileSync('SPECIFY_ACCOUNTS_YOU_WANT_TO_BUY_FOR_HERE.json', 'utf-8'));

var targetIndex = Number(process.argv.splice(2)[0]);
var targetAccount = targetAccounts[targetIndex];

console.log(`Buying ONLYONE for ${originalAmountToBuyWith} BNB from pancakeswap for address ${targetAccount.address}`);

var res = buyOnlyone(targetAccounts[targetIndex], bnbAmount);
console.log(res);

async function buyOnlyone(targetAccount, amount) {

    var amountToBuyWith = web3.utils.toHex(amount);
    var privateKey = Buffer.from(targetAccount.privateKey.slice(2), 'hex')  ;
    var abiArray = JSON.parse(JSON.parse(fs.readFileSync('onlyone-abi.json','utf-8')));
    var tokenAddress = '0xb899db682e6d6164d885ff67c1e676141deaaa40'; // ONLYONE contract address
    var WBNBAddress = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; // WBNB token address

    // var onlyOneWbnbCakePairAddress = '0xd22fa770dad9520924217b51bf7433c4a26067c2';
    // var pairAbi = JSON.parse(fs.readFileSync('cake-pair-onlyone-bnb-abi.json', 'utf-8'));
    // var pairContract = new web3.eth.Contract(pairAbi, onlyOneWbnbCakePairAddress/*, {from: targetAccount.address}*/);
    var amountOutMin = '100' + Math.random().toString().slice(2,6);
    var pancakeSwapRouterAddress = '0x10ed43c718714eb63d5aa57b78b54704e256024e';

    var routerAbi = JSON.parse(fs.readFileSync('pancake-router-abi.json', 'utf-8'));
    var contract = new web3.eth.Contract(routerAbi, pancakeSwapRouterAddress, {from: targetAccount.address});
    var data = contract.methods.swapExactETHForTokens(
        web3.utils.toHex(amountOutMin),
        [WBNBAddress,
         tokenAddress],
        targetAccount.address,
        web3.utils.toHex(Math.round(Date.now()/1000)+60*20),
    );

    var count = await web3.eth.getTransactionCount(targetAccount.address);
    var rawTransaction = {
        "from":targetAccount.address,
        "gasPrice":web3.utils.toHex(5000000000),
        "gasLimit":web3.utils.toHex(290000),
        "to":pancakeSwapRouterAddress,
        "value":web3.utils.toHex(amountToBuyWith),
        "data":data.encodeABI(),
        "nonce":web3.utils.toHex(count)
    };

    var transaction = new Tx(rawTransaction, { 'common': BSC_FORK });
    transaction.sign(privateKey);

    var result = await web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'));
    console.log(result)
    return result;
}

Anyone can also contribute to the repository.

thanks

I’m trying to call function of my own contract in uniswap.
For example, I want to call my own function of my contract instead of swapETHForExactTokens of UniswapV2Router02 contract.