Когда мы добавляем ликвидность в пуль ликвидности Uniswap V3 (пуль торговых пар), контракт NonfungiblePositionManager возвращает нам отчеканенный NFT в качестве доказательства добавления ликвидности.
Первый шаг состоит в том, чтобы использовать контракт маршрутизатора для получения адреса соответствующего контракта NonfungiblePositionManager, а затем использовать метод balanceOf контракта NonfungiblePositionManager для получения количества позиций NFT для указанного адреса кошелька.
Затем используйте метод tokenOfOwnerByIndex, чтобы получить tokenId этих позиций NFT, с этими tokenId вы можете использовать метод позиций, чтобы продолжать запрос на конкретные детали этих позиций.
Следующий код испытания:
“
// Uniswap ABI
const ABI_UniswapV3Router =
[
const ABI_NonfungiblePositionManager =
[{
// Адрес контракта Uniswap
const UniswapV3RouterAddress =
// общая постоянная const TWO = BigInt(2) const Q192 = (ДВА ** BigInt(96)) ** ДВА const Q96 = (TWO ** BigInt ((96))
// Преобразовать в читаемую сумму функция toAmount ((s, десятичные знаки) { возвращение числа (BigDecimal) (BigInt) (s) / (BigDecimal) (Math.pow), десятичных знаков (toString)) Я не знаю.
// Обратное преобразование от читаемой суммы к сумме, используемой для передачи параметров и расчетов функция toInnerAmount ((n, десятичные знаки) { return (BigDecimal(n) * BigDecimal(Math.pow(10, десятичные цифры))).toFixed(0) Я не знаю.
Функция основной
// Адрес кошелька для поиска
// const walletAddress = exchange.IO(
// Get the address of Uniswap V3's positionManager contract
exchange.IO("abi", UniswapV3RouterAddress, ABI_UniswapV3Router)
const NonfungiblePositionManagerAddress = exchange.IO("api", UniswapV3RouterAddress, "positionManager")
Log("NonfungiblePositionManagerAddress:", NonfungiblePositionManagerAddress)
// Register ABI for positionManager contracts
exchange.IO("abi", NonfungiblePositionManagerAddress, ABI_NonfungiblePositionManager)
// Query the number of Uniswap V3 positions NFT owned by the current account
var nftBalance = exchange.IO("api", NonfungiblePositionManagerAddress, "balanceOf", walletAddress)
Log("nftBalance:", nftBalance)
// Query the TokenId of these NFTs
var nftTokenIds = []
for (var i = 0 ; i < nftBalance; i++) {
var nftTokenId = exchange.IO("api", NonfungiblePositionManagerAddress, "tokenOfOwnerByIndex", walletAddress, i)
nftTokenIds.push(nftTokenId)
Log("nftTokenId:", nftTokenId)
}
// Query liquidity position details based on the tokenId of the positions NFT
var positions = []
for (var i = 0; i < nftTokenIds.length; i++) {
var pos = exchange.IO("api", NonfungiblePositionManagerAddress, "positions", nftTokenIds[i])
Log("pos:", pos)
// Parsing position data
positions.push(parsePosData(pos))
}
var tbl = {
type : "table",
title : "LP",
cols : ["range(token0 valuation)", "token0", "token1", "fee", "lowerPrice(tickLower)", "upperPrice(tickUpper)", "liquidity", "amount0", "amount1"],
rows : positions
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
// Запишите информацию о токенах, запрошенных через coingecko.com
var tokens = []
функция init() {
// При инициализации, получить информацию о всех токенов для запроса
var res = JSON.parse ((HttpQuery))https://tokens.coingecko.com/uniswap/all.json”))
Log ((
Функция parsePosData ((posData) {
/*
{ Это не так.
Объявление:
var token0Symbol = null
var token1Symbol = null
// Determine the token according to the address of the token, record the information about the token
for (var i in tokens) {
if (tokens[i].address.toLowerCase() == posData.token0.toLowerCase()) {
token0Symbol = tokens[i]
} else if (tokens[i].address.toLowerCase() == posData.token1.toLowerCase()) {
token1Symbol = tokens[i]
}
}
if (!token0Symbol || !token1Symbol) {
Log("token0Symbol:", token0Symbol, ", token1Symbol:", token1Symbol)
throw "token not found"
}
// get Pool , obtaining data about the exchange pool
var poolInfo = getPool(token0Symbol.address, token1Symbol.address, posData.fee)
Log("poolInfo:", poolInfo)
/* Data examples
{
"slot0":{
"sqrtPriceX96":"4403124416947951698847768103","tick":"-57804","observationIndex":136,"observationCardinality":300,
"observationCardinalityNext":300,"feeProtocol":0,"unlocked":true
}
}
*/
// Calculate token0Amount, token1Amount
var currentTick = parseInt(poolInfo.slot0.tick)
var lowerPrice = 1.0001 ** posData.tickLower
var upperPrice = 1.0001 ** posData.tickUpper
var sqrtRatioA = Math.sqrt(lowerPrice)
var sqrtRatioB = Math.sqrt(upperPrice)
var sqrtPrice = Number(BigFloat(poolInfo.slot0.sqrtPriceX96) / Q96)
var amount0wei = 0
var amount1wei = 0
if (currentTick <= posData.tickLower) {
amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtRatioA) / (sqrtRatioA * sqrtRatioB)))
} else if (currentTick > posData.tickUpper) {
amount1wei = Math.floor(posData.liquidity * (sqrtRatioB - sqrtRatioA))
} else if (currentTick >= posData.tickLower && cu