@swaptoshi/dex-module
Version:
Klayr decentralized exchange (dex) on-chain module
481 lines • 28.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NonfungiblePositionManager = void 0;
const codec_1 = require("@klayr/codec");
const utils = require("@klayr/utils");
const IPFSHash = require("ipfs-only-hash");
const int_1 = require("../library/int");
const position_info_1 = require("../position_info");
const pool_1 = require("../pool");
const schema_1 = require("../../schema");
const PositionKey = require("../library/periphery/position_key");
const PoolAddress = require("../library/periphery/pool_address");
const TickMath = require("../library/core/tick_math");
const LiquidityAmounts = require("../library/periphery/liquidity_amounts");
const FullMath = require("../library/core/full_math");
const FixedPoint128 = require("../library/core/fixed_point_128");
const NFTDescriptor = require("../library/periphery/nft_descriptor");
const token_symbol_1 = require("../token_symbol");
const collect_position_1 = require("../../events/collect_position");
const decrease_liquidity_1 = require("../../events/decrease_liquidity");
const increase_liquidity_1 = require("../../events/increase_liquidity");
const tokenuri_created_1 = require("../../events/tokenuri_created");
const constants_1 = require("../../constants");
const tokenuri_destroyed_1 = require("../../events/tokenuri_destroyed");
class NonfungiblePositionManager {
constructor(positionManager, stores, events, genesisConfig, dexConfig, moduleName) {
this.collectionId = Buffer.alloc(0);
this.poolAddress = Buffer.alloc(0);
this.name = '';
this.symbol = '';
this.address = constants_1.POSITION_MANAGER_ADDRESS;
this.chainId = Buffer.alloc(0);
this.mutableDependencyReady = false;
this.immutableDependencyReady = false;
Object.assign(this, utils.objects.cloneDeep(positionManager));
this.collectionId = PoolAddress.computePoolId(positionManager.poolAddress);
this.events = events;
this.chainId = Buffer.from(genesisConfig.chainID, 'hex');
this.dexConfig = dexConfig;
this.poolStore = stores.get(pool_1.PoolStore);
this.tokenSymbolStore = stores.get(token_symbol_1.TokenSymbolStore);
this.positionInfoStore = stores.get(position_info_1.PositionInfoStore);
this.moduleName = moduleName;
}
toJSON() {
return utils.objects.cloneDeep({
poolAddress: this.poolAddress,
name: this.name,
symbol: this.symbol,
});
}
addMutableDependencies(context, tokenMethod, nftMethod) {
if (this.mutableDependencyReady || this.immutableDependencyReady) {
throw new Error('this instance dependencies already been configured');
}
this.mutableContext = context;
this.immutableContext = this.mutableContext;
this.tokenMethod = tokenMethod;
this.nftMethod = nftMethod;
this.immutableDependencyReady = true;
this.mutableDependencyReady = true;
}
addImmutableDependencies(context, tokenMethod, nftMethod) {
if (this.mutableDependencyReady || this.immutableDependencyReady) {
throw new Error('this instance dependencies already been configured');
}
this.immutableContext = context;
this.tokenMethod = tokenMethod;
this.nftMethod = nftMethod;
this.immutableDependencyReady = true;
}
setSender(senderAddress) {
if (this.mutableContext) {
this.mutableContext.senderAddress = senderAddress;
}
else if (this.immutableContext) {
this.immutableContext.senderAddress = senderAddress;
}
}
async createAndInitializePoolIfNecessary(token0, token0Symbol, token0Decimal, token1, token1Symbol, token1Decimal, fee, sqrtPriceX96) {
this._checkMutableDependency();
if (token0.compare(token1) >= 0)
throw new Error('invalid token order');
let pool;
try {
pool = await this.poolStore.getMutablePool(this.mutableContext, token0, token1, fee);
const { sqrtPriceX96: sqrtPriceX96Existing } = pool.slot0;
if (sqrtPriceX96Existing === '0')
await pool.initialize(sqrtPriceX96);
}
catch {
pool = await this.poolStore.createPool(this.mutableContext, token0, token0Symbol, token0Decimal, token1, token1Symbol, token1Decimal, fee);
await pool.initialize(sqrtPriceX96);
}
this.poolAddress = pool.address;
this.collectionId = PoolAddress.computePoolId(pool.address);
return pool;
}
async getPositions(tokenId) {
this._checkImmutableDependency();
const nft = await this.nftMethod.getNFT(this.immutableContext.context, PositionKey.getNFTId(this.chainId, this.collectionId, tokenId));
const dexAttribute = nft.attributesArray.find(t => t.module === this.moduleName);
if (!dexAttribute)
throw new Error(`attributes '${this.moduleName}' doesnt exist on nft ${PositionKey.getNFTId(this.chainId, this.collectionId, tokenId).toString('hex')}`);
const positionBuf = dexAttribute.attributes;
return codec_1.codec.decode(schema_1.dexNFTAttributeSchema, positionBuf);
}
async mint(params) {
this._checkMutableDependency();
this._checkDeadline(params.deadline);
let liquidity = int_1.Uint128.from(0);
let amount0 = int_1.Uint256.from(0);
let amount1 = int_1.Uint256.from(0);
const [_liquidity, _amount0, _amount1] = await this._addLiquidity({
token0: params.token0,
token1: params.token1,
fee: params.fee,
recipient: this.address,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
amount0Desired: params.amount0Desired,
amount1Desired: params.amount1Desired,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min,
});
liquidity = int_1.Uint128.from(_liquidity);
amount0 = int_1.Uint256.from(_amount0);
amount1 = int_1.Uint256.from(_amount1);
const positionKey = PositionKey.compute(this.address, params.tickLower, params.tickUpper);
const { feeGrowthInside0LastX128, feeGrowthInside1LastX128 } = await this.positionInfoStore.get(this.mutableContext.context, this.positionInfoStore.getKey(this.poolAddress, positionKey));
const position = {
token0: params.token0,
token1: params.token1,
fee: params.fee,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidity: liquidity.toString(),
feeGrowthInside0LastX128,
feeGrowthInside1LastX128,
tokensOwed0: '0',
tokensOwed1: '0',
};
const tokenId = await this.nftMethod.getNextAvailableIndex(this.mutableContext.context, this.collectionId);
await this.nftMethod.create(this.mutableContext.context, params.recipient, this.collectionId, [
{
module: this.moduleName,
attributes: codec_1.codec.encode(schema_1.dexNFTAttributeSchema, position),
},
]);
const { tokenURI } = await this._saveTokenURI(tokenId.toString());
const events = this.events.get(increase_liquidity_1.IncreaseLiquidityEvent);
events.add(this.mutableContext.context, {
tokenId: PositionKey.getNFTId(this.chainId, this.collectionId, tokenId.toString()),
ownerAddress: params.recipient,
liquidity: liquidity.toString(),
amount0: amount0.toString(),
amount1: amount1.toString(),
}, [this.poolAddress, this.mutableContext.senderAddress]);
const tokenUriEvent = this.events.get(tokenuri_created_1.TokenURICreatedEvent);
tokenUriEvent.add(this.mutableContext.context, {
tokenURI,
tokenId: PositionKey.getNFTId(this.chainId, this.collectionId, tokenId.toString()),
}, [this.mutableContext.senderAddress]);
return [tokenId.toString(), liquidity.toString(), amount0.toString(), amount1.toString()];
}
async increaseLiquidity(params) {
this._checkMutableDependency();
this._checkDeadline(params.deadline);
const position = await this.getPositions(params.tokenId);
let liquidity = int_1.Uint128.from(0);
let amount0 = int_1.Uint256.from(0);
let amount1 = int_1.Uint256.from(0);
const [_liquidity, _amount0, _amount1] = await this._addLiquidity({
token0: position.token0,
token1: position.token1,
fee: position.fee,
tickLower: position.tickLower,
tickUpper: position.tickUpper,
amount0Desired: params.amount0Desired,
amount1Desired: params.amount1Desired,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min,
recipient: this.address,
});
liquidity = int_1.Uint128.from(_liquidity);
amount0 = int_1.Uint256.from(_amount0);
amount1 = int_1.Uint256.from(_amount1);
const positionKey = PositionKey.compute(this.address, position.tickLower, position.tickUpper);
const { feeGrowthInside0LastX128, feeGrowthInside1LastX128 } = await this.positionInfoStore.get(this.mutableContext.context, this.positionInfoStore.getKey(this.poolAddress, positionKey));
position.tokensOwed0 = int_1.Uint128.from(position.tokensOwed0)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside0LastX128).sub(position.feeGrowthInside0LastX128).toString(), position.liquidity, FixedPoint128.Q128))
.toString();
position.tokensOwed1 = int_1.Uint128.from(position.tokensOwed1)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside1LastX128).sub(position.feeGrowthInside1LastX128).toString(), position.liquidity, FixedPoint128.Q128))
.toString();
position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128;
position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128;
position.liquidity = int_1.Uint128.from(position.liquidity).add(liquidity).toString();
await this._savePosition(params.tokenId, position);
const nft = await this.nftMethod.getNFT(this.mutableContext.context, PositionKey.getNFTId(this.chainId, this.collectionId, params.tokenId));
const events = this.events.get(increase_liquidity_1.IncreaseLiquidityEvent);
events.add(this.mutableContext.context, {
tokenId: PositionKey.getNFTId(this.chainId, this.collectionId, params.tokenId),
ownerAddress: nft.owner,
liquidity: liquidity.toString(),
amount0: amount0.toString(),
amount1: amount1.toString(),
}, [this.poolAddress, this.mutableContext.senderAddress]);
return [liquidity.toString(), amount0.toString(), amount1.toString()];
}
async decreaseLiquidity(params) {
this._checkMutableDependency();
await this._isAuthorizedForToken(this.mutableContext.senderAddress, params.tokenId);
this._checkDeadline(params.deadline);
let amount0 = int_1.Uint256.from(0);
let amount1 = int_1.Uint256.from(0);
if (int_1.Uint128.from(params.liquidity).lte(0))
throw new Error('params.liquidity cant be negative');
const position = await this.getPositions(params.tokenId);
const positionLiquidity = position.liquidity;
if (int_1.Uint128.from(positionLiquidity).lt(params.liquidity))
throw new Error('invalid params.liquidity');
const originalSender = this.mutableContext.senderAddress;
const pool = await this.poolStore.getMutablePool(this.mutableContext, position.token0, position.token1, position.fee);
pool.setSender(this.address);
const [_amount0, _amount1] = await pool.burn(position.tickLower, position.tickUpper, params.liquidity);
amount0 = int_1.Uint256.from(_amount0);
amount1 = int_1.Uint256.from(_amount1);
if (amount0.lt(params.amount0Min) || amount1.lt(params.amount1Min))
throw new Error('Price slippage check');
const positionKey = PositionKey.compute(this.address, position.tickLower, position.tickUpper);
const { feeGrowthInside0LastX128, feeGrowthInside1LastX128 } = await this.positionInfoStore.get(this.mutableContext.context, this.positionInfoStore.getKey(this.poolAddress, positionKey));
position.tokensOwed0 = int_1.Uint128.from(position.tokensOwed0)
.add(amount0)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside0LastX128).sub(position.feeGrowthInside0LastX128).toString(), positionLiquidity, FixedPoint128.Q128))
.toString();
position.tokensOwed1 = int_1.Uint128.from(position.tokensOwed1)
.add(amount1)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside1LastX128).sub(position.feeGrowthInside1LastX128).toString(), positionLiquidity, FixedPoint128.Q128))
.toString();
position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128;
position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128;
position.liquidity = int_1.Uint128.from(positionLiquidity).sub(params.liquidity).toString();
await this._savePosition(params.tokenId, position);
const events = this.events.get(decrease_liquidity_1.DecreaseLiquidityEvent);
events.add(this.mutableContext.context, {
tokenId: PositionKey.getNFTId(this.chainId, this.collectionId, params.tokenId),
liquidity: params.liquidity,
amount0: amount0.toString(),
amount1: amount1.toString(),
}, [this.poolAddress, this.mutableContext.senderAddress]);
pool.setSender(originalSender);
return [amount0.toString(), amount1.toString()];
}
async collect(params) {
this._checkMutableDependency();
await this._isAuthorizedForToken(this.mutableContext.senderAddress, params.tokenId);
if (int_1.Uint128.from(params.amount0Max).lte(0) && int_1.Uint128.from(params.amount1Max).lte(0))
throw new Error('invalid params amount max');
const recipient = params.recipient.compare(Buffer.alloc(0)) === 0 ? this.address : params.recipient;
const position = await this.getPositions(params.tokenId);
let { tokensOwed0, tokensOwed1 } = position;
const originalSender = this.mutableContext.senderAddress;
const pool = await this.poolStore.getMutablePool(this.mutableContext, position.token0, position.token1, position.fee);
pool.setSender(this.address);
if (int_1.Uint128.from(position.liquidity).gt(0)) {
await pool.burn(position.tickLower, position.tickUpper, '0');
const { feeGrowthInside0LastX128, feeGrowthInside1LastX128 } = await this.positionInfoStore.get(this.mutableContext.context, this.positionInfoStore.getKey(this.poolAddress, PositionKey.compute(this.address, position.tickLower, position.tickUpper)));
tokensOwed0 = int_1.Uint128.from(tokensOwed0)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside0LastX128).sub(position.feeGrowthInside0LastX128).toString(), position.liquidity, FixedPoint128.Q128))
.toString();
tokensOwed1 = int_1.Uint128.from(tokensOwed1)
.add(FullMath.mulDiv(int_1.Uint256.from(feeGrowthInside1LastX128).sub(position.feeGrowthInside1LastX128).toString(), position.liquidity, FixedPoint128.Q128))
.toString();
position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128;
position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128;
}
const amount0Collect = int_1.Uint128.from(params.amount0Max).gt(tokensOwed0) ? tokensOwed0 : params.amount0Max;
const amount1Collect = int_1.Uint128.from(params.amount1Max).gt(tokensOwed1) ? tokensOwed1 : params.amount1Max;
const [amount0, amount1] = await pool.collect(recipient, position.tickLower, position.tickUpper, amount0Collect, amount1Collect);
position.tokensOwed0 = int_1.Uint128.from(tokensOwed0).sub(amount0Collect).toString();
position.tokensOwed1 = int_1.Uint128.from(tokensOwed1).sub(amount1Collect).toString();
await this._savePosition(params.tokenId, position);
const events = this.events.get(collect_position_1.CollectPositionEvent);
events.add(this.mutableContext.context, {
tokenId: PositionKey.getNFTId(this.chainId, this.collectionId, params.tokenId),
recipientAddress: recipient,
amount0Collect,
amount1Collect,
}, [this.poolAddress, recipient]);
pool.setSender(originalSender);
return [amount0, amount1];
}
async burn(tokenId) {
this._checkMutableDependency();
await this._isAuthorizedForToken(this.mutableContext.senderAddress, tokenId);
const position = await this.getPositions(tokenId);
if (!int_1.Uint128.from(position.liquidity).eq(0) || !int_1.Uint128.from(position.tokensOwed0).eq(0) || !int_1.Uint128.from(position.tokensOwed1).eq(0))
throw new Error('Not cleared');
const tokenURI = await this.tokenURI(tokenId);
const nftId = PositionKey.getNFTId(this.chainId, this.collectionId, tokenId);
const nft = await this.nftMethod.getNFT(this.mutableContext.context, nftId);
await this.nftMethod.destroy(this.mutableContext.context, nft.owner, nftId);
const events = this.events.get(tokenuri_destroyed_1.TokenURIDestroyedEvent);
events.add(this.mutableContext.context, { tokenURI, tokenId: nftId }, [this.poolAddress, this.mutableContext.senderAddress]);
}
async tokenURI(tokenId) {
this._checkImmutableDependency();
const nft = await this.nftMethod.getNFT(this.immutableContext.context, PositionKey.getNFTId(this.chainId, this.collectionId, tokenId));
const tokenUriAttribute = nft.attributesArray.find(t => t.module === constants_1.TOKENURI_ATTTRIBUTE);
if (!tokenUriAttribute)
throw new Error(`attributes '${constants_1.TOKENURI_ATTTRIBUTE}' doesnt exist on nft ${PositionKey.getNFTId(this.chainId, this.collectionId, tokenId).toString('hex')}`);
return codec_1.codec.decode(schema_1.tokenUriNFTAttributeSchema, tokenUriAttribute.attributes).tokenURI;
}
async getMetadata(tokenId) {
this._checkImmutableDependency();
const { token0, token1, fee, tickLower, tickUpper } = await this.getPositions(tokenId);
const pool = await this.poolStore.getImmutablePool(this.immutableContext, token0, token1, fee);
const baseTokenAddress = token0;
const quoteTokenAddress = token1;
const { tick } = pool.slot0;
const baseToken = await this.tokenSymbolStore.get(this.immutableContext.context, this.tokenSymbolStore.getKey(baseTokenAddress));
const quoteToken = await this.tokenSymbolStore.get(this.immutableContext.context, this.tokenSymbolStore.getKey(quoteTokenAddress));
const uri = NFTDescriptor.constructTokenURI({
config: this.dexConfig,
tokenId,
quoteTokenAddress,
baseTokenAddress,
quoteTokenSymbol: quoteToken.symbol,
baseTokenSymbol: baseToken.symbol,
quoteTokenDecimals: quoteToken.decimal.toString(),
baseTokenDecimals: baseToken.decimal.toString(),
flipRatio: false,
tickLower,
tickUpper,
tickCurrent: tick,
tickSpacing: pool.tickSpacing,
fee,
poolAddress: pool.address,
});
const encodedJSON = uri.substring('data:application/json;base64,'.length);
const decodedJSON = Buffer.from(encodedJSON, 'base64').toString('utf8');
return JSON.parse(decodedJSON);
}
async total(tokenId, sqrtRatioX96) {
this._checkImmutableDependency();
const [amount0Principal, amount1Principal] = await this.principal(tokenId, sqrtRatioX96);
const [amount0Fee, amount1Fee] = await this.fees(tokenId);
return [int_1.Uint256.from(amount0Principal).add(amount0Fee).toString(), int_1.Uint256.from(amount1Principal).add(amount1Fee).toString()];
}
async principal(tokenId, sqrtRatioX96) {
this._checkImmutableDependency();
const { tickLower, tickUpper, liquidity } = await this.getPositions(tokenId);
return LiquidityAmounts.getAmountsForLiquidity(sqrtRatioX96, TickMath.getSqrtRatioAtTick(tickLower), TickMath.getSqrtRatioAtTick(tickUpper), liquidity);
}
async fees(tokenId) {
this._checkImmutableDependency();
const { token0, token1, fee, tickLower, tickUpper, liquidity, feeGrowthInside0LastX128: positionFeeGrowthInside0LastX128, feeGrowthInside1LastX128: positionFeeGrowthInside1LastX128, tokensOwed0, tokensOwed1, } = await this.getPositions(tokenId);
return this._fees({
token0,
token1,
fee,
tickLower,
tickUpper,
liquidity,
positionFeeGrowthInside0LastX128,
positionFeeGrowthInside1LastX128,
tokensOwed0,
tokensOwed1,
});
}
async _fees(feeParams) {
let amount0 = int_1.Uint256.from(0);
let amount1 = int_1.Uint256.from(0);
const pool = await this.poolStore.getImmutablePool(this.immutableContext, feeParams.token0, feeParams.token1, feeParams.fee);
const [poolFeeGrowthInside0LastX128, poolFeeGrowthInside1LastX128] = await this._getFeeGrowthInside(pool, feeParams.tickLower, feeParams.tickUpper);
amount0 = int_1.Uint256.from(FullMath.mulDiv(int_1.Uint256.from(poolFeeGrowthInside0LastX128).sub(feeParams.positionFeeGrowthInside0LastX128).toString(), feeParams.liquidity, FixedPoint128.Q128)).add(feeParams.tokensOwed0);
amount1 = int_1.Uint256.from(FullMath.mulDiv(int_1.Uint256.from(poolFeeGrowthInside1LastX128).sub(feeParams.positionFeeGrowthInside1LastX128).toString(), feeParams.liquidity, FixedPoint128.Q128)).add(feeParams.tokensOwed1);
return [amount0.toString(), amount1.toString()];
}
async _getFeeGrowthInside(pool, tickLower, tickUpper) {
let feeGrowthInside0X128 = int_1.Uint256.from(0);
let feeGrowthInside1X128 = int_1.Uint256.from(0);
const { tick: tickCurrent } = pool.slot0;
const { feeGrowthOutside0X128: lowerFeeGrowthOutside0X128, feeGrowthOutside1X128: lowerFeeGrowthOutside1X128 } = await pool.getTick(tickLower);
const { feeGrowthOutside0X128: upperFeeGrowthOutside0X128, feeGrowthOutside1X128: upperFeeGrowthOutside1X128 } = await pool.getTick(tickUpper);
if (int_1.Int24.from(tickCurrent).lt(tickLower)) {
feeGrowthInside0X128 = int_1.Uint256.from(lowerFeeGrowthOutside0X128).sub(upperFeeGrowthOutside0X128);
feeGrowthInside1X128 = int_1.Uint256.from(lowerFeeGrowthOutside1X128).sub(upperFeeGrowthOutside1X128);
}
else if (int_1.Int24.from(tickCurrent).lt(tickUpper)) {
const { feeGrowthGlobal0X128 } = pool;
const { feeGrowthGlobal1X128 } = pool;
feeGrowthInside0X128 = int_1.Uint256.from(feeGrowthGlobal0X128).sub(lowerFeeGrowthOutside0X128).sub(upperFeeGrowthOutside0X128);
feeGrowthInside1X128 = int_1.Uint256.from(feeGrowthGlobal1X128).sub(lowerFeeGrowthOutside1X128).sub(upperFeeGrowthOutside1X128);
}
else {
feeGrowthInside0X128 = int_1.Uint256.from(upperFeeGrowthOutside0X128).sub(lowerFeeGrowthOutside0X128);
feeGrowthInside1X128 = int_1.Uint256.from(upperFeeGrowthOutside1X128).sub(lowerFeeGrowthOutside1X128);
}
return [feeGrowthInside0X128.toString(), feeGrowthInside1X128.toString()];
}
async _metadataToIPFS(metadata) {
const cid = await IPFSHash.of(Buffer.from(JSON.stringify(metadata, null, 0), 'utf8'), {
cidVersion: 1,
rawLeaves: true,
});
return `ipfs://${cid}`;
}
async _saveTokenURI(tokenId) {
const metadata = await this.getMetadata(tokenId);
const tokenURI = await this._metadataToIPFS(metadata);
const encodedTokenURI = codec_1.codec.encode(schema_1.tokenUriNFTAttributeSchema, { tokenURI });
await this.nftMethod.setAttributes(this.mutableContext.context, constants_1.TOKENURI_ATTTRIBUTE, PositionKey.getNFTId(this.chainId, this.collectionId, tokenId), encodedTokenURI);
return { tokenURI, metadata };
}
async _savePosition(tokenId, position) {
const encodedPosition = codec_1.codec.encode(schema_1.dexNFTAttributeSchema, position);
await this.nftMethod.setAttributes(this.mutableContext.context, this.moduleName, PositionKey.getNFTId(this.chainId, this.collectionId, tokenId), encodedPosition);
}
_checkImmutableDependency() {
if (!this.immutableDependencyReady) {
throw new Error('dependencies not configured');
}
}
_checkMutableDependency() {
if (!this.mutableDependencyReady) {
throw new Error('dependencies not configured');
}
}
async _pay(token, payer, recipient, value) {
await this.tokenMethod.transfer(this.mutableContext.context, payer, recipient, token, BigInt(value));
}
async _mintCallback(amount0Owed, amount1Owed, data) {
const decoded = JSON.parse(data);
const pool = await this.poolStore.getMutablePool(this.mutableContext, Buffer.from(decoded.poolKey.token0, 'hex'), Buffer.from(decoded.poolKey.token1, 'hex'), decoded.poolKey.fee);
if (int_1.Uint256.from(amount0Owed).gt(0)) {
await this._pay(Buffer.from(decoded.poolKey.token0, 'hex'), Buffer.from(decoded.payer, 'hex'), pool.address, amount0Owed);
}
if (int_1.Uint256.from(amount1Owed).gt(0)) {
await this._pay(Buffer.from(decoded.poolKey.token1, 'hex'), Buffer.from(decoded.payer, 'hex'), pool.address, amount1Owed);
}
}
_checkDeadline(deadline) {
if (int_1.Uint256.from(this.mutableContext.timestamp).gt(deadline))
throw new Error('Transaction too old');
}
async _addLiquidity(params) {
const poolKey = {
token0: params.token0,
token1: params.token1,
fee: params.fee,
};
const pool = await this.poolStore.getMutablePool(this.mutableContext, params.token0, params.token1, params.fee);
const { sqrtPriceX96 } = pool.slot0;
const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
const liquidity = LiquidityAmounts.getLiquidityForAmounts(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, params.amount0Desired, params.amount1Desired);
const data = JSON.stringify({
poolKey: {
token0: poolKey.token0.toString('hex'),
token1: poolKey.token1.toString('hex'),
fee: poolKey.fee,
},
payer: this.mutableContext.senderAddress.toString('hex'),
});
const [amount0, amount1] = await pool.mint(params.recipient, params.tickLower, params.tickUpper, liquidity, data, this._mintCallback.bind(this));
if (int_1.Uint256.from(amount0).lt(params.amount0Min) || int_1.Uint256.from(amount1).lt(params.amount1Min)) {
throw new Error('Price slippage check');
}
return [liquidity, amount0, amount1, pool];
}
async _isAuthorizedForToken(sender, tokenId) {
const nft = await this.nftMethod.getNFT(this.mutableContext.context, PositionKey.getNFTId(this.chainId, this.collectionId, tokenId));
if (nft.owner.compare(sender) !== 0) {
throw new Error('Not approved');
}
}
}
exports.NonfungiblePositionManager = NonfungiblePositionManager;
//# sourceMappingURL=position_manager.js.map