const Web3 = require('web3')
const axios = require('axios')
const { BN } = Web3.utils
const MAX_UINT = '115792089237316195423570985008687907853269984665640564039457584007913129639935'
const PRIVATE_KEY = '' // TODO: config your private key
const ROUTER_API = 'https://router.firebird.finance/aggregator/v1/route'
const RPC_URL = 'https://rpc.ftm.tools/'
"inputs": [{ "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" }],
"outputs": [{ "name": "remaining", "type": "uint256" }],
"stateMutability": "view",
"inputs": [{ "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" }],
"stateMutability": "nonpayable",
const web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL))
// PRIVATE_KEY variable defined
const account = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY)
function sendTransaction(tx) {
const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
return new Promise((resolve, reject) => {
signPromise.then((signedTx) => {
// raw transaction string may be available in .raw or
// .rawTransaction depending on which signTransaction
const sentTx = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction)
sentTx.on("receipt", receipt => {
// do something when receipt comes back
sentTx.on("error", err => {
// do something on transaction error
// do something when promise fails
async function swap(params) {
// fetch encoded swap transaction data
const { data: { encodedData } } = await axios.get(ROUTER_API, {
headers: { 'Content-Type': 'application/json' },
const tokenIn = params.from
const routerContract = encodedData.router // router contract address
const currencyAIsEth = tokenIn.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
const amountIn = params.amount
const contract = new web3.eth.Contract(ERC20_ABI, tokenIn, {
const allowance = await contract.methods.allowance(account.address, routerContract).call()
if (new BN(allowance).lt(new BN(amountIn))) {
console.log('# APPROVING...')
const approvalData = contract.methods.approve(routerContract, MAX_UINT).encodeABI()
const approvalReceipt = await sendTransaction(tx, PRIVATE_KEY).catch()
console.log('# APPROVED TXN:', approvalReceipt.transactionHash)
from: account.address, // signer address
data: encodedData.data, // encoded contract data
value: currencyAIsEth ? amountIn : undefined,
console.log('# SWAPPING...')
console.log('# SWAP SUCCESSFULLY:')
// do something when receipt comes back
console.log('# SWAP FAILED:')
// do something on transaction error
from: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7',
to: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
receiver: account.address,