Code Snippets for Node scripts
Useful code snippets for developers
Get MINT token price via PancakeSwap
MINT token liquidity is provided with BNB token on PancakeSwap, so we can query the USD value of one MINT token by calling minimumAmountOut()
function on PancakeSwap SDK with MINT -> WBNB -> USDT
routes.
const { JsonRpcProvider } = require('@ethersproject/providers');
const { Token, Fetcher, Percent, Trade, TradeType, Route, TokenAmount, WETH } = require('@pancakeswap/sdk');
// Constants
const MINT_CONTRACT = '0x1f3Af095CDa17d63cad238358837321e95FC5915';
const USDT_CONTRACT = '0x55d398326f99059fF775485246999027B3197955';
const BSC_CHAIN_ID = 56;
const DECIMALS = 18;
const ONE_UNIT = new BigNumber('1000000000000000000'); // 1e18
async function getMintPrice() {
const provider = new JsonRpcProvider(getRandomRPCServer());
const MINT = new Token(BSC_CHAIN_ID, MINT_CONTRACT, DECIMALS);
const USDT = new Token(BSC_CHAIN_ID, USDT_CONTRACT, DECIMALS);
const MINT_BNB_PAIR = await Fetcher.fetchPairData(MINT, WETH[BSC_CHAIN_ID], provider);
const BNB_USDT_PAIR = await Fetcher.fetchPairData(USDT, WETH[BSC_CHAIN_ID], provider);
const route = new Route([MINT_BNB_PAIR, BNB_USDT_PAIR], MINT);
const trade = new Trade(route, new TokenAmount(MINT, ONE_UNIT), TradeType.EXACT_INPUT);
const slippageTolerance = new Percent('0', '10000');
const amountOut = new BigNumber(trade.minimumAmountOut(slippageTolerance).raw.toString(10))
.dividedBy(ONE_UNIT)
.toNumber();
return amountOut;
}
Transfer BEP20 tokens
Transfer BEP20 tokens using a JS node script (with a private key)
const { ethers } = require('ethers');
const BigNumber = require('bignumber.js');
const minABI = [{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}];
const ONE_UNIT = new BigNumber('1000000000000000000'); // 1e18
const PRIVATE_KEY = ""; // Private key of sender wallet
async function send(contract, to, amount) {
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed.binance.org/');
const fromWallet = new ethers.Wallet(PRIVATE_KEY, provider);
const token = new ethers.Contract(contract, minABI, fromWallet);
const tx = await token.transfer(
to,
String(new BigNumber(amount).multipliedBy(DECIMALS)),
{ gasLimit: 100000, gasPrice: 5100000000 } // 5.1 GWei
);
console.log(`SENT -> TX: ${tx.hash}`)
}
Get balance of a wallet
const BigNumber = require('bignumber.js');
const { ethers } = require("ethers");
const { JsonRpcProvider } = require('@ethersproject/providers');
const minABI = [{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}];
function toDecimalAmount(bn) {
return new BigNumber(bn.toString()).dividedBy(ETHER).toNumber();
}
function getBalance(tokenContractAddress, wallet) {
const provider = new JsonRpcProvider('https://bsc-dataseed.binance.org/');
const contract = new ethers.Contract(tokenContractAddress, minABI, provider);
return toDecimalAmount(await contract.balanceOf(wallet));
}
Monitor events
Following example monitors all Transfer
events emitted from a token contract.
We can use contract.on(event, listener)
if a WebSocket endpoint is available (there's no reliable one on BSC), but we should check blocks manually if we only have HTTP RPC endpoints. This example will use the manual approach with HTTP endpoints.
const { JsonRpcProvider } = require('@ethersproject/providers');
const { ethers } = require("ethers");
const erc20ABI = require('./abi/erc20.json');
const TARGET_CONTRACT = '0x1f3Af095CDa17d63cad238358837321e95FC5915';
function sleep(sec) {
return new Promise(resolve => setTimeout(resolve, sec * 1000));
}
async function checkEvents(contract, fromBlock, toBlock = 'latest') {
const events = await contract.queryFilter('*', fromBlock, toBlock);
for (event of events) {
if (event.removed) {
console.log(`[SKIP_REMOVED] ${event.transactionHash}`);
continue;
}
if (event.event === 'Transfer' && event.args) {
console.log('Transfer event detected:', event);
}
}
}
async function runForever() {
const provider = new JsonRpcProvider(getRandomRPCServer());
const contract = new ethers.Contract(TARGET_CONTRACT, erc20ABI, provider);
let recentBlock = await provider.getBlockNumber();
let lastCheckedBlock = recentBlock - 4999; // Max API limit: 5000
let fromBlock = lastCheckedBlock + 1;
logger(`First, fetch from the last checked block: #${fromBlock} - #${recentBlock}`);
// This will fetch all events from [fromBlock - recentBlock]
await checkEvents(contract, fromBlock);
await sleep(3); // BSC block speed: 3 secs
fromBlock = recentBlock + 1;
while(1) {
recentBlock = await provider.getBlockNumber();
// If we are faster than block mining
if (fromBlock >= recentBlock) {
console.log(`#${fromBlock} block is not mined yet. Wait..`);
await sleep(3);
continue;
}
console.log(`Check blocks: #${fromBlock} - #${recentBlock}`);
await checkEvents(contract, fromBlock); // Check [fromBlock - recentBlock]
fromBlock = recentBlock + 1;
await sleep(3);
}
}
runForever();