In this example we will look at AVAX price and we will take the WAVAX / USDT pool on pangolin at this address : 0x9ee0a4e21bd333a6bb2ab298194320b8daa26516
In order to make requests to a contract we need its ABI, it's like a definition of its functions and variables in JSON format.
To retrieve it you can go on : and click copy ABI.
You can paste it on a new file : pool.json
Now we can read it from our python script (we also need to import the json module)
import json
with open("Pool.json") as poolFile :
poolABI = json.load(poolFile )
We need to transform our address to a Checksum valid address or web3.py won't accept it.
Our program is now :
bot.py
from web3 import Web3
import json
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:9650/ext/bc/C/rpc'))
with open("Pool.json") as poolFile :
poolABI = json.load(poolFile )
liquidityContract = w3.eth.contract(address=w3.toChecksumAddress("0x9ee0a4e21bd333a6bb2ab298194320b8daa26516"), abi=poolABI)
Now we need to make a call to retrieve reserves of each token on this pool
(It exists two types of call to a contract one which just read on the blockchain the informations : we call it with .call() and another one which write and really interact with the blockchain : we call it with .transact() )
The function returns a list of 3 : reserveToken0 , reserveToken1 and timestamp of last update.
Our problem is we don't know which of token0 or token1 is WAVAX or USDT we could check manually but we want our bot to work even with other pool in unknown orders so we need to check which one is which.
if token0Symbol == "WAVAX" :
price = reserveToken1/10**token1Decimals / reserveToken0/10**token0Decimals
else :
price = reserveToken0/10**token0Decimals / reserveToken1/10**token1Decimals
print("The current price of AVAX is {:4.2f} USDT".format(price)
Final code
bot.py
from web3 import Web3
import json
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:9650/ext/bc/C/rpc'))
with open("pool.json") as poolFile :
poolABI = json.load(poolFile )
with open("ERC20.json") as erc20File:
ERC20ABI = json.load(erc20File)
liquidityContract = w3.eth.contract(address=w3.toChecksumAddress("0x9ee0a4e21bd333a6bb2ab298194320b8daa26516"), abi=poolABI)
reserves = liquidityContract.functions.getReserves().call()
reserveToken0 = reserves[0]
reserveToken1 = reserves[1]
token0Address = liquidityContract.functions.token0().call()
token1Address = liquidityContract.functions.token1().call()
token0 = w3.eth.contract(address=w3.toChecksumAddress(token0Address), abi=ERC20ABI)
token1 = w3.eth.contract(address=w3.toChecksumAddress(token1Address), abi=ERC20ABI)
token0Symbol = token0.functions.symbol().call()
token0Decimals = token0.functions.decimals().call()
token1Symbol = token1.functions.symbol().call()
token1Decimals = token1.functions.decimals().call()
if token0Symbol == "WAVAX" :
price = (reserveToken1/10**token1Decimals) / (reserveToken0/10**token0Decimals)
else :
price = (reserveToken0/10**token0Decimals) / (reserveToken1/10**token1Decimals)
print("The current price of AVAX is {:4.2f} USDT".format(price))
Now that we have the address of which we can query the blockchain to determine who they are.
In order to do so we need to instantiate a contract for each of them and for that we need their ABIs.
We just need a basic ERC20 ABI so we're gonna grab one from the explorer (like here : )