যখন আমরা Uniswap V3 এর লিকুইডিটি পুল (ট্রেড-টু-পুল) তে লিকুইডিটি যোগ করি, তখন NonfungiblePositionManager চুক্তিটি একটি তৈরি NFT ফেরত দেয় যা আমাদের লিকুইডিটি যোগ করার প্রমাণ হিসাবে। প্রথম ধাপে, আমরা একটি রুটিং চুক্তি ব্যবহার করে একটি সংশ্লিষ্ট NonfungiblePositionManager চুক্তি ঠিকানা অর্জন করি, এবং তারপর NonfungiblePositionManager চুক্তির balanceOf পদ্ধতি ব্যবহার করে একটি নির্দিষ্ট ওয়ালেট ঠিকানার জন্য অবস্থান NFT সংখ্যা অর্জন করি। এরপরে, টোকেন অফ ওয়ানার বাই ইনডেক্স পদ্ধতি ব্যবহার করে এই অবস্থানগুলির টোকেন আইডিগুলি এনএফটি-তে পাওয়া যায়, এবং এই টোকেন আইডিগুলির সাথে আপনি অবস্থানগুলি পদ্ধতি ব্যবহার করে এই অবস্থানগুলির জন্য বিস্তারিত তথ্য অনুসন্ধান করতে পারেন।
এখানে পরীক্ষার কোড দেওয়া হলঃ
“javascript
// Uniswap ABI
const ABI_UniswapV3Router =
[
const ABI_NonfungiblePositionManager =
{
// Uniswap চুক্তির ঠিকানা
const UniswapV3RouterAddress =
// সাধারণ পরিমাণ const TWO = বিগইন্ট (২) const Q192 = (TWO ** BigInt ((96)) ** TWO const Q96 = (TWO ** BigInt ((96))
// পাঠযোগ্য সংখ্যায় রূপান্তরিত function toAmount ((s, decimals) { return Number (((BigDecimal ((BigInt)) s)) / BigDecimal ((Math.pow ((10, decimals))).toString (()) }
// পাঠযোগ্য সংখ্যার বিপরীত রূপান্তর করে গণনা করার জন্য ব্যবহৃত সংখ্যায় function toInnerAmount ((n, decimals) { return (BigDecimal ((n) * BigDecimal ((Math.pow ((10, decimals))).toFixed ((0) }
function main (() {
// যে ওয়ালেটের ঠিকানাটি অনুসন্ধান করা হচ্ছে
// const walletAddress = exchange.IO ((
// 获取Uniswap V3的positionManager合约的地址
exchange.IO("abi", UniswapV3RouterAddress, ABI_UniswapV3Router)
const NonfungiblePositionManagerAddress = exchange.IO("api", UniswapV3RouterAddress, "positionManager")
Log("NonfungiblePositionManagerAddress:", NonfungiblePositionManagerAddress)
// 注册positionManager合约的ABI
exchange.IO("abi", NonfungiblePositionManagerAddress, ABI_NonfungiblePositionManager)
// 查询当前账户拥有的Uniswap V3 positions NFT数量
var nftBalance = exchange.IO("api", NonfungiblePositionManagerAddress, "balanceOf", walletAddress)
Log("nftBalance:", nftBalance)
// 查询这些NFT的TokenId
var nftTokenIds = []
for (var i = 0 ; i < nftBalance; i++) {
var nftTokenId = exchange.IO("api", NonfungiblePositionManagerAddress, "tokenOfOwnerByIndex", walletAddress, i)
nftTokenIds.push(nftTokenId)
Log("nftTokenId:", nftTokenId)
}
// 根据positions NFT的tokenId查询流动性头寸详细信息
var positions = []
for (var i = 0; i < nftTokenIds.length; i++) {
var pos = exchange.IO("api", NonfungiblePositionManagerAddress, "positions", nftTokenIds[i])
Log("pos:", pos)
// 解析头寸数据
positions.push(parsePosData(pos))
}
var tbl = {
type : "table",
title : "LP",
cols : ["range(token0计价)", "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”))
লগ ((
ফাংশন পার্সপোসডাটা ((পোসডাটা) {
/*
{
var token0Symbol = null
var token1Symbol = null
// 根据代币地址判断token,记录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 ,获取兑换池的相关数据
var poolInfo = getPool(token0Symbol.address, token1Symbol.address, posData.fee)
Log("poolInfo:", poolInfo)
/* 数据范例
{
"slot0":{
"sqrtPriceX96":"4403124416947951698847768103","tick":"-57804","observationIndex":136,"observationCardinality":300,
"observationCardinalityNext":300,"feeProtocol":0,"unlocked":true
}
}
*/
// 计算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 && currentTick < posData.tickUpper) {
amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtPrice) / (sqrtPrice * sqrtRatioB)))
amount1wei = Math.floor(posData.liquidity * (sqrtPrice - sqrtRatioA))
}
var rangeToken0 = (1.0001 ** -posData.tickUpper) + " ~ " + (1.0001 ** -posData.tickLower)
var amount0 = toAmount(amount0wei, token0Symbol.decimals)
var amount1 = toAmount(amount1wei, token1Symbol.decimals)
return [rangeToken0, token0Symbol.symbol,
ক্রিপ্টো জোএটা খুব শক্তিশালী!