├── .gitignore ├── package.json ├── README.md └── pancakeswap-sniping-bot.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /node_modules 3 | /logs -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pancakeswap-sniping-bot", 3 | "version": "2.0.0", 4 | "description": "A free NodeJS sniper bot built to work with PancakeSwap", 5 | "main": "pancakeswap-sniping-bot.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cronr": "^2.2.1", 14 | "web3": "1.3.6" 15 | } 16 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PancakeSwap sniping bot 2 | 3 | ## Purpose 4 | This bot allows you to compete with other trading bots when buying a cryptocurrency. Can be used for fairlaunch projects or if you've been unlucky and not being whitelisted for the private or public sales and you still want to buy immediately on PancakeSwap pair creation. If a project is hype it is quite impossible to compete manually with bots. For long time bots have been integral part of trading not only for the cryptocurrencies, but also for stocks, fiat currencies, etc. 5 | 6 | ## Features 7 | * Operating with PancakeSwap: Router v2 8 | * Has the option to work with both BSC mainnet and testnet 9 | * Including all kind of transaction options like gas price, gas limit, transaction slippage, transaction deadline, etc 10 | * Has the option to fire multiple transactions at once 11 | * Supporting milliseconds 12 | * Free 13 | 14 | ## Requirements 15 | * npm 6.0.0 or above 16 | * NodeJS 10.0.0 or above 17 | * pm2 18 | 19 | ## Installation 20 | Clone this repository ( or download from Code -> Download ZIP ) and run `npm install` inside the project folder. This command will download all the needed libraries which the bot needs to work properly. 21 | 22 | ## Usage 23 | You can run the script using `node` or `pm2` commands. I personally like to use the `pm2` command on my server, because PM2 is a process manager which takes care for my script to run 24/7. 24 | 25 | #### Required parameters: 26 | * `tokenAddress` - this is the contract address of the token you're willing to buy. String, 42 bytes size starting with `0x`. 27 | * `buyingBnbAmount` - this is the amount of BNB which you are willing to use to execute the buying transaction. Integer or float. 28 | * `senderPrivateKey` - this is the private key of the wallet address which will be used to execute the buying transaction. String, 66 bytes size starting with `0x`. *If you're using MetaMask then you will have to manually add `0x` at the beginning of your private key, because MetaMask is displaying the private key with 64 bytes size.* 29 | 30 | #### Optional parameters: 31 | * `gasLimit` - the maximum amount of gas you are willing to consume on a transaction, default value is 500000. 32 | *( This value may not be sufficient in some cases, because some projects require more `gasLimit` in order for the tokens to be transferred. )* 33 | * `gasPrice` - the transaction gas price in Gwei, default value is 10 Gwei. 34 | * `transactionIterations` - how many times you want the transaction to be executed. Some fairlaunch projects have smart contract conditions to not buy big amounts of tokens for single transaction, so in the case that you want to buy bigger amount and to bypass the contract condition you can execute many transactions buying same amount. Setting `transactionIterations` to 3 will execute 3 different buying transactions with the same transaction parameters. Default value is 1. 35 | * `transactionSlippage` - the difference ( in percents ) between the expected price of a trade and the executed price of that trade. Default value is 15 percents, integer. 36 | * `transactionDeadline` - your transaction will revert if it is pending for more than this long. Default value is 1200 seconds, integer. 37 | * `bscNetwork` - accepts only `mainnet` and `testnet` values. Defines to which network should the bot submit blockchain transactions. Default value is `testnet`. 38 | * `createLogs` - boolean, if set to `true` it will create ./logs folder and save logs on different bot actions. 39 | * `cronTime` - how often should the bot try to buy the particular token. Default is `*/100 * * * * * *` aka every 100 milliseconds. 40 | * `botInitialDelay` - by default when starting the bot for first time it has 10 seconds delay to double check what parameters have been passed. Setting this parameter to `0` will remove the delay if needed. 41 | 42 | #### Sample terminal command: 43 | * Using `node` - `node pancakeswap-sniper-bot.js -- tokenAddress=0xc9849e6fdb743d08faee3e34dd2d1bc69ea11a51 buyingBnbAmount=1.05 senderPrivateKey=0x8da4ef21b864d2cc526dbdb2a120bd2874c36c9d0a1fb7f8c63d7f7a8b41de8f createLogs=true gasPrice=25 transactionSlippage=30 bscNetwork=mainnet` 44 | * Using `pm2` - `pm2 start pancakeswap-sniper-bot.js -- tokenAddress=0xc9849e6fdb743d08faee3e34dd2d1bc69ea11a51 buyingBnbAmount=1.05 senderPrivateKey=0x8da4ef21b864d2cc526dbdb2a120bd2874c36c9d0a1fb7f8c63d7f7a8b41de8f createLogs=true gasPrice=25 transactionSlippage=30 bscNetwork=mainnet` 45 | 46 | If you wish to use the bot at same time for multiple crypto tokens you could make several pm2 instances by passing `--name` parameter to the pm2 command. Example: `--name "app name"`. -------------------------------------------------------------------------------- /pancakeswap-sniping-bot.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ nodejs 2 | const fs = require('fs'); 3 | const Cronr = require('cronr'); 4 | const Web3 = require('web3'); 5 | 6 | console.log('Welcome to PancakeSwap Sniper bot!'); 7 | 8 | // ======================== DEFAULT CONFIG ======================== 9 | var bscNetwork = 'testnet'; 10 | var allowedNetworks = ['testnet', 'mainnet']; 11 | var gasLimit = 500000; 12 | var gasPrice = 10; // in gwei 13 | var transactionIterations = 1; 14 | var executed = 0; 15 | var transactionSlippage = 15; // in percents 16 | var transactionDeadline = 1200; // in seconds 17 | var createLogs = false; 18 | var cronTime = '*/100 * * * * * *'; // every 10 milliseconds 19 | var botInitialDelay = 10000; 20 | // ======================== /DEFAULT CONFIG ======================== 21 | 22 | var logsDir = __dirname + '/logs/'; 23 | var logsPath = logsDir + new Date().toISOString().slice(0,10) + '.txt'; 24 | 25 | const projectData = { 26 | utils: { 27 | createLog: function(content) { 28 | if (createLogs) { 29 | console.log(content); 30 | if (fs.existsSync(logsPath)) { 31 | content = '\r\n' + new Date().toUTCString() + ': ' + content; 32 | } 33 | fs.appendFile(logsPath, content, function (err) { 34 | if (err) throw err; 35 | }); 36 | } 37 | }, 38 | propertyExists: function(object, key) { 39 | return object ? hasOwnProperty.call(object, key) : false; 40 | } 41 | } 42 | }; 43 | 44 | // reading params 45 | var params = process.argv.slice(2); 46 | var args = {}; 47 | for (var i = 0, len = params.length; i < len; i+=1) { 48 | var key_value = params[i].split('='); 49 | args[key_value[0]] = key_value[1]; 50 | } 51 | 52 | function initPancakeswapSniperBot() { 53 | bscNetwork = (projectData.utils.propertyExists(args, 'bscNetwork') && allowedNetworks.includes(args.bscNetwork)) ? args.bscNetwork : bscNetwork; 54 | if (bscNetwork == 'mainnet') { 55 | var web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/')); 56 | var pancakeContractAddress = '0x10ed43c718714eb63d5aa57b78b54704e256024e'; 57 | var wbnbAddress = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; 58 | var chainId = 56; 59 | } else if (bscNetwork == 'testnet') { 60 | var web3 = new Web3(new Web3.providers.HttpProvider('https://data-seed-prebsc-1-s1.binance.org:8545')); 61 | var pancakeContractAddress = '0x9ac64cc6e4415144c455bd8e4837fea55603e5c3'; 62 | var wbnbAddress = '0xae13d989dac2f0debff460ac112a837c89baa7cd'; 63 | var chainId = 97; 64 | } 65 | 66 | // ======================== REQUIRED PARAMETERS ======================== 67 | if (!projectData.utils.propertyExists(args, 'tokenAddress') || args.tokenAddress == '' || args.tokenAddress == null || args.tokenAddress == undefined || args.tokenAddress.length != 42) { 68 | return console.error('Missing or wrong tokenAddress parameter.'); 69 | } else if (!projectData.utils.propertyExists(args, 'buyingBnbAmount') || args.buyingBnbAmount == '' || args.buyingBnbAmount == null || args.buyingBnbAmount == undefined) { 70 | return console.error('Missing or wrong buyingBnbAmount parameter.'); 71 | } else if (!projectData.utils.propertyExists(args, 'senderPrivateKey') || args.senderPrivateKey == '' || args.senderPrivateKey == null || args.senderPrivateKey == undefined || args.senderPrivateKey.length != 66) { 72 | return console.error('Missing or wrong senderPrivateKey parameter.'); 73 | } 74 | 75 | var buyingBnbAmount = args.buyingBnbAmount; 76 | var tokenAddress = args.tokenAddress; 77 | var senderPrivateKey = args.senderPrivateKey; 78 | var senderAddress = web3.eth.accounts.privateKeyToAccount(senderPrivateKey).address; 79 | // ======================== /REQUIRED PARAMETERS ======================== 80 | 81 | // ======================== CHANGING DEFAULT PARAMETERS IF THEY ARE PASSED ======================== 82 | console.log('Address used to send the transactions: ' + senderAddress); 83 | console.log('BSC network: ' + bscNetwork); 84 | gasLimit = (projectData.utils.propertyExists(args, 'gasLimit') && args.gasLimit != '' && args.gasLimit != null && args.gasLimit != undefined) ? args.gasLimit : gasLimit; 85 | console.log('Gas limit: ' + gasLimit); 86 | gasPrice = (projectData.utils.propertyExists(args, 'gasPrice') && args.gasPrice != '' && args.gasPrice != null && args.gasPrice != undefined) ? args.gasPrice * 1000000000 : gasPrice * 1000000000; 87 | console.log('Gas price: ' + (gasPrice / 1000000000) + ' Gwei'); 88 | transactionIterations = (projectData.utils.propertyExists(args, 'transactionIterations') && args.transactionIterations != '' && args.transactionIterations != null && args.transactionIterations != undefined) ? args.transactionIterations : transactionIterations; 89 | console.log('Transaction iterations: ' + transactionIterations); 90 | transactionSlippage = (projectData.utils.propertyExists(args, 'transactionSlippage') && args.transactionSlippage != '' && args.transactionSlippage != null && args.transactionSlippage != undefined) ? args.transactionSlippage : transactionSlippage; 91 | console.log('Transaction slippage: ' + transactionSlippage); 92 | transactionDeadline = (projectData.utils.propertyExists(args, 'transactionDeadline') && args.transactionDeadline != '' && args.transactionDeadline != null && args.transactionDeadline != undefined) ? args.transactionDeadline : transactionDeadline; 93 | console.log('Transaction deadline: ' + transactionDeadline); 94 | createLogs = (projectData.utils.propertyExists(args, 'createLogs') && args.createLogs === 'true') ? true : createLogs; 95 | console.log('Creating logs: ' + createLogs); 96 | cronTime = (projectData.utils.propertyExists(args, 'cronTime') && args.cronTime != '' && args.cronTime != null && args.cronTime != undefined) ? args.cronTime : cronTime; 97 | console.log('Cron time: ' + cronTime); 98 | botInitialDelay = (projectData.utils.propertyExists(args, 'botInitialDelay') && args.botInitialDelay != '' && args.botInitialDelay != null && args.botInitialDelay != undefined) ? args.botInitialDelay : botInitialDelay; 99 | console.log('Bot initial delay: ' + botInitialDelay); 100 | // ======================== /CHANGING DEFAULT PARAMETERS IF THEY ARE PASSED ======================== 101 | 102 | // if logs dir missing then create it 103 | if (createLogs && !fs.existsSync(logsDir)){ 104 | fs.mkdirSync(logsDir); 105 | } 106 | 107 | var pancakeContractABI = [{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExeactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]; 108 | var pancakeContract = new web3.eth.Contract(pancakeContractABI, pancakeContractAddress); 109 | 110 | if (botInitialDelay > 0) { 111 | console.log('Starting the PancakeSwap Sniper bot in ' + (botInitialDelay / 1000) + ' seconds... ¯\\_(*o*)_/¯'); 112 | } else { 113 | console.log('Starting the PancakeSwap Sniper bot now... ¯\\_(*o*)_/¯'); 114 | } 115 | 116 | setTimeout(function () { 117 | var executeBuy = true; 118 | // check if sender has enough balance 119 | web3.eth.getBalance(senderAddress, function (getBalanceErr, getBalanceResponse) { 120 | if (!getBalanceErr) { 121 | if (BigInt(web3.utils.toWei(buyingBnbAmount, 'ether')) < BigInt(getBalanceResponse)) { 122 | // check if token address is a contract address 123 | web3.eth.getCode(tokenAddress, function (getCodeErr, getCodeResponse) { 124 | if (!getCodeErr) { 125 | if (getCodeResponse != '0x') { 126 | // take the current nonce of the sender 127 | web3.eth.getTransactionCount(senderAddress, 'pending', function (nonceErr, nonceResponse) { 128 | var nonce = nonceResponse; 129 | var txParams = { 130 | gas: web3.utils.toHex(gasLimit), 131 | gasPrice: web3.utils.toHex(gasPrice), 132 | nonce: web3.utils.toHex(nonce), 133 | chainId: chainId, 134 | value: web3.utils.toHex(web3.utils.toWei(buyingBnbAmount, 'ether')), 135 | to: pancakeContractAddress 136 | }; 137 | 138 | const job = new Cronr(cronTime, function() { 139 | projectData.utils.createLog('Cronjob iteration.'); 140 | if (executeBuy) { 141 | executeBuy = false; 142 | 143 | return executeTransaction(executed); 144 | function executeTransaction(executed) { 145 | pancakeContract.methods.getAmountsOut(web3.utils.toWei(buyingBnbAmount, 'ether'), [wbnbAddress, tokenAddress]).call({}, function(amountsOutError, amountsOutResult) { 146 | if (!amountsOutError) { 147 | var amountOut = amountsOutResult[1]; 148 | if (amountOut > 0) { 149 | amountOut = amountOut - (amountOut * transactionSlippage / 100); 150 | projectData.utils.createLog('Trading pair is active.'); 151 | 152 | amountOut = BigInt(Math.round(amountOut)); 153 | amountOut = amountOut.toString(); 154 | 155 | // check if swap transaction is going to succeed or fail 156 | pancakeContract.methods.swapExactETHForTokens(amountOut, [wbnbAddress, tokenAddress], senderAddress, Math.round(new Date(new Date().getTime() + (transactionDeadline * 1000)).getTime() / 1000)).estimateGas({from: senderAddress, gas: gasLimit, value: web3.utils.toHex(web3.utils.toWei(buyingBnbAmount, 'ether'))}, function(gasEstimateError, gasAmount) { 157 | if (!gasEstimateError) { 158 | projectData.utils.createLog('Method executeTransaction, params: {executed: ' + executed + ', amountOut: ' + amountOut + ', wbnbAddress: ' + wbnbAddress + ', tokenAddress: ' + tokenAddress + ', senderAddress: ' + senderAddress + '}'); 159 | txParams.data = pancakeContract.methods.swapExactETHForTokens(amountOut, [wbnbAddress, tokenAddress], senderAddress, Math.round(new Date(new Date().getTime() + (transactionDeadline * 1000)).getTime() / 1000)).encodeABI(); 160 | 161 | web3.eth.accounts.signTransaction(txParams, senderPrivateKey, function (signTransactionErr, signedTx) { 162 | if (!signTransactionErr) { 163 | nonce += 1; 164 | txParams.nonce = web3.utils.toHex(nonce); 165 | 166 | web3.eth.sendSignedTransaction(signedTx.rawTransaction, function (sendSignedTransactionErr, transactionHash) { 167 | if (!sendSignedTransactionErr) { 168 | executed += 1; 169 | 170 | if (transactionIterations != 1) { 171 | projectData.utils.createLog('Buying order N: ' + executed + '. Transaction hash: ' + transactionHash); 172 | if (transactionIterations != executed) { 173 | return executeTransaction(executed); 174 | } else { 175 | job.stop(); 176 | } 177 | } else { 178 | projectData.utils.createLog('First and only buying order. Transaction hash: ' + transactionHash) 179 | job.stop(); 180 | } 181 | } else { 182 | executeBuy = true; 183 | if (sendSignedTransactionErr.message) { 184 | projectData.utils.createLog('Method web3.eth.sendSignedTransaction failed. Message: ' + sendSignedTransactionErr.message); 185 | } else { 186 | projectData.utils.createLog('Method web3.eth.sendSignedTransaction failed. Message: ' + sendSignedTransactionErr.toString()); 187 | } 188 | } 189 | }); 190 | } else { 191 | executeBuy = true; 192 | if (signTransactionErr.message) { 193 | projectData.utils.createLog('Method web3.eth.accounts.signTransaction failed. Message: ' + signTransactionErr.message); 194 | } else { 195 | projectData.utils.createLog('Method web3.eth.accounts.signTransaction failed. Message: ' + signTransactionErr.toString()); 196 | } 197 | } 198 | }); 199 | } else { 200 | executeBuy = true; 201 | if (gasEstimateError.message) { 202 | projectData.utils.createLog('Method pancakeContract.methods.swapExactETHForTokens.estimateGas() failed. Message: ' + gasEstimateError.message); 203 | } else { 204 | projectData.utils.createLog('Method pancakeContract.methods.swapExactETHForTokens.estimateGas() failed. Message: ' + gasEstimateError.toString()); 205 | } 206 | } 207 | }); 208 | } else { 209 | executeBuy = true; 210 | projectData.utils.createLog('Trading pair active. amountOut smaller or equal to 0.'); 211 | } 212 | } else { 213 | executeBuy = true; 214 | projectData.utils.createLog('Trading pair not active yet.'); 215 | } 216 | }); 217 | } 218 | } 219 | }, {}); 220 | job.start(); 221 | }); 222 | } else { 223 | projectData.utils.createLog('Invalid tokenAddress parameter. tokenAddress must be contract address.'); 224 | return false; 225 | } 226 | } else { 227 | projectData.utils.createLog('Reading token address code failed.'); 228 | return false; 229 | } 230 | }); 231 | } else { 232 | executeBuy = true; 233 | projectData.utils.createLog('Sender address does not have enough BNB balance to execute the transaction. Current balance: ' + web3.utils.fromWei(getBalanceResponse.toString(), 'ether') + ' BNB.'); 234 | return false; 235 | } 236 | } else { 237 | projectData.utils.createLog('Reading sender address balance failed.'); 238 | return false; 239 | } 240 | }); 241 | }, botInitialDelay); 242 | } 243 | initPancakeswapSniperBot(); --------------------------------------------------------------------------------