0

I need to get price of PCS v3 pairs. I see that Pancakeswap makes call to https://nodes.pancakeswap.info/

[
  {
    "data": "...",
    "to": "..."
  },
  "..."
]

with response

{
    "jsonrpc": "2.0",
    "id": 416,
    "result": "..."
}

How can I send the same request via python httpx, or web3py and get the price given that I do know its ABI?

1 Answer 1

1

The https://nodes.pancakeswap.info/ URL is a node endpoint. If you make a simple eth_chainid curl call to it, it'll return 0x38, which is the chain id of the BNB smart chain mainnet.

Although, when you try making a connection to the node from within a web3py Python piece, it's failing to connect. I assume this is because a proxy to the node has some allow list access rules implemented, so that the node won't get flooded by random curious devs like you and me.

Anyway, it's always good to have your own unique & secure node endpoint that you can always rely on from any of the web3 infrastructure providers. I use Chainstack, but you get any of the web3 providers or just grab a quick one for tests off https://chainlist.org/

Now that established that we need a proper node endpoint, let's walk through the actual implementation using web3py.

Since you mention you are interested in a v3 pair, let's get an actual liquidity pair off the pancake.info front end https://pancakeswap.finance/info/v3

Let's pick the top traded liquidity pair here which is USDT-WBNB https://pancakeswap.finance/info/v3/pairs/0x36696169c63e42cd08ce11f5deebbcebae652050

The liquidity pair contract of interest for us hence is 0x36696169C63e42cd08ce11f5deeBbCeBae652050.

To get the price (or the exchange rate for the token pair), we need to make a call to slot0:

(Pancake swap is a Uniswap fork, so we are using Uniswap docs)

What the slot0 call returns, however, is the raw value, that you'll need to convert following the Uniswap V3 math primer https://blog.uniswap.org/uniswap-v3-math-primer

Here's the full implementation with comments.

import json
from web3 import Web3

# Load the PancakeV3Pool ABI from local file. You can get the ABI from https://bscscan.com/address/0x36696169c63e42cd08ce11f5deebbcebae652050#code
with open('PancakeV3Pool_ABI.json', 'r') as file:
    contract_abi = json.load(file)

# Connect to the node
w3 = Web3(Web3.HTTPProvider("NODE_ENDPOINT"))

# Verify connection.
if not w3.is_connected():
    raise Exception('Failed to connect to the node')

# PancakeV3Pool liquidity pair for WBNB-USDT https://pancakeswap.finance/info/v3/pairs/0x36696169c63e42cd08ce11f5deebbcebae652050
contract_address = "0x36696169C63e42cd08ce11f5deeBbCeBae652050"
contract = w3.eth.contract(address=contract_address, abi=contract_abi)

# Make the eth_call to the slot0 function 
result = contract.functions.slot0().call()

# Parse the result from the returned value following the struct https://bscscan.com/address/0x36696169c63e42cd08ce11f5deebbcebae652050#code#F1#L62 // basically just get the first value in the response
sqrtPriceX96 = result[0]

# Calculate the price following Uniswap's methodology because this is a fork of Uniswap. For the calculation walkthrough, see https://blog.uniswap.org/uniswap-v3-math-primer
price = (sqrtPriceX96 / (2**96))**2

# Convert the price per WBNB token to a more readable format
exchange_rate = 1 / price

# Print the exchange rate with 2f as a two-decimal floating number for readability
print(f'The exchange rate is {exchange_rate:.2f} USDT per WBNB.')

Remember to replace NODE_ENDPOINT with your own that works.

2
  • Thanks for taking your time to answer, this is exactly what I needed.
    – LLDimup
    Commented Feb 6 at 12:55
  • just a small note: exchange_rate works if the decimals of both tokens are equal. If not you will have to convert : )
    – LLDimup
    Commented Feb 23 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.