I am trying to query token's prices from Uniswap. I have found the official documentation of Uniswap but it is still not clear for me, as it returns an object that I cannot formulate into an actual price. I am trying to use typescript for this following the example.
Here is the code I am using:
import { ethers } from "ethers";
import { Pool } from "@uniswap/v3-sdk";
import { Token } from "@uniswap/sdk-core";
import { abi as IUniswapV3PoolABI } from "@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json";
interface Immutables {
factory: string;
token0: string;
token1: string;
fee: number;
tickSpacing: number;
maxLiquidityPerTick: ethers.BigNumber;
}
interface State {
liquidity: ethers.BigNumber;
sqrtPriceX96: ethers.BigNumber;
tick: number;
observationIndex: number;
observationCardinality: number;
observationCardinalityNext: number;
feeProtocol: number;
unlocked: boolean;
}
const provider = new ethers.providers.JsonRpcProvider(
"https://mainnet.infura.io/v3/<MYINFURIAURL>"
);
const poolAddress = "0x4e68ccd3e89f51c3074ca5072bbac773960dfa36";
const poolContract = new ethers.Contract(
poolAddress,
IUniswapV3PoolABI,
provider
);
async function getPoolImmutables() {
const [factory, token0, token1, fee, tickSpacing, maxLiquidityPerTick] =
await Promise.all([
poolContract.factory(),
poolContract.token0(),
poolContract.token1(),
poolContract.fee(),
poolContract.tickSpacing(),
poolContract.maxLiquidityPerTick(),
]);
const immutables: Immutables = {
factory,
token0,
token1,
fee,
tickSpacing,
maxLiquidityPerTick,
};
return immutables;
}
async function getPoolState() {
const [liquidity, slot] = await Promise.all([
poolContract.liquidity(),
poolContract.slot0(),
]);
const PoolState: State = {
liquidity,
sqrtPriceX96: slot[0],
tick: slot[1],
observationIndex: slot[2],
observationCardinality: slot[3],
observationCardinalityNext: slot[4],
feeProtocol: slot[5],
unlocked: slot[6],
};
return PoolState;
}
async function main() {
const [immutables, state] = await Promise.all([
getPoolImmutables(),
getPoolState(),
]);
const TokenA = new Token(3, immutables.token0, 6, "ETH", "Ether coin");
const TokenB = new Token(3, immutables.token1, 18, "USDT", "USD Tether");
const poolExample = new Pool(
TokenA,
TokenB,
immutables.fee,
state.sqrtPriceX96.toString(),
state.liquidity.toString(),
state.tick
);
const token0Price = poolExample.token0Price;
const token1Price = poolExample.token1Price;
console.log(`${JSON.stringify(TokenA)}`);
console.log(`${JSON.stringify(TokenB)}`);
console.log(`ETH price: ${JSON.stringify(token0Price)}`);
console.log(`USDT price: ${JSON.stringify(token1Price)}`);
}
main();
It returns me this for the two last logs:
ETH price: {"numerator":[705566737,8761776,105637858,994326226,700219462,14069],"denominator":[0,0,0,0,0,0,4096],"baseCurrency":{"chainId":3,"decimals":6,"symbol":"ETH","name":"Ether coin","isNative":false,"isToken":true,"address":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"},"quoteCurrency":{"chainId":3,"decimals":18,"symbol":"USDT","name":"USD Tether","isNative":false,"isToken":true,"address":"0xdAC17F958D2ee523a2206206994597C13D831ec7"},"scalar":{"numerator":[1000000],"denominator":[660865024,931322574]}}
How do I turn this object into an actual number in typescript?
Also one thing that is not clear, are these the prices of the coins in this pool right? It is odd that there is a "traded pair" and there are two prices for the two tokens being traded against each other. Or is this how they represent the bid/ask gap?
Thanks
token0 price: ${(1 / Number(token0Price.toSignificant(10)))/1000000000000000000000000}
); and console.log(token1 price: ${(1 / Number(token1Price.toSignificant(10)))*1000000000000000000000000}
); give me actually sensible numbers, BUT they seem to be off based on the Uniswap sites price. Eg: this returns 3035 as you said, but on Uniswap this pair is at 3020 which is big difference considering prices.