Skip to content

Instantly share code, notes, and snippets.

@Linch1
Last active May 21, 2024 04:43
Show Gist options
  • Save Linch1/ede03999f483f2b1d5fcac9e8b312f2c to your computer and use it in GitHub Desktop.
Save Linch1/ede03999f483f2b1d5fcac9e8b312f2c to your computer and use it in GitHub Desktop.
Retrive the price of any bsc token from it's address without using external service like poocoin/dextools
let pancakeSwapAbi = [
{"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"},
];
let tokenAbi = [
{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
];
const Web3 = require('web3');
/*
Required Node.js
-- Web3 Token Charting --
Checkout my repo about building a clone of poocoin/dextools on bsc/pancakeswap and on any other similar chain/dex
https://github.com/Linch1/Web3TokenCharting
-- Usage --
1. Make a directory on your pc
2. Open a terminal
3. go inside the created directory
4. run : npm init
5. run : npm i --save web3
6. Create a file: tokenPrice.js
7. Copy this text inside that file
8. run: node tokenPrice.js
-- Direct contact --
https://www.reddit.com/user/Linch-1
*/
let pancakeSwapContract = "0x10ED43C718714eb63d5aA57B78B54704E256024E".toLowerCase();
const web3 = new Web3("https://bsc-dataseed1.binance.org");
async function calcSell( tokensToSell, tokenAddres){
const web3 = new Web3("https://bsc-dataseed1.binance.org");
const BNBTokenAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" //BNB
let tokenRouter = await new web3.eth.Contract( tokenAbi, tokenAddres );
let tokenDecimals = await tokenRouter.methods.decimals().call();
tokensToSell = setDecimals(tokensToSell, tokenDecimals);
let amountOut;
try {
let router = await new web3.eth.Contract( pancakeSwapAbi, pancakeSwapContract );
amountOut = await router.methods.getAmountsOut(tokensToSell, [tokenAddres ,BNBTokenAddress]).call();
amountOut = web3.utils.fromWei(amountOut[1]);
} catch (error) {}
if(!amountOut) return 0;
return amountOut;
}
async function calcBNBPrice(){
const web3 = new Web3("https://bsc-dataseed1.binance.org");
const BNBTokenAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" //BNB
const USDTokenAddress = "0x55d398326f99059fF775485246999027B3197955" //USDT
let bnbToSell = web3.utils.toWei("1", "ether") ;
let amountOut;
try {
let router = await new web3.eth.Contract( pancakeSwapAbi, pancakeSwapContract );
amountOut = await router.methods.getAmountsOut(bnbToSell, [BNBTokenAddress ,USDTokenAddress]).call();
amountOut = web3.utils.fromWei(amountOut[1]);
} catch (error) {}
if(!amountOut) return 0;
return amountOut;
}
function setDecimals( number, decimals ){
number = number.toString();
let numberAbs = number.split('.')[0]
let numberDecimals = number.split('.')[1] ? number.split('.')[1] : '';
while( numberDecimals.length < decimals ){
numberDecimals += "0";
}
return numberAbs + numberDecimals;
}
/*
How it works?
This script simply comunicates with the smart contract deployed by pancakeswap and calls the main
function that was build to retrive the token prices
*/
(async () => {
const tokenAddres = '0xa49e44976c236beb51a1f818d49b9b9759ed97b1'; // change this with the token addres that you want to know the
let bnbPrice = await calcBNBPrice() // query pancakeswap to get the price of BNB in USDT
console.log(`CURRENT BNB PRICE: ${bnbPrice}`);
// Them amount of tokens to sell. adjust this value based on you need, you can encounter errors with high supply tokens when this value is 1.
let tokens_to_sell = 1;
let priceInBnb = await calcSell(tokens_to_sell, tokenAddres)/tokens_to_sell; // calculate TOKEN price in BNB
console.log( 'SHIT_TOKEN VALUE IN BNB : ' + priceInBnb + ' | Just convert it to USD ' );
console.log(`SHIT_TOKEN VALUE IN USD: ${priceInBnb*bnbPrice}`); // convert the token price from BNB to USD based on the retrived BNB value
})();
@nilooy
Copy link

nilooy commented Nov 1, 2021

Anyone interested to work on publishing an opensource project with this amazing script?

@mitko-janeski
Copy link

Is it possible to get Marketcap data for coins ?

@rsmith2002
Copy link

rsmith2002 commented Dec 11, 2021

changing token amount doesn't seem to alter the value outputted under the bnbvalue or usdvalue

@luisbriyan
Copy link

luisbriyan commented Dec 23, 2021

Hi @Linch1 sometimes I get wrong prices, I'm not sure if this has a solution. For example when the token has a pair in BNB / BUSD. In the image you can see that the price it shows is incorrect compared to what it shows in poocoin. The token is 18 decimal places, it is strange because sometimes with other tokens it works normal and with some others a too different price appears. I don't want to give you more work, because you already made a pretty good API! Do you have any idea that it can be modified to work properly? (I no longer use the "getReserves0 / 1" because in some tokens the price it shows is different because it was not updated in minutes)

https://poocoin.app/tokens/0x8c5921a9563e6d5dda95cb46b572bb1cc9b04a27
pair BUSD_cryptowolf

@Linch1
Copy link
Author

Linch1 commented Dec 25, 2021

Ehi @luisbriyan and @rsmith2002 😃

Actually the issue with your tokens probably is that the token's main pair is done with a token other than BNB.

Taking as example the image that @luisbriyan sent we can see that the pair of poocoin currently showed is CWOLF/BUSD, the chart and the price is based on that pair.

My script by default works only on BNB/<your token> pairs, so in this case the price is taken from the second pair that poocoin is listing ( the one to the left / middle of the image with 0.03BNB inside ).

if you want to take the price of other pairs rather than the ones that involve BNB you must edit the variables at line 28 and 46 ( where the BNB address is ) with the token that is involved inside the interested pair.

in this case the interested token involved inside the pair is BUSD, so if you replace the variables at line 28 and 46 with the value 0xe9e7cea3dedca5984780bafc599bd69add087d56 the script should work correctly.

Unfortunately you cannot know by default the correct pair's tokens where to take the price, you should estimate the value inside each pair and consider the one with most money inside, but this work is much more complex rater than a simple gist.
In mostly BNB is used so is the default one in this gist.

Let me know if you still have something not clear !

@Greyh4t
Copy link

Greyh4t commented Dec 26, 2021

Hi,

Thank you for creating this excellent script, it works well in most cases, but when I use it to query the price of AAVE, it returns the wrong result, which is different from the one shown on the website. Do you know why this is?

1

You can see price here https://swap.arken.finance/tokens/bsc/0xfb6115445bff7b52feb98650c87f44907e58f802

@Linch1
Copy link
Author

Linch1 commented Dec 26, 2021

Ehi @Greyh4t 😄 , the main issue with your token is that the arken price is retrived from different platforms rather than pancakeswap as i can see, you should do some researches and change the pancakeSwapContract address inside the code with the platfrom you want to use to retrive the price from them. I never really tested it outside of pancakeswap

for example if you change the

  • variable at line 24 with the value 0x325e343f1de602396e256b67efd1f61c3a6b38bd ( BabySwap Router )
  • variables at line 28 and 46 with the value 0x55d398326f99059fF775485246999027B3197955 ( USDT token )

it should work, on my end it retrives the correct price.

@Greyh4t
Copy link

Greyh4t commented Dec 27, 2021

Hi @Linch1, I tried the method you said and it works great, thanks!

@taewookim
Copy link

taewookim commented Jan 24, 2022

Can this be abstracted to get price of any coin on any evm compaible chains?

How would you get price of token pairs on DEX's?

@Linch1
Copy link
Author

Linch1 commented Jan 24, 2022

@taewookim yeah it can work on any pancakeswap clone on any compatible evm chain, like uniswap ( eth ) or quickswap ( polygon )

@nisar909
Copy link

works fine really appreciate your efforts, I'm trying to get pool liquidity can you guys help me out with that.

@cashy23
Copy link

cashy23 commented Jun 19, 2022

I can use it to display the price of my token on my website?

@nisar909
Copy link

I can use it to display the price of my token on my website?

yes, you can, I work on this project but am stuck on liquidity. can you help me out with that?

@Linch1
Copy link
Author

Linch1 commented Jun 19, 2022

Hello @nisar909 i can tell you the steps to understand the liquidity price

  1. find the liquidity pool address
  1. once you found the liquidity pool address you have to get how many bnb it has inside

  2. calculate how much the bnb inside the pool are worth in dollar

I made a full repo about scanning real time the tokens and their liquidity here if you wanne dive into it, but it has no documentation
https://github.com/Linch1/Web3TokenCharting

@Linch1
Copy link
Author

Linch1 commented Jun 19, 2022

If you want to calcculate the liquidity pool address offchain instead,
you can use this snipped of code that I posted on stackoverflow

https://stackoverflow.com/a/70327791/11005474

@gggman404
Copy link

does the pancake swap api only work for top 1000 tokens?

@Goatghosts
Copy link

If you want to get the same in Python.
https://github.com/Goatghosts/token-price-api-py

@Wantedslv
Copy link

How can I invert the pair? For example default is sell Token1 for BNB, but I want to sell BNB for Token1 (to see price for buying Token1). Because price when I selling Token1 or buying Token1 is different on PCS. Thanks.

@KingMaxine
Copy link

KingMaxine commented Oct 6, 2022

@Wantedslv just edit the path from [token1, token2] to [token2, token1]

@Wantedslv
Copy link

@Wantedslv just edit the path from [token1, token2] to [token2, token1]

@KingMaxine Don't quite understand which line of code do you mean?
I'd tried to replace [token1, token2] to [token2, token1] in the line 49, but it doesn't work.

@callmekidz
Copy link

I need help. I'm trying to figure out how to identify any liquidity that has just been added to the pancake pool. By checking the pair factory, I can only search for newly created pairs, previous pairs cannot be verified. Thanks for your help

@imanrep
Copy link

imanrep commented Nov 4, 2022

I need help. I'm trying to figure out how to identify any liquidity that has just been added to the pancake pool. By checking the pair factory, I can only search for newly created pairs, previous pairs cannot be verified. Thanks for your help

you can use getPair function on 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73 tokenaddress / wbnb

@Linch1
Copy link
Author

Linch1 commented Nov 5, 2022

I need help. I'm trying to figure out how to identify any liquidity that has just been added to the pancake pool. By checking the pair factory, I can only search for newly created pairs, previous pairs cannot be verified. Thanks for your help

To identify whenever someone add liquidity to a pair you can make a subscription to the Mint event,
it is emitted whenever someone adds liquidity to pancakeswap

@jeremfrs
Copy link

Clever solution. Thank you !

@xdayeh
Copy link

xdayeh commented Feb 2, 2023

(async () => {
    const Token     = '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82';
    const abi       = [{"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"},]
    const web3      = new Web3(Web3.givenProvider);
    const contract  = new web3.eth.Contract(abi, '0x10ed43c718714eb63d5aa57b78b54704e256024e');
    const result    = await  contract.methods.getAmountsOut((10 ** 18) + '', [Token, '0xe9e7cea3dedca5984780bafc599bd69add087d56']).call();
    const price     = result[1] / (10 ** 18);
    console.log('$' + price.toFixed(2) );
})();

@rsmith-github
Copy link

This is awesome man thanks for this.

@ChesterInGameconomy
Copy link

I've been working on router contracts for a while now and I have no issues calculating prices from an LP, but there's still 1 thing that i haven't figure it out yet, which is how does the dex figure out the best route for a swap pair to get the best price(minimum slippage)? Example:

  1. Swap 100 FROYO to BUSD, Route: FROYO>CAKE>BUSD.
  2. Swap 10000 FROYO to BUSD, Route: FROYO>BNB>BUSD.

I still haven't work this out this algorithm yet, anyone has any experience or advice on this? I would appreciate any help or ideas!

Thank You!

@trantamcdt92
Copy link

I would like to ask your help to solve my problem. It is the script can't get the price of some tokens which their prices are very small. For example.
0x12F9e38F9e09D9dD84DC39A1f11d236bB9d9c27f
0x3ECd448a623d82E3dAecbeA8CD4Ba1310457dA1b
As I know so far, it seems the decimals of those tokens in bsc scan are smaller than the decimals of actual prices.
If possile please teach me how to update the script to be able get their prices
Thank you very much.

@SantiiRepair
Copy link

I will create a dart package for flutter apps from this code, thanks!

@saveriocastellano
Copy link

@Linch1 isn't it time you make some money with software instead of sharing these bullshits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment