UNPKG

testsetset

Version:

A Typescript SDK for interacting with the Dynamic Bonding Curve on Meteora.

1,361 lines (1,315 loc) 617 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/services/migration.ts var _web3js = require('@solana/web3.js'); // src/types.ts var ActivationType = /* @__PURE__ */ ((ActivationType3) => { ActivationType3[ActivationType3["Slot"] = 0] = "Slot"; ActivationType3[ActivationType3["Timestamp"] = 1] = "Timestamp"; return ActivationType3; })(ActivationType || {}); var TokenType = /* @__PURE__ */ ((TokenType2) => { TokenType2[TokenType2["SPL"] = 0] = "SPL"; TokenType2[TokenType2["Token2022"] = 1] = "Token2022"; return TokenType2; })(TokenType || {}); var CollectFeeMode = /* @__PURE__ */ ((CollectFeeMode4) => { CollectFeeMode4[CollectFeeMode4["QuoteToken"] = 0] = "QuoteToken"; CollectFeeMode4[CollectFeeMode4["OutputToken"] = 1] = "OutputToken"; return CollectFeeMode4; })(CollectFeeMode || {}); var DammV2DynamicFeeMode = /* @__PURE__ */ ((DammV2DynamicFeeMode3) => { DammV2DynamicFeeMode3[DammV2DynamicFeeMode3["Disabled"] = 0] = "Disabled"; DammV2DynamicFeeMode3[DammV2DynamicFeeMode3["Enabled"] = 1] = "Enabled"; return DammV2DynamicFeeMode3; })(DammV2DynamicFeeMode || {}); var MigrationOption = /* @__PURE__ */ ((MigrationOption2) => { MigrationOption2[MigrationOption2["MET_DAMM"] = 0] = "MET_DAMM"; MigrationOption2[MigrationOption2["MET_DAMM_V2"] = 1] = "MET_DAMM_V2"; return MigrationOption2; })(MigrationOption || {}); var BaseFeeMode = /* @__PURE__ */ ((BaseFeeMode2) => { BaseFeeMode2[BaseFeeMode2["FeeSchedulerLinear"] = 0] = "FeeSchedulerLinear"; BaseFeeMode2[BaseFeeMode2["FeeSchedulerExponential"] = 1] = "FeeSchedulerExponential"; BaseFeeMode2[BaseFeeMode2["RateLimiter"] = 2] = "RateLimiter"; return BaseFeeMode2; })(BaseFeeMode || {}); var MigrationFeeOption = /* @__PURE__ */ ((MigrationFeeOption2) => { MigrationFeeOption2[MigrationFeeOption2["FixedBps25"] = 0] = "FixedBps25"; MigrationFeeOption2[MigrationFeeOption2["FixedBps30"] = 1] = "FixedBps30"; MigrationFeeOption2[MigrationFeeOption2["FixedBps100"] = 2] = "FixedBps100"; MigrationFeeOption2[MigrationFeeOption2["FixedBps200"] = 3] = "FixedBps200"; MigrationFeeOption2[MigrationFeeOption2["FixedBps400"] = 4] = "FixedBps400"; MigrationFeeOption2[MigrationFeeOption2["FixedBps600"] = 5] = "FixedBps600"; MigrationFeeOption2[MigrationFeeOption2["Customizable"] = 6] = "Customizable"; return MigrationFeeOption2; })(MigrationFeeOption || {}); var TokenDecimal = /* @__PURE__ */ ((TokenDecimal3) => { TokenDecimal3[TokenDecimal3["SIX"] = 6] = "SIX"; TokenDecimal3[TokenDecimal3["SEVEN"] = 7] = "SEVEN"; TokenDecimal3[TokenDecimal3["EIGHT"] = 8] = "EIGHT"; TokenDecimal3[TokenDecimal3["NINE"] = 9] = "NINE"; return TokenDecimal3; })(TokenDecimal || {}); var TradeDirection = /* @__PURE__ */ ((TradeDirection3) => { TradeDirection3[TradeDirection3["BaseToQuote"] = 0] = "BaseToQuote"; TradeDirection3[TradeDirection3["QuoteToBase"] = 1] = "QuoteToBase"; return TradeDirection3; })(TradeDirection || {}); var Rounding = /* @__PURE__ */ ((Rounding2) => { Rounding2[Rounding2["Up"] = 0] = "Up"; Rounding2[Rounding2["Down"] = 1] = "Down"; return Rounding2; })(Rounding || {}); var TokenUpdateAuthorityOption = /* @__PURE__ */ ((TokenUpdateAuthorityOption2) => { TokenUpdateAuthorityOption2[TokenUpdateAuthorityOption2["CreatorUpdateAuthority"] = 0] = "CreatorUpdateAuthority"; TokenUpdateAuthorityOption2[TokenUpdateAuthorityOption2["Immutable"] = 1] = "Immutable"; TokenUpdateAuthorityOption2[TokenUpdateAuthorityOption2["PartnerUpdateAuthority"] = 2] = "PartnerUpdateAuthority"; TokenUpdateAuthorityOption2[TokenUpdateAuthorityOption2["CreatorUpdateAndMintAuthority"] = 3] = "CreatorUpdateAndMintAuthority"; TokenUpdateAuthorityOption2[TokenUpdateAuthorityOption2["PartnerUpdateAndMintAuthority"] = 4] = "PartnerUpdateAndMintAuthority"; return TokenUpdateAuthorityOption2; })(TokenUpdateAuthorityOption || {}); var SwapMode = /* @__PURE__ */ ((SwapMode2) => { SwapMode2[SwapMode2["ExactIn"] = 0] = "ExactIn"; SwapMode2[SwapMode2["PartialFill"] = 1] = "PartialFill"; SwapMode2[SwapMode2["ExactOut"] = 2] = "ExactOut"; return SwapMode2; })(SwapMode || {}); // src/constants.ts var _bnjs = require('bn.js'); var _bnjs2 = _interopRequireDefault(_bnjs); var OFFSET = 64; var U128_MAX = new (0, _bnjs2.default)("340282366920938463463374607431768211455"); var U64_MAX = new (0, _bnjs2.default)("18446744073709551615"); var U16_MAX = 65535; var MIN_SQRT_PRICE = new (0, _bnjs2.default)("4295048016"); var MAX_SQRT_PRICE = new (0, _bnjs2.default)("79226673521066979257578248091"); var RESOLUTION = 64; var ONE_Q64 = new (0, _bnjs2.default)(1).shln(RESOLUTION); var FEE_DENOMINATOR = 1e9; var MAX_FEE_BPS = 9900; var MIN_FEE_BPS = 1; var MIN_FEE_NUMERATOR = 1e5; var MAX_FEE_NUMERATOR = 99e7; var BASIS_POINT_MAX = 1e4; var MAX_CURVE_POINT = 16; var PARTNER_SURPLUS_SHARE = 80; var SWAP_BUFFER_PERCENTAGE = 25; var MAX_MIGRATION_FEE_PERCENTAGE = 50; var MAX_CREATOR_MIGRATION_FEE_PERCENTAGE = 100; var MAX_SWALLOW_PERCENTAGE = 20; var MAX_RATE_LIMITER_DURATION_IN_SECONDS = 43200; var MAX_RATE_LIMITER_DURATION_IN_SLOTS = 108e3; var SLOT_DURATION = 400; var TIMESTAMP_DURATION = 1e3; var DYNAMIC_BONDING_CURVE_PROGRAM_ID = new (0, _web3js.PublicKey)( "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN" ); var METAPLEX_PROGRAM_ID = new (0, _web3js.PublicKey)( "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" ); var DAMM_V1_PROGRAM_ID = new (0, _web3js.PublicKey)( "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB" ); var DAMM_V2_PROGRAM_ID = new (0, _web3js.PublicKey)( "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG" ); var VAULT_PROGRAM_ID = new (0, _web3js.PublicKey)( "24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi" ); var LOCKER_PROGRAM_ID = new (0, _web3js.PublicKey)( "LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn" ); var BASE_ADDRESS = new (0, _web3js.PublicKey)( "HWzXGcGHy4tcpYfaRDCyLNzXqBTv3E6BttpCH2vJxArv" ); var DYNAMIC_FEE_FILTER_PERIOD_DEFAULT = 10; var DYNAMIC_FEE_DECAY_PERIOD_DEFAULT = 120; var DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT = 5e3; var MAX_DYNAMIC_FEE_PERCENTAGE = 20; var DYNAMIC_FEE_SCALING_FACTOR = new (0, _bnjs2.default)(1e11); var DYNAMIC_FEE_ROUNDING_OFFSET = new (0, _bnjs2.default)(99999999999); var BIN_STEP_BPS_DEFAULT = 1; var BIN_STEP_BPS_U128_DEFAULT = new (0, _bnjs2.default)("1844674407370955"); var MAX_PRICE_CHANGE_BPS_DEFAULT = 1500; var MIN_MIGRATED_POOL_FEE_BPS = 10; var MAX_MIGRATED_POOL_FEE_BPS = 1e3; var DAMM_V1_MIGRATION_FEE_ADDRESS = [ new (0, _web3js.PublicKey)("8f848CEy8eY6PhJ3VcemtBDzPPSD4Vq7aJczLZ3o8MmX"), // FixedBps25 new (0, _web3js.PublicKey)("HBxB8Lf14Yj8pqeJ8C4qDb5ryHL7xwpuykz31BLNYr7S"), // FixedBps30 new (0, _web3js.PublicKey)("7v5vBdUQHTNeqk1HnduiXcgbvCyVEZ612HLmYkQoAkik"), // FixedBps100 new (0, _web3js.PublicKey)("EkvP7d5yKxovj884d2DwmBQbrHUWRLGK6bympzrkXGja"), // FixedBps200 new (0, _web3js.PublicKey)("9EZYAJrcqNWNQzP2trzZesP7XKMHA1jEomHzbRsdX8R2"), // FixedBps400 new (0, _web3js.PublicKey)("8cdKo87jZU2R12KY1BUjjRPwyjgdNjLGqSGQyrDshhud") // FixedBps600 ]; var DAMM_V2_MIGRATION_FEE_ADDRESS = [ new (0, _web3js.PublicKey)("7F6dnUcRuyM2TwR8myT1dYypFXpPSxqwKNSFNkxyNESd"), // FixedBps25 new (0, _web3js.PublicKey)("2nHK1kju6XjphBLbNxpM5XRGFj7p9U8vvNzyZiha1z6k"), // FixedBps30 new (0, _web3js.PublicKey)("Hv8Lmzmnju6m7kcokVKvwqz7QPmdX9XfKjJsXz8RXcjp"), // FixedBps100 new (0, _web3js.PublicKey)("2c4cYd4reUYVRAB9kUUkrq55VPyy2FNQ3FDL4o12JXmq"), // FixedBps200 new (0, _web3js.PublicKey)("AkmQWebAwFvWk55wBoCr5D62C6VVDTzi84NJuD9H7cFD"), // FixedBps400 new (0, _web3js.PublicKey)("DbCRBj8McvPYHJG1ukj8RE15h2dCNUdTAESG49XpQ44u"), // FixedBps600 new (0, _web3js.PublicKey)("A8gMrEPJkacWkcb3DGwtJwTe16HktSEfvwtuDh2MCtck") // Customizable ]; // src/helpers/common.ts var _decimaljs = require('decimal.js'); var _decimaljs2 = _interopRequireDefault(_decimaljs); // src/math/curve.ts // src/math/safeMath.ts var SafeMath = class { /** * Safe addition * @param a First number * @param b Second number * @returns Sum of a and b */ static add(a, b) { return a.add(b); } /** * Safe subtraction * @param a First number * @param b Second number * @returns Difference of a and b * @throws Error if b > a */ static sub(a, b) { if (b.gt(a)) { throw new Error("SafeMath: subtraction overflow"); } return a.sub(b); } /** * Safe multiplication * @param a First number * @param b Second number * @returns Product of a and b */ static mul(a, b) { return a.mul(b); } /** * Safe division * @param a First number * @param b Second number * @returns Quotient of a and b * @throws Error if b is zero */ static div(a, b) { if (b.isZero()) { throw new Error("SafeMath: division by zero"); } return a.div(b); } /** * Safe modulo * @param a First number * @param b Second number * @returns Remainder of a divided by b * @throws Error if b is zero */ static mod(a, b) { if (b.isZero()) { throw new Error("SafeMath: modulo by zero"); } return a.mod(b); } /** * Safe left shift * @param a Number to shift * @param b Number of bits to shift * @returns a << b */ static shl(a, b) { return a.shln(b); } /** * Safe right shift * @param a Number to shift * @param b Number of bits to shift * @returns a >> b */ static shr(a, b) { return a.shrn(b); } }; function pow(base, exponent, scaling = true) { const ONE = new (0, _bnjs2.default)(1).shln(RESOLUTION); if (exponent.isZero()) return ONE; if (base.isZero()) return new (0, _bnjs2.default)(0); if (base.eq(ONE)) return ONE; const isNegative = exponent.isNeg(); const absExponent = isNegative ? exponent.neg() : exponent; let result = ONE; let currentBase = base; let exp = absExponent; while (!exp.isZero()) { if (exp.and(new (0, _bnjs2.default)(1)).eq(new (0, _bnjs2.default)(1))) { result = SafeMath.div(SafeMath.mul(result, currentBase), ONE); } currentBase = SafeMath.div(SafeMath.mul(currentBase, currentBase), ONE); exp = exp.shrn(1); } if (isNegative) { result = SafeMath.div(ONE.mul(ONE), result); } return scaling ? result : SafeMath.div(result, ONE); } // src/math/utilsMath.ts function mulDiv(x, y, denominator, rounding) { if (denominator.isZero()) { throw new Error("MulDiv: division by zero"); } if (denominator.eq(new (0, _bnjs2.default)(1)) || x.isZero() || y.isZero()) { return x.mul(y); } const prod = x.mul(y); if (rounding === 0 /* Up */) { const numerator = prod.add(denominator.sub(new (0, _bnjs2.default)(1))); return numerator.div(denominator); } else { return prod.div(denominator); } } function mulShr(x, y, offset) { if (offset === 0 || x.isZero() || y.isZero()) { return x.mul(y); } const prod = SafeMath.mul(x, y); return SafeMath.shr(prod, offset); } function sqrt(value) { if (value.isZero()) { return new (0, _bnjs2.default)(0); } if (value.eq(new (0, _bnjs2.default)(1))) { return new (0, _bnjs2.default)(1); } let x = value; let y = value.add(new (0, _bnjs2.default)(1)).div(new (0, _bnjs2.default)(2)); while (y.lt(x)) { x = y; y = x.add(value.div(x)).div(new (0, _bnjs2.default)(2)); } return x; } // src/math/curve.ts function getInitialLiquidityFromDeltaQuote(quoteAmount, sqrtMinPrice, sqrtPrice) { const priceDelta = SafeMath.sub(sqrtPrice, sqrtMinPrice); const quoteAmountShifted = SafeMath.shl(quoteAmount, 128); return SafeMath.div(quoteAmountShifted, priceDelta); } function getInitialLiquidityFromDeltaBase(baseAmount, sqrtMaxPrice, sqrtPrice) { const priceDelta = SafeMath.sub(sqrtMaxPrice, sqrtPrice); const prod = SafeMath.mul(SafeMath.mul(baseAmount, sqrtPrice), sqrtMaxPrice); const liquidity = SafeMath.div(prod, priceDelta); return liquidity; } function getDeltaAmountBaseUnsigned(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const result = getDeltaAmountBaseUnsigned256( lowerSqrtPrice, upperSqrtPrice, liquidity, round ); return result; } function getDeltaAmountBaseUnsigned256(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const result = getDeltaAmountBaseUnsignedUnchecked( lowerSqrtPrice, upperSqrtPrice, liquidity, round ); return result; } function getDeltaAmountBaseUnsignedUnchecked(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const numerator1 = liquidity; const numerator2 = SafeMath.sub(upperSqrtPrice, lowerSqrtPrice); const denominator = SafeMath.mul(lowerSqrtPrice, upperSqrtPrice); if (denominator.isZero()) { throw new Error("Denominator cannot be zero"); } const result = mulDiv(numerator1, numerator2, denominator, round); return result; } function getDeltaAmountQuoteUnsigned(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const result = getDeltaAmountQuoteUnsigned256( lowerSqrtPrice, upperSqrtPrice, liquidity, round ); return result; } function getDeltaAmountQuoteUnsigned256(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const result = getDeltaAmountQuoteUnsignedUnchecked( lowerSqrtPrice, upperSqrtPrice, liquidity, round ); return result; } function getDeltaAmountQuoteUnsignedUnchecked(lowerSqrtPrice, upperSqrtPrice, liquidity, round) { const deltaSqrtPrice = SafeMath.sub(upperSqrtPrice, lowerSqrtPrice); const prod = SafeMath.mul(liquidity, deltaSqrtPrice); if (round === 0 /* Up */) { const denominator = new (0, _bnjs2.default)(1).shln(RESOLUTION * 2); const numerator = SafeMath.add( prod, SafeMath.sub(denominator, new (0, _bnjs2.default)(1)) ); return SafeMath.div(numerator, denominator); } else { return SafeMath.shr(prod, RESOLUTION * 2); } } function getNextSqrtPriceFromInput(sqrtPrice, liquidity, amountIn, baseForQuote) { if (sqrtPrice.isZero()) { throw new Error("sqrt_price must be greater than 0"); } if (liquidity.isZero()) { throw new Error("liquidity must be greater than 0"); } if (baseForQuote) { return getNextSqrtPriceFromBaseAmountInRoundingUp( sqrtPrice, liquidity, amountIn ); } else { return getNextSqrtPriceFromQuoteAmountInRoundingDown( sqrtPrice, liquidity, amountIn ); } } function getNextSqrtPriceFromOutput(sqrtPrice, liquidity, amountOut, baseForQuote) { if (sqrtPrice.isZero()) { throw new Error("sqrt_price must be greater than 0"); } if (liquidity.isZero()) { throw new Error("liquidity must be greater than 0"); } if (baseForQuote) { return getNextSqrtPriceFromQuoteAmountOutRoundingDown( sqrtPrice, liquidity, amountOut ); } else { return getNextSqrtPriceFromBaseAmountOutRoundingUp( sqrtPrice, liquidity, amountOut ); } } function getNextSqrtPriceFromQuoteAmountOutRoundingDown(sqrtPrice, liquidity, amount) { const qAmount = SafeMath.shl(amount, 128); const numerator = SafeMath.add(qAmount, SafeMath.sub(liquidity, new (0, _bnjs2.default)(1))); const quotient = SafeMath.div(numerator, liquidity); const result = SafeMath.sub(sqrtPrice, quotient); return result; } function getNextSqrtPriceFromBaseAmountOutRoundingUp(sqrtPrice, liquidity, amount) { if (amount.isZero()) { return sqrtPrice; } const product = SafeMath.mul(amount, sqrtPrice); const denominator = SafeMath.sub(liquidity, product); if (denominator.isZero() || denominator.isNeg()) { throw new Error( "Invalid denominator: liquidity must be greater than amount * sqrt_price" ); } return mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */); } function getNextSqrtPriceFromBaseAmountInRoundingUp(sqrtPrice, liquidity, amount) { if (amount.isZero()) { return sqrtPrice; } const product = SafeMath.mul(amount, sqrtPrice); if (product.gt(U128_MAX)) { const quotient = SafeMath.div(liquidity, sqrtPrice); const denominator2 = SafeMath.add(quotient, amount); return SafeMath.div(liquidity, denominator2); } const denominator = SafeMath.add(liquidity, product); return mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */); } function getNextSqrtPriceFromQuoteAmountInRoundingDown(sqrtPrice, liquidity, amount) { const quotient = SafeMath.div( SafeMath.shl(amount, RESOLUTION * 2), liquidity ); return SafeMath.add(sqrtPrice, quotient); } // src/helpers/common.ts // src/helpers/utils.ts var _spltoken = require('@solana/spl-token'); function convertToLamports(amount, tokenDecimal) { const valueInLamports = new (0, _decimaljs2.default)(amount).mul( _decimaljs2.default.pow(10, tokenDecimal) ); return fromDecimalToBN(valueInLamports); } function fromDecimalToBN(value) { return new (0, _bnjs2.default)(value.floor().toFixed()); } function createProgramAccountFilter(owner, offset) { const ownerKey = typeof owner === "string" ? new (0, _web3js.PublicKey)(owner) : owner; return [ { memcmp: { offset, bytes: ownerKey.toBase58(), encoding: "base58" } } ]; } function isNativeSol(mint) { return mint.toString() === _spltoken.NATIVE_MINT.toString(); } function isDefaultLockedVesting(lockedVesting) { return lockedVesting.amountPerPeriod.eqn(0) && lockedVesting.cliffDurationFromMigrationTime.eqn(0) && lockedVesting.frequency.eqn(0) && lockedVesting.numberOfPeriod.eqn(0) && lockedVesting.cliffUnlockAmount.eqn(0); } function convertDecimalToBN(value) { return new (0, _bnjs2.default)(value.floor().toFixed()); } function bpsToFeeNumerator(bps) { return new (0, _bnjs2.default)(bps * FEE_DENOMINATOR).divn(BASIS_POINT_MAX); } function feeNumeratorToBps(feeNumerator) { return feeNumerator.muln(BASIS_POINT_MAX).div(new (0, _bnjs2.default)(FEE_DENOMINATOR)).toNumber(); } // src/helpers/token.ts var getOrCreateATAInstruction = async (connection, tokenMint, owner, payer, allowOwnerOffCurve = true, tokenProgram) => { const toAccount = _spltoken.getAssociatedTokenAddressSync.call(void 0, tokenMint, owner, allowOwnerOffCurve, tokenProgram ); try { await _spltoken.getAccount.call(void 0, connection, toAccount); return { ataPubkey: toAccount, ix: void 0 }; } catch (e) { if (e instanceof _spltoken.TokenAccountNotFoundError || e instanceof _spltoken.TokenInvalidAccountOwnerError) { const ix = _spltoken.createAssociatedTokenAccountIdempotentInstruction.call(void 0, payer, toAccount, owner, tokenMint, tokenProgram ); return { ataPubkey: toAccount, ix }; } else { console.error("Error::getOrCreateATAInstruction", e); throw e; } } }; function unwrapSOLInstruction(owner, receiver, allowOwnerOffCurve = true) { const wSolATAAccount = _spltoken.getAssociatedTokenAddressSync.call(void 0, _spltoken.NATIVE_MINT, owner, allowOwnerOffCurve ); if (wSolATAAccount) { const closedWrappedSolInstruction = _spltoken.createCloseAccountInstruction.call(void 0, wSolATAAccount, receiver, owner, [], _spltoken.TOKEN_PROGRAM_ID ); return closedWrappedSolInstruction; } return null; } function wrapSOLInstruction(from, to, amount) { return [ _web3js.SystemProgram.transfer({ fromPubkey: from, toPubkey: to, lamports: amount }), new (0, _web3js.TransactionInstruction)({ keys: [ { pubkey: to, isSigner: false, isWritable: true } ], data: Buffer.from(new Uint8Array([17])), programId: _spltoken.TOKEN_PROGRAM_ID }) ]; } function findAssociatedTokenAddress(walletAddress, tokenMintAddress, tokenProgramId) { return _web3js.PublicKey.findProgramAddressSync( [ walletAddress.toBuffer(), tokenProgramId.toBuffer(), tokenMintAddress.toBuffer() ], _spltoken.ASSOCIATED_TOKEN_PROGRAM_ID )[0]; } async function getTokenDecimals(connection, mintAddress) { const mintPubkey = mintAddress instanceof _web3js.PublicKey ? mintAddress : new (0, _web3js.PublicKey)(mintAddress); const tokenProgram = (await connection.getAccountInfo(mintPubkey)).owner; const mintInfo = await _spltoken.getMint.call(void 0, connection, mintPubkey, "confirmed", tokenProgram ); return mintInfo.decimals; } function getTokenProgram(tokenType) { return tokenType === 0 /* SPL */ ? _spltoken.TOKEN_PROGRAM_ID : _spltoken.TOKEN_2022_PROGRAM_ID; } async function getTokenType(connection, tokenMint) { const accountInfo = await connection.getAccountInfo(tokenMint); if (!accountInfo) { return null; } return accountInfo.owner.equals(_spltoken.TOKEN_PROGRAM_ID) ? 0 /* SPL */ : 1 /* Token2022 */; } async function prepareTokenAccountTx(connection, owner, payer, tokenMint, amount, tokenProgram) { const instructions = []; const { ataPubkey: tokenAccount, ix: createAtaIx } = await getOrCreateATAInstruction( connection, tokenMint, owner, payer, true, tokenProgram ); createAtaIx && instructions.push(createAtaIx); if (tokenMint.equals(_spltoken.NATIVE_MINT)) { const wrapIx = wrapSOLInstruction(owner, tokenAccount, amount); instructions.push(...wrapIx); } const transaction = new (0, _web3js.Transaction)(); if (instructions.length > 0) { transaction.add(...instructions); } return { tokenAccount, transaction }; } async function cleanUpTokenAccountTx(owner, receiver, tokenMint) { if (tokenMint.equals(_spltoken.NATIVE_MINT)) { const unwrapIx = unwrapSOLInstruction(owner, receiver); if (unwrapIx) { return { transaction: new (0, _web3js.Transaction)().add(unwrapIx) }; } } return null; } // src/helpers/common.ts function getFirstKey(key1, key2) { const buf1 = key1.toBuffer(); const buf2 = key2.toBuffer(); if (Buffer.compare(buf1, buf2) === 1) { return buf1; } return buf2; } function getSecondKey(key1, key2) { const buf1 = key1.toBuffer(); const buf2 = key2.toBuffer(); if (Buffer.compare(buf1, buf2) === 1) { return buf2; } return buf1; } async function getAccountData(accountAddress, accountType, program, commitment) { const address = accountAddress instanceof _web3js.PublicKey ? accountAddress : new (0, _web3js.PublicKey)(accountAddress); return await program.account[accountType].fetchNullable( address, commitment ); } async function getAccountCreationTimestamp(accountAddress, connection) { const address = accountAddress instanceof _web3js.PublicKey ? accountAddress : new (0, _web3js.PublicKey)(accountAddress); const signatures = await connection.getSignaturesForAddress(address, { limit: 1 }); return _optionalChain([signatures, 'access', _ => _[0], 'optionalAccess', _2 => _2.blockTime]) ? new Date(signatures[0].blockTime * 1e3) : void 0; } async function getAccountCreationTimestamps(accountAddresses, connection) { const timestampPromises = accountAddresses.map( (address) => getAccountCreationTimestamp(address, connection) ); return Promise.all(timestampPromises); } function getTotalTokenSupply(swapBaseAmount, migrationBaseThreshold, lockedVestingParams) { try { const totalCirculatingAmount = swapBaseAmount.add( migrationBaseThreshold ); const totalLockedVestingAmount = lockedVestingParams.cliffUnlockAmount.add( lockedVestingParams.amountPerPeriod.mul( lockedVestingParams.numberOfPeriod ) ); const totalAmount = totalCirculatingAmount.add(totalLockedVestingAmount); if (totalAmount.isNeg() || totalAmount.bitLength() > 64) { throw new Error("Math overflow"); } return totalAmount; } catch (error) { throw new Error("Math overflow"); } } function getPriceFromSqrtPrice(sqrtPrice, tokenBaseDecimal, tokenQuoteDecimal) { const sqrtPriceDecimal = new (0, _decimaljs2.default)(sqrtPrice.toString()); const lamportPrice = sqrtPriceDecimal.mul(sqrtPriceDecimal).div(new (0, _decimaljs2.default)(2).pow(128)); const tokenPrice = lamportPrice.mul( new (0, _decimaljs2.default)(10).pow(tokenBaseDecimal - tokenQuoteDecimal) ); return tokenPrice; } var getSqrtPriceFromPrice = (price, tokenADecimal, tokenBDecimal) => { const decimalPrice = new (0, _decimaljs2.default)(price); const adjustedByDecimals = decimalPrice.div( new (0, _decimaljs2.default)(10 ** (tokenADecimal - tokenBDecimal)) ); const sqrtValue = _decimaljs2.default.sqrt(adjustedByDecimals); const sqrtValueQ64 = sqrtValue.mul(_decimaljs2.default.pow(2, 64)); return new (0, _bnjs2.default)(sqrtValueQ64.floor().toFixed()); }; var getSqrtPriceFromMarketCap = (marketCap, totalSupply, tokenBaseDecimal, tokenQuoteDecimal) => { let price = new (0, _decimaljs2.default)(marketCap).div(new (0, _decimaljs2.default)(totalSupply)); return getSqrtPriceFromPrice( price.toString(), tokenBaseDecimal, tokenQuoteDecimal ); }; function getBaseTokenForSwap(sqrtStartPrice, sqrtMigrationPrice, curve) { let totalAmount = new (0, _bnjs2.default)(0); for (let i = 0; i < curve.length; i++) { const lowerSqrtPrice = i == 0 ? sqrtStartPrice : curve[i - 1].sqrtPrice; if (curve[i].sqrtPrice && curve[i].sqrtPrice.gt(sqrtMigrationPrice)) { const deltaAmount = getDeltaAmountBaseUnsigned( lowerSqrtPrice, sqrtMigrationPrice, curve[i].liquidity, 0 /* Up */ ); totalAmount = totalAmount.add(deltaAmount); break; } else { const deltaAmount = getDeltaAmountBaseUnsigned( lowerSqrtPrice, curve[i].sqrtPrice, curve[i].liquidity, 0 /* Up */ ); totalAmount = totalAmount.add(deltaAmount); } } return totalAmount; } var getMigrationQuoteAmountFromMigrationQuoteThreshold = (migrationQuoteThreshold, migrationFeePercent) => { const migrationQuoteAmount = migrationQuoteThreshold.mul(new (0, _decimaljs2.default)(100).sub(new (0, _decimaljs2.default)(migrationFeePercent))).div(new (0, _decimaljs2.default)(100)); return migrationQuoteAmount; }; var getMigrationQuoteThresholdFromMigrationQuoteAmount = (migrationQuoteAmount, migrationFeePercent) => { const migrationQuoteThreshold = migrationQuoteAmount.mul(new (0, _decimaljs2.default)(100)).div(new (0, _decimaljs2.default)(100).sub(new (0, _decimaljs2.default)(migrationFeePercent))); return migrationQuoteThreshold; }; var getMigrationBaseToken = (migrationQuoteAmount, sqrtMigrationPrice, migrationOption) => { if (migrationOption == 0 /* MET_DAMM */) { const price = sqrtMigrationPrice.mul(sqrtMigrationPrice); const quote = migrationQuoteAmount.shln(128); const { div: baseDiv, mod } = quote.divmod(price); let div = baseDiv; if (!mod.isZero()) { div = div.add(new (0, _bnjs2.default)(1)); } return div; } else if (migrationOption == 1 /* MET_DAMM_V2 */) { const liquidity = getInitialLiquidityFromDeltaQuote( migrationQuoteAmount, MIN_SQRT_PRICE, sqrtMigrationPrice ); const baseAmount = getDeltaAmountBaseUnsigned( sqrtMigrationPrice, MAX_SQRT_PRICE, liquidity, 0 /* Up */ ); return baseAmount; } else { throw Error("Invalid migration option"); } }; var getTotalVestingAmount = (lockedVesting) => { const totalVestingAmount = lockedVesting.cliffUnlockAmount.add( lockedVesting.amountPerPeriod.mul(lockedVesting.numberOfPeriod) ); return totalVestingAmount; }; var getLiquidity = (baseAmount, quoteAmount, minSqrtPrice, maxSqrtPrice) => { const liquidityFromBase = getInitialLiquidityFromDeltaBase( baseAmount, maxSqrtPrice, minSqrtPrice ); const liquidityFromQuote = getInitialLiquidityFromDeltaQuote( quoteAmount, minSqrtPrice, maxSqrtPrice ); return _bnjs2.default.min(liquidityFromBase, liquidityFromQuote); }; var getFirstCurve = (migrationSqrtPrice, migrationBaseAmount, swapAmount, migrationQuoteThreshold, migrationFeePercent) => { const migrationSqrPriceDecimal = new (0, _decimaljs2.default)(migrationSqrtPrice.toString()); const migrationBaseAmountDecimal = new (0, _decimaljs2.default)( migrationBaseAmount.toString() ); const swapAmountDecimal = new (0, _decimaljs2.default)(swapAmount.toString()); const migrationFeePercentDecimal = new (0, _decimaljs2.default)( migrationFeePercent.toString() ); const denominator = swapAmountDecimal.mul(new (0, _decimaljs2.default)(100).sub(migrationFeePercentDecimal)).div(new (0, _decimaljs2.default)(100)); const sqrtStartPriceDecimal = migrationSqrPriceDecimal.mul(migrationBaseAmountDecimal).div(denominator); const sqrtStartPrice = new (0, _bnjs2.default)(sqrtStartPriceDecimal.floor().toFixed()); const liquidity = getLiquidity( swapAmount, migrationQuoteThreshold, sqrtStartPrice, migrationSqrtPrice ); return { sqrtStartPrice, curve: [ { sqrtPrice: migrationSqrtPrice, liquidity } ] }; }; var getTotalSupplyFromCurve = (migrationQuoteThreshold, sqrtStartPrice, curve, lockedVesting, migrationOption, leftover, migrationFeePercent) => { const sqrtMigrationPrice = getMigrationThresholdPrice( migrationQuoteThreshold, sqrtStartPrice, curve ); const swapBaseAmount = getBaseTokenForSwap( sqrtStartPrice, sqrtMigrationPrice, curve ); const swapBaseAmountBuffer = getSwapAmountWithBuffer( swapBaseAmount, sqrtStartPrice, curve ); const migrationQuoteAmount = getMigrationQuoteAmountFromMigrationQuoteThreshold( new (0, _decimaljs2.default)(migrationQuoteThreshold.toString()), migrationFeePercent ); const migrationBaseAmount = getMigrationBaseToken( fromDecimalToBN(migrationQuoteAmount), sqrtMigrationPrice, migrationOption ); const totalVestingAmount = getTotalVestingAmount(lockedVesting); const minimumBaseSupplyWithBuffer = swapBaseAmountBuffer.add(migrationBaseAmount).add(totalVestingAmount).add(leftover); return minimumBaseSupplyWithBuffer; }; var getMigrationThresholdPrice = (migrationThreshold, sqrtStartPrice, curve) => { let nextSqrtPrice = sqrtStartPrice; if (curve.length === 0) { throw Error("Curve is empty"); } const totalAmount = getDeltaAmountQuoteUnsigned( nextSqrtPrice, curve[0].sqrtPrice, curve[0].liquidity, 0 /* Up */ ); if (totalAmount.gt(migrationThreshold)) { nextSqrtPrice = getNextSqrtPriceFromInput( nextSqrtPrice, curve[0].liquidity, migrationThreshold, false ); } else { let amountLeft = migrationThreshold.sub(totalAmount); nextSqrtPrice = curve[0].sqrtPrice; for (let i = 1; i < curve.length; i++) { const maxAmount = getDeltaAmountQuoteUnsigned( nextSqrtPrice, curve[i].sqrtPrice, curve[i].liquidity, 0 /* Up */ ); if (maxAmount.gt(amountLeft)) { nextSqrtPrice = getNextSqrtPriceFromInput( nextSqrtPrice, curve[i].liquidity, amountLeft, false ); amountLeft = new (0, _bnjs2.default)(0); break; } else { amountLeft = amountLeft.sub(maxAmount); nextSqrtPrice = curve[i].sqrtPrice; } } if (!amountLeft.isZero()) { let migrationThresholdStr = migrationThreshold.toString(); let amountLeftStr = amountLeft.toString(); throw Error( `Not enough liquidity, migrationThreshold: ${migrationThresholdStr} amountLeft: ${amountLeftStr}` ); } } return nextSqrtPrice; }; var getSwapAmountWithBuffer = (swapBaseAmount, sqrtStartPrice, curve) => { const swapAmountBuffer = swapBaseAmount.add( swapBaseAmount.mul(new (0, _bnjs2.default)(25)).div(new (0, _bnjs2.default)(100)) ); const maxBaseAmountOnCurve = getBaseTokenForSwap( sqrtStartPrice, MAX_SQRT_PRICE, curve ); return _bnjs2.default.min(swapAmountBuffer, maxBaseAmountOnCurve); }; var getPercentageSupplyOnMigration = (initialMarketCap, migrationMarketCap, lockedVesting, totalLeftover, totalTokenSupply) => { const marketCapRatio = initialMarketCap.div(migrationMarketCap); const sqrtRatio = _decimaljs2.default.sqrt(marketCapRatio); const totalVestingAmount = getTotalVestingAmount(lockedVesting); const vestingPercentage = new (0, _decimaljs2.default)(totalVestingAmount.toString()).mul(new (0, _decimaljs2.default)(100)).div(new (0, _decimaljs2.default)(totalTokenSupply.toString())); const leftoverPercentage = new (0, _decimaljs2.default)(totalLeftover.toString()).mul(new (0, _decimaljs2.default)(100)).div(new (0, _decimaljs2.default)(totalTokenSupply.toString())); const numerator = new (0, _decimaljs2.default)(100).mul(sqrtRatio).sub(vestingPercentage.add(leftoverPercentage).mul(sqrtRatio)); const denominator = new (0, _decimaljs2.default)(1).add(sqrtRatio); return numerator.div(denominator).toNumber(); }; var getMigrationQuoteAmount = (migrationMarketCap, percentageSupplyOnMigration) => { return migrationMarketCap.mul(percentageSupplyOnMigration).div(new (0, _decimaljs2.default)(100)); }; function getFeeSchedulerParams(startingBaseFeeBps, endingBaseFeeBps, baseFeeMode, numberOfPeriod, totalDuration) { if (startingBaseFeeBps == endingBaseFeeBps) { if (numberOfPeriod != 0 || totalDuration != 0) { throw new Error( "numberOfPeriod and totalDuration must both be zero" ); } return { cliffFeeNumerator: bpsToFeeNumerator(startingBaseFeeBps), firstFactor: 0, secondFactor: new (0, _bnjs2.default)(0), thirdFactor: new (0, _bnjs2.default)(0), baseFeeMode: 0 /* FeeSchedulerLinear */ }; } if (numberOfPeriod <= 0) { throw new Error("Total periods must be greater than zero"); } if (startingBaseFeeBps > MAX_FEE_BPS) { throw new Error( `startingBaseFeeBps (${startingBaseFeeBps} bps) exceeds maximum allowed value of ${MAX_FEE_BPS} bps` ); } if (endingBaseFeeBps > startingBaseFeeBps) { throw new Error( "endingBaseFeeBps bps must be less than or equal to startingBaseFeeBps bps" ); } if (numberOfPeriod == 0 || totalDuration == 0) { throw new Error( "numberOfPeriod and totalDuration must both greater than zero" ); } const maxBaseFeeNumerator = bpsToFeeNumerator(startingBaseFeeBps); const minBaseFeeNumerator = bpsToFeeNumerator(endingBaseFeeBps); const periodFrequency = new (0, _bnjs2.default)(totalDuration / numberOfPeriod); let reductionFactor; if (baseFeeMode == 0 /* FeeSchedulerLinear */) { const totalReduction = maxBaseFeeNumerator.sub(minBaseFeeNumerator); reductionFactor = totalReduction.divn(numberOfPeriod); } else { const ratio = minBaseFeeNumerator.toNumber() / maxBaseFeeNumerator.toNumber(); const decayBase = Math.pow(ratio, 1 / numberOfPeriod); reductionFactor = new (0, _bnjs2.default)(BASIS_POINT_MAX * (1 - decayBase)); } return { cliffFeeNumerator: maxBaseFeeNumerator, firstFactor: numberOfPeriod, secondFactor: periodFrequency, thirdFactor: reductionFactor, baseFeeMode }; } function calculateFeeSchedulerEndingBaseFeeBps(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, baseFeeMode) { if (numberOfPeriod === 0 || periodFrequency === 0) { return cliffFeeNumerator / FEE_DENOMINATOR * BASIS_POINT_MAX; } let baseFeeNumerator; if (baseFeeMode == 0 /* FeeSchedulerLinear */) { baseFeeNumerator = cliffFeeNumerator - numberOfPeriod * reductionFactor; } else { const decayRate = 1 - reductionFactor / BASIS_POINT_MAX; baseFeeNumerator = cliffFeeNumerator * Math.pow(decayRate, numberOfPeriod); } return Math.max(0, baseFeeNumerator / FEE_DENOMINATOR * BASIS_POINT_MAX); } function getRateLimiterParams(baseFeeBps, feeIncrementBps, referenceAmount, maxLimiterDuration, tokenQuoteDecimal, activationType) { const cliffFeeNumerator = bpsToFeeNumerator(baseFeeBps); const feeIncrementNumerator = bpsToFeeNumerator(feeIncrementBps); if (baseFeeBps <= 0 || feeIncrementBps <= 0 || referenceAmount <= 0 || maxLimiterDuration <= 0) { throw new Error("All rate limiter parameters must be greater than zero"); } if (baseFeeBps > MAX_FEE_BPS) { throw new Error( `Base fee (${baseFeeBps} bps) exceeds maximum allowed value of ${MAX_FEE_BPS} bps` ); } if (feeIncrementBps > MAX_FEE_BPS) { throw new Error( `Fee increment (${feeIncrementBps} bps) exceeds maximum allowed value of ${MAX_FEE_BPS} bps` ); } if (feeIncrementNumerator.gte(new (0, _bnjs2.default)(FEE_DENOMINATOR))) { throw new Error( "Fee increment numerator must be less than FEE_DENOMINATOR" ); } const deltaNumerator = new (0, _bnjs2.default)(MAX_FEE_NUMERATOR).sub(cliffFeeNumerator); const maxIndex = deltaNumerator.div(feeIncrementNumerator); if (maxIndex.lt(new (0, _bnjs2.default)(1))) { throw new Error("Fee increment is too large for the given base fee"); } if (cliffFeeNumerator.lt(new (0, _bnjs2.default)(MIN_FEE_NUMERATOR)) || cliffFeeNumerator.gt(new (0, _bnjs2.default)(MAX_FEE_NUMERATOR))) { throw new Error("Base fee must be between 0.01% and 99%"); } const maxDuration = activationType === 0 /* Slot */ ? MAX_RATE_LIMITER_DURATION_IN_SLOTS : MAX_RATE_LIMITER_DURATION_IN_SECONDS; if (maxLimiterDuration > maxDuration) { throw new Error( `Max duration exceeds maximum allowed value of ${maxDuration}` ); } const referenceAmountInLamports = convertToLamports( referenceAmount, tokenQuoteDecimal ); return { cliffFeeNumerator, firstFactor: feeIncrementBps, secondFactor: new (0, _bnjs2.default)(maxLimiterDuration), thirdFactor: new (0, _bnjs2.default)(referenceAmountInLamports), baseFeeMode: 2 /* RateLimiter */ }; } function getDynamicFeeParams(baseFeeBps, maxPriceChangeBps = MAX_PRICE_CHANGE_BPS_DEFAULT) { if (maxPriceChangeBps > MAX_PRICE_CHANGE_BPS_DEFAULT) { throw new Error( `maxPriceChangeBps (${maxPriceChangeBps} bps) must be less than or equal to ${MAX_PRICE_CHANGE_BPS_DEFAULT}` ); } const priceRatio = maxPriceChangeBps / BASIS_POINT_MAX + 1; const sqrtPriceRatioQ64 = new (0, _bnjs2.default)( _decimaljs2.default.sqrt(priceRatio.toString()).mul(_decimaljs2.default.pow(2, 64)).floor().toFixed() ); const deltaBinId = sqrtPriceRatioQ64.sub(ONE_Q64).div(BIN_STEP_BPS_U128_DEFAULT).muln(2); const maxVolatilityAccumulator = new (0, _bnjs2.default)(deltaBinId.muln(BASIS_POINT_MAX)); const squareVfaBin = maxVolatilityAccumulator.mul(new (0, _bnjs2.default)(BIN_STEP_BPS_DEFAULT)).pow(new (0, _bnjs2.default)(2)); const baseFeeNumerator = new (0, _bnjs2.default)(bpsToFeeNumerator(baseFeeBps)); const maxDynamicFeeNumerator = baseFeeNumerator.muln(20).divn(100); const vFee = maxDynamicFeeNumerator.mul(new (0, _bnjs2.default)(1e11)).sub(new (0, _bnjs2.default)(99999999999)); const variableFeeControl = vFee.div(squareVfaBin); return { binStep: BIN_STEP_BPS_DEFAULT, binStepU128: BIN_STEP_BPS_U128_DEFAULT, filterPeriod: DYNAMIC_FEE_FILTER_PERIOD_DEFAULT, decayPeriod: DYNAMIC_FEE_DECAY_PERIOD_DEFAULT, reductionFactor: DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT, maxVolatilityAccumulator: maxVolatilityAccumulator.toNumber(), variableFeeControl: variableFeeControl.toNumber() }; } function getLockedVestingParams(totalLockedVestingAmount, numberOfVestingPeriod, cliffUnlockAmount, totalVestingDuration, cliffDurationFromMigrationTime, tokenBaseDecimal) { if (totalLockedVestingAmount == 0) { return { amountPerPeriod: new (0, _bnjs2.default)(0), cliffDurationFromMigrationTime: new (0, _bnjs2.default)(0), frequency: new (0, _bnjs2.default)(0), numberOfPeriod: new (0, _bnjs2.default)(0), cliffUnlockAmount: new (0, _bnjs2.default)(0) }; } if (totalLockedVestingAmount == cliffUnlockAmount) { return { amountPerPeriod: convertToLamports(1, tokenBaseDecimal), cliffDurationFromMigrationTime: new (0, _bnjs2.default)( cliffDurationFromMigrationTime ), frequency: new (0, _bnjs2.default)(1), numberOfPeriod: new (0, _bnjs2.default)(1), cliffUnlockAmount: convertToLamports( totalLockedVestingAmount - 1, tokenBaseDecimal ) }; } if (numberOfVestingPeriod <= 0) { throw new Error("Total periods must be greater than zero"); } if (numberOfVestingPeriod == 0 || totalVestingDuration == 0) { throw new Error( "numberOfPeriod and totalVestingDuration must both be greater than zero" ); } if (cliffUnlockAmount > totalLockedVestingAmount) { throw new Error( "Cliff unlock amount cannot be greater than total locked vesting amount" ); } const amountPerPeriod = (totalLockedVestingAmount - cliffUnlockAmount) / numberOfVestingPeriod; const roundedAmountPerPeriod = Math.floor(amountPerPeriod); const totalPeriodicAmount = roundedAmountPerPeriod * numberOfVestingPeriod; const remainder = totalLockedVestingAmount - (cliffUnlockAmount + totalPeriodicAmount); const adjustedCliffUnlockAmount = cliffUnlockAmount + remainder; const periodFrequency = new (0, _bnjs2.default)(totalVestingDuration / numberOfVestingPeriod); return { amountPerPeriod: convertToLamports( roundedAmountPerPeriod, tokenBaseDecimal ), cliffDurationFromMigrationTime: new (0, _bnjs2.default)(cliffDurationFromMigrationTime), frequency: periodFrequency, numberOfPeriod: new (0, _bnjs2.default)(numberOfVestingPeriod), cliffUnlockAmount: convertToLamports( adjustedCliffUnlockAmount, tokenBaseDecimal ) }; } var getTwoCurve = (migrationSqrtPrice, midSqrtPrice, initialSqrtPrice, swapAmount, migrationQuoteThreshold) => { let p0 = new (0, _decimaljs2.default)(initialSqrtPrice.toString()); let p1 = new (0, _decimaljs2.default)(midSqrtPrice.toString()); let p2 = new (0, _decimaljs2.default)(migrationSqrtPrice.toString()); let a1 = new (0, _decimaljs2.default)(1).div(p0).sub(new (0, _decimaljs2.default)(1).div(p1)); let b1 = new (0, _decimaljs2.default)(1).div(p1).sub(new (0, _decimaljs2.default)(1).div(p2)); let c1 = new (0, _decimaljs2.default)(swapAmount.toString()); let a2 = p1.sub(p0); let b2 = p2.sub(p1); let c2 = new (0, _decimaljs2.default)(migrationQuoteThreshold.toString()).mul( _decimaljs2.default.pow(2, 128) ); let l0 = c1.mul(b2).sub(c2.mul(b1)).div(a1.mul(b2).sub(a2.mul(b1))); let l1 = c1.mul(a2).sub(c2.mul(a1)).div(b1.mul(a2).sub(b2.mul(a1))); if (l0.isNeg() || l1.isNeg()) { return { isOk: false, sqrtStartPrice: new (0, _bnjs2.default)(0), curve: [] }; } return { isOk: true, sqrtStartPrice: initialSqrtPrice, curve: [ { sqrtPrice: midSqrtPrice, liquidity: new (0, _bnjs2.default)(l0.floor().toFixed()) }, { sqrtPrice: migrationSqrtPrice, liquidity: new (0, _bnjs2.default)(l1.floor().toFixed()) } ] }; }; function checkRateLimiterApplied(baseFeeMode, swapBaseForQuote, currentPoint, activationPoint, maxLimiterDuration) { return baseFeeMode === 2 /* RateLimiter */ && !swapBaseForQuote && currentPoint.gte(activationPoint) && currentPoint.lte(activationPoint.add(maxLimiterDuration)); } function getBaseFeeParams(baseFeeParams, tokenQuoteDecimal, activationType) { if (baseFeeParams.baseFeeMode === 2 /* RateLimiter */) { if (!baseFeeParams.rateLimiterParam) { throw new Error( "Rate limiter parameters are required for RateLimiter mode" ); } const { baseFeeBps, feeIncrementBps, referenceAmount, maxLimiterDuration } = baseFeeParams.rateLimiterParam; return getRateLimiterParams( baseFeeBps, feeIncrementBps, referenceAmount, maxLimiterDuration, tokenQuoteDecimal, activationType ); } else { if (!baseFeeParams.feeSchedulerParam) { throw new Error( "Fee scheduler parameters are required for FeeScheduler mode" ); } const { startingFeeBps, endingFeeBps, numberOfPeriod, totalDuration } = baseFeeParams.feeSchedulerParam; return getFeeSchedulerParams( startingFeeBps, endingFeeBps, baseFeeParams.baseFeeMode, numberOfPeriod, totalDuration ); } } function getQuoteReserveFromNextSqrtPrice(nextSqrtPrice, config) { let totalAmount = new (0, _bnjs2.default)(0); for (let i = 0; i < config.curve.length; i++) { const lowerSqrtPrice = i === 0 ? config.sqrtStartPrice : config.curve[i - 1].sqrtPrice; if (nextSqrtPrice.gt(lowerSqrtPrice)) { const upperSqrtPrice = nextSqrtPrice.lt(config.curve[i].sqrtPrice) ? nextSqrtPrice : config.curve[i].sqrtPrice; const maxAmountIn = getDeltaAmountQuoteUnsigned( lowerSqrtPrice, upperSqrtPrice, config.curve[i].liquidity, 0 /* Up */ ); totalAmount = totalAmount.add(maxAmountIn); } } return totalAmount; } var getTokenomics = (initialMarketCap, migrationMarketCap, totalLockedVestingAmount, totalLeftover, totalTokenSupply) => { const marketCapRatio = initialMarketCap.div(migrationMarketCap); const sqrtRatio = _decimaljs2.default.sqrt(marketCapRatio); const vestingPercentage = new (0, _decimaljs2.default)(totalLockedVestingAmount.toString()).mul(new (0, _decimaljs2.default)(100)).div(new (0, _decimaljs2.default)(totalTokenSupply.toString())); const leftoverPercentage = new (0, _decimaljs2.default)(totalLeftover.toString()).mul(new (0, _decimaljs2.default)(100)).div(new (0, _decimaljs2.default)(totalTokenSupply.toString())); const percentageSupplyOnMigration = new (0, _decimaljs2.default)(100).mul(sqrtRatio).sub(vestingPercentage.add(leftoverPercentage).mul(sqrtRatio)); const denominator = new (0, _decimaljs2.default)(1).add(sqrtRatio); const migrationSupplyDecimal = percentageSupplyOnMigration.div(denominator).mul(new (0, _decimaljs2.default)(totalTokenSupply.toString())).div(new (0, _decimaljs2.default)(100)); const migrationSupply = new (0, _bnjs2.default)(migrationSupplyDecimal.floor().toFixed()); const bondingCurveSupply = totalTokenSupply.sub(migrationSupply).sub(totalLeftover).sub(totalLockedVestingAmount); return { bondingCurveSupply, migrationSupply, leftoverSupply: totalLeftover, lockedVestingSupply: totalLockedVestingAmount }; }; function getMigratedPoolFeeParams(migrationOption, migrationFeeOption, migratedPoolFee) { const defaultFeeParams = { collectFeeMode: 0, dynamicFee: 0, poolFeeBps: 0 }; if (migrationOption === 0 /* MET_DAMM */) { return defaultFeeParams; } if (migrationOption === 1 /* MET_DAMM_V2 */) { if (migrationFeeOption === 6 /* Customizable */) { return migratedPoolFee; } return defaultFeeParams; } return defaultFeeParams; } async function getCurrentPoint(connection, activationType) { const currentSlot = await connection.getSlot(); if (activationType === 0 /* Slot */) { return new (0, _bnjs2.default)(currentSlot); } else { const currentTime = await connection.getBlockTime(currentSlot); return new (0, _bnjs2.default)(currentTime); } } async function prepareSwapAmountParam(amount, mintAddress, connection) { const mintTokenDecimals = await getTokenDecimals(connection, mintAddress); return convertToLamports(amount, mintTokenDecimals); } // src/helpers/accounts.ts var SEED = Object.freeze({ POOL_AUTHORITY: "pool_authority", EVENT_AUTHORITY: "__event_authority", POOL: "pool", TOKEN_VAULT: "token_vault", METADATA: "metadata", PARTNER_METADATA: "partner_metadata", CLAIM_FEE_OPERATOR: "cf_operator", DAMM_V1_MIGRATION_METADATA: "meteora", DAMM_V2_MIGRATION_METADATA: "damm_v2", LP_MINT: "lp_mint", FEE: "fee", POSITION: "position", POSITION_NFT_ACCOUNT: "position_nft_account", LOCK_ESCROW: "lock_escrow", VIRTUAL_POOL_METADATA: "virtual_pool_metadata", ESCROW: "escrow", BASE_LOCKER: "base_locker", VAULT: "vault" }); function deriveDbcEventAuthority() { const [eventAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.EVENT_AUTHORITY)], DYNAMIC_BONDING_CURVE_PROGRAM_ID ); return eventAuthority; } function deriveDammV1EventAuthority() { const [eventAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.EVENT_AUTHORITY)], DAMM_V1_PROGRAM_ID ); return eventAuthority; } function deriveDammV2EventAuthority() { const [eventAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.EVENT_AUTHORITY)], DAMM_V2_PROGRAM_ID ); return eventAuthority; } function deriveLockerEventAuthority() { const [eventAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.EVENT_AUTHORITY)], LOCKER_PROGRAM_ID ); return eventAuthority; } function deriveDbcPoolAuthority() { const [poolAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.POOL_AUTHORITY)], DYNAMIC_BONDING_CURVE_PROGRAM_ID ); return poolAuthority; } function deriveDammV1PoolAuthority() { const [poolAuthority] = _web3js.PublicKey.findProgramAddressSync( [Buffer.from(SEED.POOL_AUTHORITY)], DAMM_V1_PROGRAM_ID ); return p