-
-
Save BlockmanCodes/1f30ca6289b40472e84344d76a02894a to your computer and use it in GitHub Desktop.
Get spot prices on Uniswap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
INFURA_URL=<your_url> | |
ETHERSCAN_API_KEY=<your_api_key> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const axios = require('axios') | |
require('dotenv').config() | |
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY | |
exports.getAbi = async (address) => { | |
const url = `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}&apikey=${ETHERSCAN_API_KEY}` | |
const res = await axios.get(url) | |
const abi = JSON.parse(res.data.result) | |
return abi | |
} | |
exports.getPoolImmutables = async (poolContract) => { | |
const [token0, token1, fee] = await Promise.all([ | |
poolContract.token0(), | |
poolContract.token1(), | |
poolContract.fee(), | |
]) | |
const immutables = { | |
token0: token0, | |
token1: token1, | |
fee: fee | |
} | |
return immutables | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "uniswapbot", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"keywords": [], | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"@uniswap/v3-sdk": "^3.8.2", | |
"axios": "^0.26.1", | |
"dotenv": "^16.0.0", | |
"ethers": "^5.6.2" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { ethers } = require("ethers"); | |
const { abi: IUniswapV3PoolABI } = require("@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json"); | |
const { abi: QuoterABI } = require("@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json"); | |
const { getAbi, getPoolImmutables } = require('./helpers') | |
require('dotenv').config() | |
const INFURA_URL = process.env.INFURA_URL | |
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY | |
const provider = new ethers.providers.JsonRpcProvider(INFURA_URL) | |
const poolAddress = '0xcbcdf9626bc03e24f779434178a73a0b4bad62ed' | |
const quoterAddress = "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6" | |
const getPrice = async (inputAmount) => { | |
const poolContract = new ethers.Contract( | |
poolAddress, | |
IUniswapV3PoolABI, | |
provider | |
) | |
const tokenAddress0 = await poolContract.token0(); | |
const tokenAddress1 = await poolContract.token1(); | |
const tokenAbi0 = await getAbi(tokenAddress0) | |
const tokenAbi1 = await getAbi(tokenAddress1) | |
const tokenContract0 = new ethers.Contract( | |
tokenAddress0, | |
tokenAbi0, | |
provider | |
) | |
const tokenContract1 = new ethers.Contract( | |
tokenAddress1, | |
tokenAbi1, | |
provider | |
) | |
const tokenSymbol0 = await tokenContract0.symbol() | |
const tokenSymbol1 = await tokenContract1.symbol() | |
const tokenDecimals0 = await tokenContract0.decimals() | |
const tokenDecimals1 = await tokenContract1.decimals() | |
const quoterContract = new ethers.Contract( | |
quoterAddress, | |
QuoterABI, | |
provider | |
) | |
const immutables = await getPoolImmutables(poolContract) | |
const amountIn = ethers.utils.parseUnits( | |
inputAmount.toString(), | |
tokenDecimals0 | |
) | |
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle( | |
immutables.token0, | |
immutables.token1, | |
immutables.fee, | |
amountIn, | |
0 | |
) | |
const amountOut = ethers.utils.formatUnits(quotedAmountOut, tokenDecimals1) | |
console.log('=========') | |
console.log(`${inputAmount} ${tokenSymbol0} can be swapped for ${amountOut} ${tokenSymbol1}`) | |
console.log('=========') | |
} | |
getPrice(1) |
The "is not a function" error you get when calling e.g. USDC based pool is caused by the fact that USDC is using a proxy which doesn't have either the symbol info, the decimals info or both. One solution is to hardcode those values when making the call.
I am not able to import Pool in node js
I used
const {Pool}= require('@uniswap/v3-sdk');
and module not found error is coming
@BlockmanCodes thanks for your script, works perfect. But how to invert for example USDT-SAITO to SAITO-USDT?
@Wantedslv You should be able to use the function quoteExactOutputSingle in the Quoter contract.
Getting this error: function selector was not recognized and there's no fallback function. Any suggestion here?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried to use this example to get price of the pair that includes USDC (e.g. WBTC-USDC) on Mainnet and got an error. What could be a possible source of the problem? Perhaps that USDC has proxy contract?