-
-
Save earthchie/b8dc9f8cbbf842ee1975938845d96bc2 to your computer and use it in GitHub Desktop.
const express = require('express'); | |
const { ethers } = require('ethers'); | |
const app = express(); | |
const port = 3000; | |
const provider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed.binance.org/'); | |
const contract = { | |
factory: '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73', // PancakeSwap V2 factory | |
router: '0x10ED43C718714eb63d5aA57B78B54704E256024E', // PancakeSwap V2 router | |
}; | |
const tokens = { | |
BUSD: '0xe9e7cea3dedca5984780bafc599bd69add087d56', | |
SCZ: '0x39f1014a88c8ec087cedf1bfc7064d24f507b894', | |
DOP: '0x844fa82f1e54824655470970f7004dd90546bb28', | |
}; | |
const router = new ethers.Contract( | |
contract.router, | |
['function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)'], | |
provider | |
); | |
app.get('/getPrice', (req, res) => { | |
let token = req.query.token; | |
if(token.indexOf('0x') === -1){ | |
token = tokens[token.toUpperCase()]; | |
} | |
if(token) { | |
getPrice(token, tokens.BUSD).then(price => { | |
res.json({ | |
success: true, | |
BUSD: price | |
}); | |
}); | |
}else{ | |
res.status(400).json({ | |
success: false, | |
description: 'missing `token` parameter' | |
}); | |
} | |
}); | |
app.listen(port, () => { | |
console.log(`getPrice listening at http://localhost:${port}`) | |
}); | |
async function getPrice(inputCurrency, outputCurrency){ | |
const amounts = await router.getAmountsOut(ethers.utils.parseUnits('1', 18), [inputCurrency, outputCurrency]); | |
return amounts[1].toString()/1e18; | |
} |
it's incorrect the first argument of getAmountsOut, must div the token decimal not 18
Can I check price real time. I feel it incorrect
Doesn't seem to be realtime, but thanks!
First parameter to getAmountsOut()
should be 1
to avoid underflow when token has less than 18 decimals... If for example the token has 2 decimals, the divisor must be 1e16 to get correct result. Basically divisor is 10^(18-decimals). For some tokens it is also required to use for example "WBNB" as output currency as there is no "BUSD" pair yet. Then to get price as "BUSD", input currency must be "WBNB" and output currency must be "BUSD". That doesn't need divisor at all, just multiply with the price from first step.
First parameter to
getAmountsOut()
should be1
to avoid underflow when token has less than 18 decimals... If for example the token has 2 decimals, the divisor must be 1e16 to get correct result. Basically divisor is 10^(18-decimals). For some tokens it is also required to use for example "WBNB" as output currency as there is no "BUSD" pair yet. Then to get price as "BUSD", input currency must be "WBNB" and output currency must be "BUSD". That doesn't need divisor at all, just multiply with the price from first step.
Wow thanks!
By the way, please also check this gist.
https://gist.github.com/earthchie/bc528f3bcbc1ef00b43c40ab9238cbd2
It is an another implementation to get price and more accurate than this gist.
I already noticed this one gives slightly different results as shown in the liquidity pool... But liquidity pool also includes the accumulated transaction fees debited to liquidity provider.
try
http://localhost:3000/getPrice?token=0x844fa82f1e54824655470970f7004dd90546bb28
or
http://localhost:3000/getPrice?token=DOP