@panoptic-eng/sdk 1.0.68 → 1.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cow/index.js +47 -2
- package/dist/cow/index.js.map +1 -1
- package/dist/{cow-CGgPXhY6.js → cow-sGuN0eas.js} +1 -1
- package/dist/{greeks-CGtgLUyh.js → greeks-DNPP24KL.js} +115 -9
- package/dist/index.d.ts +67 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +161 -62
- package/dist/index.js.map +1 -1
- package/dist/{irm-BDxwCFDm.js → irm-6RzXXa1_.js} +927 -3
- package/dist/panoptic/v2/greeks/index.d.ts +7 -4
- package/dist/panoptic/v2/greeks/index.d.ts.map +1 -1
- package/dist/panoptic/v2/greeks/index.js +74 -7
- package/dist/panoptic/v2/greeks/index.js.map +1 -1
- package/dist/panoptic/v2/index.d.ts +244 -6
- package/dist/panoptic/v2/index.d.ts.map +1 -1
- package/dist/panoptic/v2/index.js +2554 -464
- package/dist/panoptic/v2/index.js.map +1 -1
- package/dist/panoptic/v2/react-public.d.ts +258 -9
- package/dist/panoptic/v2/react-public.d.ts.map +1 -1
- package/dist/panoptic/v2/react-public.js +4655 -2909
- package/dist/panoptic/v2/react-public.js.map +1 -1
- package/dist/{providers-DubVMHWU.js → providers-CbcNt27n.js} +2 -1
- package/dist/{rates-BHS-Qiu7.js → rates-DDK4ZimJ.js} +40 -4
- package/dist/{router-BW6TqwOO.js → router-njWsLvZc.js} +969 -39
- package/dist/rpc/index.d.ts +12 -1
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +65 -5
- package/dist/rpc/index.js.map +1 -1
- package/dist/uniswap/index.js +53 -13
- package/dist/uniswap/index.js.map +1 -1
- package/dist/{v2-Dgh6JxG_.js → v2-BrG4T_Gh.js} +681 -32
- package/dist/{writes-CG612Vuk.js → writes-CI6Haer-.js} +34 -3
- package/package.json +1 -1
- package/dist/router-IDtCENST.js +0 -942
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { getAccountCollateral, getNetLiquidationValue, panopticQueryAbi, readBlockAndAggregate, requireReturnData } from "./irm-
|
|
2
|
-
import { AccountInsolventError, ChunkLimitError, DEFAULT_VEGOID, InvalidHistoryRangeError, MulticallResultMissingError, NotEnoughTokensError, PanopticError, PanopticValidationError, SafeModeError, StaleDataError, StorageDataNotFoundError, UnhealthyPoolError, WrongUniswapPoolError, applyMintBufferPerToken, availableToBorrow, collateralTrackerV2Abi, decodeLeftRightSigned, decodeLeftRightUnsigned, decodePositionBalance, getBlockMeta, getClosedPositionsKey, getPendingPositionsKey, getPool, getPoolMetaKey, getPoolMetadata, getPositionMetaKey, getPositionsKey, getTrackedChunksKey, getTrackedPositionIds, isPanopticErrorType, jsonSerializer, mintableAfterBuffer, panopticFactoryV3Abi, panopticFactoryV4Abi, panopticGuardianAbi, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi$1, parsePanopticError, riskEngineAbi, riskEngineMulticall, semiFungiblePositionManagerV3Abi, semiFungiblePositionManagerV4Abi, stateViewAbi, uniswapV3PoolAbi } from "./rates-
|
|
3
|
-
import { MAX_TICK, MAX_TRACKED_CHUNKS, MIN_TICK, NO_LOWER_LIQUIDATION_TICK, NO_UPPER_LIQUIDATION_TICK, WAD, calculatePositionDelta, calculatePositionDeltaDebtOnly, calculatePositionGamma, calculatePositionValue, priceToTick, sqrtPriceX96ToTick, tickLimits, tickToPriceDecimalScaled, tickToSqrtPriceX96, toVaultFrameAtTick } from "./greeks-
|
|
4
|
-
import { addLegToTokenId, buildBatchDispatchArgs, buildUniqueCredit, buildUniqueLoan, countLegs, createTokenIdBuilder, decodeAllLegs, decodeTokenId, getCurrentPositionSizes, getPoolTokensForSimulation, loadCheckpoint, resolveTokenIndex, simulateDispatch, simulateOpenPosition, simulateWithTokenFlow } from "./writes-
|
|
5
|
-
import { feesFromFeeGrowthDelta, getLpPositionFunding, getMaxLpPositionSize, getPriceHistory, preparePositionGamma } from "./router-
|
|
6
|
-
import { ContractFunctionExecutionError, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, getAddress, hexToString, keccak256, parseAbi, parseEventLogs, trim, zeroAddress } from "viem";
|
|
1
|
+
import { UniswapV3PoolAbi, getAccountCollateral, getNetLiquidationValue, panopticQueryAbi, readBlockAndAggregate, requireReturnData } from "./irm-6RzXXa1_.js";
|
|
2
|
+
import { AccountInsolventError, ChunkLimitError, DEFAULT_VEGOID, InvalidHistoryRangeError, MulticallResultMissingError, NotEnoughTokensError, PanopticError, PanopticValidationError, SafeModeError, StaleDataError, StorageDataNotFoundError, UnhealthyPoolError, WrongUniswapPoolError, applyMintBufferPerToken, availableToBorrow, collateralTrackerV2Abi, decodeLeftRightSigned, decodeLeftRightUnsigned, decodePositionBalance, getBlockMeta, getClosedPositionsKey, getPendingPositionsKey, getPool, getPoolMetaKey, getPoolMetadata, getPositionMetaKey, getPositionsKey, getTrackedChunksKey, getTrackedPositionIds, isPanopticErrorType, jsonSerializer, mintableAfterBuffer, panopticFactoryV3Abi, panopticFactoryV4Abi, panopticGuardianAbi, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi$1, parsePanopticError, riskEngineAbi, riskEngineMulticall, semiFungiblePositionManagerV3Abi, semiFungiblePositionManagerV4Abi, stateViewAbi, uniswapV3PoolAbi } from "./rates-DDK4ZimJ.js";
|
|
3
|
+
import { MAX_TICK, MAX_TRACKED_CHUNKS, MIN_TICK, NO_LOWER_LIQUIDATION_TICK, NO_UPPER_LIQUIDATION_TICK, WAD, calculatePositionDelta, calculatePositionDeltaDebtOnly, calculatePositionGamma, calculatePositionValue, getLegLiquidityRange, priceToTick, sqrtPriceX96ToTick, tickLimits, tickToPriceDecimalScaled, tickToSqrtPriceX96, toVaultFrameAtTick } from "./greeks-DNPP24KL.js";
|
|
4
|
+
import { addLegToTokenId, buildBatchDispatchArgs, buildProtectedSettlePlan, buildSettleSequenceCalls, buildUniqueCredit, buildUniqueLoan, countLegs, createTokenIdBuilder, decodeAllLegs, decodeTokenId, getCurrentPositionSizes, getPoolTokensForSimulation, loadCheckpoint, resolveTokenIndex, simulateDispatch, simulateOpenPosition, simulateWithTokenFlow } from "./writes-CI6Haer-.js";
|
|
5
|
+
import { feesFromFeeGrowthDelta, getLpPositionFunding, getMaxLpPositionSize, getPriceHistory, preparePositionGamma, quoteSwapExactOutViaRouter, quoteSwapExactOutViaV3Router } from "./router-njWsLvZc.js";
|
|
6
|
+
import { ContractFunctionExecutionError, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, getAddress, hexToString, isAddress, isAddressEqual, isHex, keccak256, parseAbi, parseEventLogs, trim, zeroAddress } from "viem";
|
|
7
7
|
import { multicall } from "viem/actions";
|
|
8
8
|
import Decimal from "decimal.js";
|
|
9
9
|
|
|
@@ -656,13 +656,15 @@ function getNotEnoughTokensError(error) {
|
|
|
656
656
|
let current = error;
|
|
657
657
|
while (current !== void 0 && current !== null && !visited.has(current)) {
|
|
658
658
|
visited.add(current);
|
|
659
|
-
const
|
|
659
|
+
const decoded = parsePanopticError(current);
|
|
660
|
+
const parsed = current instanceof NotEnoughTokensError ? current : decoded?.error;
|
|
660
661
|
const candidate = parsed instanceof NotEnoughTokensError ? parsed : null;
|
|
661
662
|
if (candidate !== null) {
|
|
662
663
|
const args = candidate;
|
|
663
|
-
if (args.tokenAddress
|
|
664
|
+
if (typeof args.tokenAddress === "string" && isAddress(args.tokenAddress) && typeof args.assetsRequested === "bigint" && typeof args.assetBalance === "bigint") return candidate;
|
|
664
665
|
}
|
|
665
|
-
|
|
666
|
+
const innerData = decoded?.errorName === "ExecuteError" ? decoded.args[1] : void 0;
|
|
667
|
+
current = typeof innerData === "string" && isHex(innerData) ? { data: innerData } : current instanceof Error && "cause" in current ? current.cause : void 0;
|
|
666
668
|
}
|
|
667
669
|
return null;
|
|
668
670
|
}
|
|
@@ -670,7 +672,7 @@ function maximumAmountIn(estimatedAmountIn, slippageBps) {
|
|
|
670
672
|
if (slippageBps < 0n) throw new PanopticError("slippageBps must be non-negative");
|
|
671
673
|
return (estimatedAmountIn * (BPS_DENOMINATOR$2 + slippageBps) + BPS_DENOMINATOR$2 - 1n) / BPS_DENOMINATOR$2;
|
|
672
674
|
}
|
|
673
|
-
function ceilDiv$
|
|
675
|
+
function ceilDiv$3(numerator, denominator) {
|
|
674
676
|
return (numerator + denominator - 1n) / denominator;
|
|
675
677
|
}
|
|
676
678
|
function getInputAmount(tokenFlow, tokenInIndex) {
|
|
@@ -775,7 +777,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
775
777
|
const estimatedAmountIn = getInputAmount(swapSimulation.tokenFlow, tokenInIndex);
|
|
776
778
|
const estimatedAmountOut = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex);
|
|
777
779
|
if (estimatedAmountOut < requiredOutput) {
|
|
778
|
-
creditInput = estimatedAmountOut > 0n ? ceilDiv$
|
|
780
|
+
creditInput = estimatedAmountOut > 0n ? ceilDiv$3(creditInput * requiredOutput, estimatedAmountOut) + 1n : creditInput * 2n;
|
|
779
781
|
continue;
|
|
780
782
|
}
|
|
781
783
|
const recoveredDispatch = buildPrefixedExactInputRecoveryDispatch({
|
|
@@ -830,7 +832,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
830
832
|
};
|
|
831
833
|
const residual = remainingShortfall.assetsRequested - remainingShortfall.assetBalance;
|
|
832
834
|
requiredOutput += residual > 0n ? residual : requiredOutput;
|
|
833
|
-
creditInput = ceilDiv$
|
|
835
|
+
creditInput = ceilDiv$3(creditInput * requiredOutput, estimatedAmountOut) + 1n;
|
|
834
836
|
}
|
|
835
837
|
return {
|
|
836
838
|
available: false,
|
|
@@ -885,7 +887,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
885
887
|
const maxAmountIn = maximumAmountIn(estimatedAmountIn, params.slippageBps);
|
|
886
888
|
const swapOutput = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex);
|
|
887
889
|
if (swapOutput < amountOut) {
|
|
888
|
-
creditOutSize = swapOutput > 0n ? ceilDiv$
|
|
890
|
+
creditOutSize = swapOutput > 0n ? ceilDiv$3(creditOutSize * amountOut, swapOutput) + 1n : creditOutSize * 2n;
|
|
889
891
|
continue;
|
|
890
892
|
}
|
|
891
893
|
const recoverySimulation = await simulateDispatch({
|
|
@@ -940,7 +942,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
940
942
|
if (decodedShortfall >= shortfallError.assetsRequested - shortfallError.assetBalance) return quotePrefixedExactInput(amountOut);
|
|
941
943
|
const additionalAmountOut = decodedShortfall > 0n ? decodedShortfall : amountOut;
|
|
942
944
|
amountOut += additionalAmountOut;
|
|
943
|
-
creditOutSize = swapOutput > 0n ? ceilDiv$
|
|
945
|
+
creditOutSize = swapOutput > 0n ? ceilDiv$3(creditOutSize * amountOut, swapOutput) + 1n : creditOutSize * 2n;
|
|
944
946
|
}
|
|
945
947
|
return quotePrefixedExactInput(shortfallError.assetsRequested - shortfallError.assetBalance);
|
|
946
948
|
}
|
|
@@ -2248,7 +2250,7 @@ async function getItmAmounts(params) {
|
|
|
2248
2250
|
* high-decimal amount can't masquerade as real flow.
|
|
2249
2251
|
*/
|
|
2250
2252
|
const FLOW_NEUTRAL_DUST_THRESHOLD = 1000n;
|
|
2251
|
-
const Q192$
|
|
2253
|
+
const Q192$3 = 1n << 192n;
|
|
2252
2254
|
const POOL_ID_MASK$1 = (1n << 64n) - 1n;
|
|
2253
2255
|
/**
|
|
2254
2256
|
* Floor integer square root for bigints (Newton's method). Exact for all
|
|
@@ -2284,7 +2286,7 @@ function buildNeutralLeg(tokenIndex, signedAmount, positionSize) {
|
|
|
2284
2286
|
const absAmount = signedAmount < 0n ? -signedAmount : signedAmount;
|
|
2285
2287
|
const legAsset = tokenIndex === 0n ? 1n : 0n;
|
|
2286
2288
|
const legIsLong = signedAmount < 0n;
|
|
2287
|
-
const sqrtKrawX96 = isqrt(absAmount * Q192$
|
|
2289
|
+
const sqrtKrawX96 = isqrt(absAmount * Q192$3 / positionSize);
|
|
2288
2290
|
let signedTick;
|
|
2289
2291
|
try {
|
|
2290
2292
|
signedTick = sqrtPriceX96ToTick(sqrtKrawX96);
|
|
@@ -2542,7 +2544,7 @@ async function createFlowNeutralTokenId(params) {
|
|
|
2542
2544
|
const sqrtPX96 = tickToSqrtPriceX96(tickBefore);
|
|
2543
2545
|
const valueAbs = (index, amount) => {
|
|
2544
2546
|
const abs$1 = amount < 0n ? -amount : amount;
|
|
2545
|
-
return index === 0n ? abs$1 * sqrtPX96 * sqrtPX96 / Q192$
|
|
2547
|
+
return index === 0n ? abs$1 * sqrtPX96 * sqrtPX96 / Q192$3 : abs$1;
|
|
2546
2548
|
};
|
|
2547
2549
|
const flowFor = (index) => index === 0n ? credit.creditAmount0 : credit.creditAmount1;
|
|
2548
2550
|
if (queryAddress !== void 0) {
|
|
@@ -3515,7 +3517,7 @@ async function getPoolLiquidities(params) {
|
|
|
3515
3517
|
|
|
3516
3518
|
//#endregion
|
|
3517
3519
|
//#region src/panoptic/v2/reads/accountGreeks.ts
|
|
3518
|
-
const Q192$
|
|
3520
|
+
const Q192$2 = 1n << 192n;
|
|
3519
3521
|
/**
|
|
3520
3522
|
* Calculate account-level greeks using stored position data.
|
|
3521
3523
|
*
|
|
@@ -3636,8 +3638,8 @@ async function getAccountGreeks(params) {
|
|
|
3636
3638
|
const assetBal = isAssetToken0 ? collateral.token0.assets : collateral.token1.assets;
|
|
3637
3639
|
const otherBal = isAssetToken0 ? collateral.token1.assets : collateral.token0.assets;
|
|
3638
3640
|
const sqrtPriceX96 = tickToSqrtPriceX96(BigInt(currentTick));
|
|
3639
|
-
if (isAssetToken0) collateralValue = assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
3640
|
-
else collateralValue = assetBal * Q192$
|
|
3641
|
+
if (isAssetToken0) collateralValue = assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 + otherBal;
|
|
3642
|
+
else collateralValue = assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96) + otherBal;
|
|
3641
3643
|
collateralDelta = assetBal;
|
|
3642
3644
|
}
|
|
3643
3645
|
return {
|
|
@@ -3677,7 +3679,7 @@ function calculateAccountGreeksPure(params) {
|
|
|
3677
3679
|
const totalDelta$1 = [];
|
|
3678
3680
|
for (let i = 0; i < n; i++) {
|
|
3679
3681
|
const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i]);
|
|
3680
|
-
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
3682
|
+
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 : assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96);
|
|
3681
3683
|
totalValue$1.push(assetValueInNumeraire + otherBal);
|
|
3682
3684
|
totalDelta$1.push(assetBal);
|
|
3683
3685
|
}
|
|
@@ -3727,7 +3729,7 @@ function calculateAccountGreeksPure(params) {
|
|
|
3727
3729
|
}
|
|
3728
3730
|
for (let i = 0; i < n; i++) {
|
|
3729
3731
|
const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i]);
|
|
3730
|
-
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
3732
|
+
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 : assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96);
|
|
3731
3733
|
totalValue[i] += assetValueInNumeraire + otherBal;
|
|
3732
3734
|
totalDelta[i] += assetBal;
|
|
3733
3735
|
}
|
|
@@ -5321,10 +5323,10 @@ async function processClosedPositions(client, queryAddress, positions) {
|
|
|
5321
5323
|
//#endregion
|
|
5322
5324
|
//#region src/panoptic/v2/reads/hedgeCapacity.ts
|
|
5323
5325
|
const SCALE$1 = 10000000n;
|
|
5324
|
-
const FEE_SCALE = 10000n;
|
|
5325
|
-
const Q192 = 1n << 192n;
|
|
5326
|
+
const FEE_SCALE$1 = 10000n;
|
|
5327
|
+
const Q192$1 = 1n << 192n;
|
|
5326
5328
|
const MASK128$1 = (1n << 128n) - 1n;
|
|
5327
|
-
const ceilDiv$
|
|
5329
|
+
const ceilDiv$2 = (value, divisor) => (value + divisor - 1n) / divisor;
|
|
5328
5330
|
function accountHedgeDelta({ positionIds, balances, collateralDelta, tick, tickSpacing, assetIndex }) {
|
|
5329
5331
|
return positionIds.reduce((sum$1, id, index) => {
|
|
5330
5332
|
const balance = balances[index];
|
|
@@ -5344,8 +5346,8 @@ function accountHedgeDelta({ positionIds, balances, collateralDelta, tick, tickS
|
|
|
5344
5346
|
function buildCapacityHedge({ delta, assetIndex, tick, tickSpacing, poolId, notionalFee, swapFee }) {
|
|
5345
5347
|
const borrowToken = delta >= 0n ? assetIndex : assetIndex === 0n ? 1n : 0n;
|
|
5346
5348
|
const receiveToken = borrowToken === 0n ? 1n : 0n;
|
|
5347
|
-
const amount = delta >= 0n ? delta : ceilDiv$
|
|
5348
|
-
const commission = ceilDiv$
|
|
5349
|
+
const amount = delta >= 0n ? delta : ceilDiv$2((toVaultFrameAtTick(-delta, assetIndex, borrowToken, tick) + 1n) * 1000000n * FEE_SCALE$1, (1000000n - swapFee) * (FEE_SCALE$1 - notionalFee));
|
|
5350
|
+
const commission = ceilDiv$2(amount * notionalFee, FEE_SCALE$1);
|
|
5349
5351
|
const proceeds = toVaultFrameAtTick((amount - commission) * (1000000n - swapFee) / 1000000n, borrowToken, receiveToken, tick);
|
|
5350
5352
|
const tokenId = addLegToTokenId(poolId, {
|
|
5351
5353
|
index: 0n,
|
|
@@ -5377,7 +5379,7 @@ function hedgeMargin({ tokenData, balanceChanges, crossRatios, tick, buffer }) {
|
|
|
5377
5379
|
const surplus1 = balances[1] > required1 ? (balances[1] - required1) * crossRatios[1] / SCALE$1 : 0n;
|
|
5378
5380
|
const sqrt = tickToSqrtPriceX96(tick);
|
|
5379
5381
|
const price = sqrt * sqrt;
|
|
5380
|
-
const pairs = sqrt < 1n << 96n ? [[balances[0] + surplus1 * Q192 / price, required0], [balances[1] * Q192 / price + surplus0, ceilDiv$
|
|
5382
|
+
const pairs = sqrt < 1n << 96n ? [[balances[0] + surplus1 * Q192$1 / price, required0], [balances[1] * Q192$1 / price + surplus0, ceilDiv$2(required1 * Q192$1, price)]] : [[balances[0] * price / Q192$1 + surplus1, ceilDiv$2(required0 * price, Q192$1)], [balances[1] + surplus0 * price / Q192$1, required1]];
|
|
5381
5383
|
const headroom = pairs.map(([balance, required]) => balance - required);
|
|
5382
5384
|
return {
|
|
5383
5385
|
solvent: balances.every((balance) => balance >= 0n) && headroom.every((value) => value >= 0n),
|
|
@@ -5590,7 +5592,7 @@ async function getHedgeLimits({ client, poolAddress, account, positionIds, asset
|
|
|
5590
5592
|
if (hedge.amount > 0n && BigInt(legCount) >= maxLegs) return unavailable("leg-limit");
|
|
5591
5593
|
const totalAssets = hedge.borrowToken === 0n ? total0 : total1;
|
|
5592
5594
|
if (hedge.amount > 0n && (hedge.amount > MAX_SIZE || hedge.amount > borrowCapacity[Number(hedge.borrowToken)] || totalAssets === 0n)) return unavailable("capacity");
|
|
5593
|
-
const projectedUtilization = currentUtilizations.map((util, i) => hedge.amount > 0n && BigInt(i) === hedge.borrowToken ? ceilDiv$
|
|
5595
|
+
const projectedUtilization = currentUtilizations.map((util, i) => hedge.amount > 0n && BigInt(i) === hedge.borrowToken ? ceilDiv$2(util * totalAssets + hedge.amount * 10000n, totalAssets) : util);
|
|
5594
5596
|
if (hedge.amount > 0n && projectedUtilization.some((util) => util > 10000n)) return unavailable("capacity");
|
|
5595
5597
|
const global = projectedUtilization.map((util, i) => util > globalUtilizations[i] ? util : globalUtilizations[i]);
|
|
5596
5598
|
const syntheticBalance = hedge.amount | projectedUtilization[0] << 128n | projectedUtilization[1] << 144n;
|
|
@@ -5682,6 +5684,90 @@ async function getHedgeLimits({ client, poolAddress, account, positionIds, asset
|
|
|
5682
5684
|
};
|
|
5683
5685
|
}
|
|
5684
5686
|
|
|
5687
|
+
//#endregion
|
|
5688
|
+
//#region src/panoptic/v2/reads/positionMintFunding.ts
|
|
5689
|
+
const Q96 = 1n << 96n;
|
|
5690
|
+
const Q192 = 1n << 192n;
|
|
5691
|
+
const BPS = 10000n;
|
|
5692
|
+
const FEE_SCALE = 1000000n;
|
|
5693
|
+
const max = (a, b) => a > b ? a : b;
|
|
5694
|
+
const ceilDiv$1 = (n, d) => n > 0n ? (n + d - 1n) / d : n / d;
|
|
5695
|
+
/**
|
|
5696
|
+
* Estimate deposit-independent mint funding, including settlement and commission.
|
|
5697
|
+
* Swaps use spot conversion with fees and slippage allowance; execution still needs a live quote.
|
|
5698
|
+
* Received tokens cover post-mint margin but cannot fund the other tracker's upfront payment.
|
|
5699
|
+
* Each requiredValue is the starting balance when funding entirely in that token.
|
|
5700
|
+
*/
|
|
5701
|
+
function getPositionMintFunding(params) {
|
|
5702
|
+
const { tokenId, positionSize, sqrtPriceX96, valuationSqrtPriceX96, swapAtMint, commissionRate, swapFee, slippageBps, required0, required1 } = params;
|
|
5703
|
+
if (positionSize < 0n || sqrtPriceX96 <= 0n || valuationSqrtPriceX96 <= 0n || commissionRate < 0n || swapFee < 0n || swapFee >= FEE_SCALE || slippageBps < 0n || slippageBps >= BPS || required0 < 0n || required1 < 0n) throw new RangeError("Invalid mint funding inputs");
|
|
5704
|
+
const { legs, tickSpacing } = decodeTokenId(tokenId);
|
|
5705
|
+
const firstLeg = legs[0];
|
|
5706
|
+
if (!firstLeg || tickSpacing <= 0n) throw new RangeError("Invalid position");
|
|
5707
|
+
let paid0 = 0n;
|
|
5708
|
+
let paid1 = 0n;
|
|
5709
|
+
let itm0 = 0n;
|
|
5710
|
+
let itm1 = 0n;
|
|
5711
|
+
let notional0 = 0n;
|
|
5712
|
+
let notional1 = 0n;
|
|
5713
|
+
for (const leg of legs) {
|
|
5714
|
+
const { sqrtLower, sqrtUpper, liquidity } = getLegLiquidityRange(leg.width === 0n ? {
|
|
5715
|
+
...leg,
|
|
5716
|
+
width: 2n
|
|
5717
|
+
} : leg, positionSize, tickSpacing);
|
|
5718
|
+
const round = !leg.isLong || leg.width === 0n ? ceilDiv$1 : (n, d) => n / d;
|
|
5719
|
+
const moved0 = round((liquidity << 96n) * (sqrtUpper - sqrtLower), sqrtUpper * sqrtLower);
|
|
5720
|
+
const moved1 = round(liquidity * (sqrtUpper - sqrtLower), Q96);
|
|
5721
|
+
const sign = leg.isLong ? -1n : 1n;
|
|
5722
|
+
let amm0 = 0n;
|
|
5723
|
+
let amm1 = 0n;
|
|
5724
|
+
if (leg.width > 0n) {
|
|
5725
|
+
const price = max(sqrtLower, sqrtPriceX96 < sqrtUpper ? sqrtPriceX96 : sqrtUpper);
|
|
5726
|
+
amm0 = sign * round((liquidity << 96n) * (sqrtUpper - price), sqrtUpper * price);
|
|
5727
|
+
amm1 = sign * round(liquidity * (price - sqrtLower), Q96);
|
|
5728
|
+
itm0 += leg.tokenType === 1n ? amm0 : 0n;
|
|
5729
|
+
itm1 += leg.tokenType === 0n ? amm1 : 0n;
|
|
5730
|
+
} else {
|
|
5731
|
+
itm0 -= leg.tokenType === 0n ? sign * moved0 : 0n;
|
|
5732
|
+
itm1 -= leg.tokenType === 1n ? sign * moved1 : 0n;
|
|
5733
|
+
}
|
|
5734
|
+
paid0 += amm0 - (leg.tokenType === 0n ? sign * moved0 : 0n);
|
|
5735
|
+
paid1 += amm1 - (leg.tokenType === 1n ? sign * moved1 : 0n);
|
|
5736
|
+
notional0 += leg.tokenType === 0n ? moved0 : 0n;
|
|
5737
|
+
notional1 += leg.tokenType === 1n ? moved1 : 0n;
|
|
5738
|
+
}
|
|
5739
|
+
if (swapAtMint && (itm0 !== 0n || itm1 !== 0n)) {
|
|
5740
|
+
const swapToken0 = itm0 !== 0n && (itm1 === 0n || firstLeg.asset === 0n);
|
|
5741
|
+
const priceSquared$1 = sqrtPriceX96 * sqrtPriceX96;
|
|
5742
|
+
const itm = swapToken0 ? itm0 : itm1;
|
|
5743
|
+
const numerator = swapToken0 ? priceSquared$1 : Q192;
|
|
5744
|
+
const denominator = swapToken0 ? Q192 : priceSquared$1;
|
|
5745
|
+
const retained$1 = (FEE_SCALE - swapFee) * (BPS - slippageBps);
|
|
5746
|
+
const scale$1 = FEE_SCALE * BPS;
|
|
5747
|
+
const payment = itm > 0n ? ceilDiv$1(itm * numerator * scale$1, denominator * retained$1) : itm * numerator * retained$1 / (denominator * scale$1);
|
|
5748
|
+
paid0 += swapToken0 ? -itm : payment;
|
|
5749
|
+
paid1 += swapToken0 ? payment : -itm;
|
|
5750
|
+
}
|
|
5751
|
+
paid0 += ceilDiv$1(notional0 * commissionRate, BPS);
|
|
5752
|
+
paid1 += ceilDiv$1(notional1 * commissionRate, BPS);
|
|
5753
|
+
const priceSquared = valuationSqrtPriceX96 * valuationSqrtPriceX96;
|
|
5754
|
+
const inToken0 = (amount0, amount1) => amount0 + ceilDiv$1(amount1 * Q192, priceSquared);
|
|
5755
|
+
const inToken1 = (amount0, amount1) => amount1 + ceilDiv$1(amount0 * priceSquared, Q192);
|
|
5756
|
+
const retained = (FEE_SCALE - swapFee) * (BPS - slippageBps);
|
|
5757
|
+
const scale = FEE_SCALE * BPS;
|
|
5758
|
+
const spotSquared = sqrtPriceX96 * sqrtPriceX96;
|
|
5759
|
+
const upfront0 = max(paid0, 0n) + ceilDiv$1(max(paid1, 0n) * Q192 * scale, spotSquared * retained);
|
|
5760
|
+
const upfront1 = max(paid1, 0n) + ceilDiv$1(max(paid0, 0n) * spotSquared * scale, Q192 * retained);
|
|
5761
|
+
const requiredValue0 = upfront0 + max(0n, inToken0(required0 - max(-paid0, 0n), required1 - max(-paid1, 0n)));
|
|
5762
|
+
const requiredValue1 = upfront1 + max(0n, inToken1(required0 - max(-paid0, 0n), required1 - max(-paid1, 0n)));
|
|
5763
|
+
return {
|
|
5764
|
+
paid0,
|
|
5765
|
+
paid1,
|
|
5766
|
+
requiredValue0,
|
|
5767
|
+
requiredValue1
|
|
5768
|
+
};
|
|
5769
|
+
}
|
|
5770
|
+
|
|
5685
5771
|
//#endregion
|
|
5686
5772
|
//#region src/panoptic/v2/sync/getSyncStatus.ts
|
|
5687
5773
|
/**
|
|
@@ -6503,6 +6589,108 @@ async function simulateClosePosition(params) {
|
|
|
6503
6589
|
}
|
|
6504
6590
|
}
|
|
6505
6591
|
|
|
6592
|
+
//#endregion
|
|
6593
|
+
//#region src/panoptic/v2/simulations/simulateClosePremiumProtection.ts
|
|
6594
|
+
/** Estimate unfunded short premium after buyer settlement and collection of chunk fees. */
|
|
6595
|
+
async function simulateClosePremiumProtection(params) {
|
|
6596
|
+
const { client, poolAddress, account, positionIdList, closingTokenIds, targets } = params;
|
|
6597
|
+
let metaPromise;
|
|
6598
|
+
try {
|
|
6599
|
+
const blockNumber = params.blockNumber ?? await client.getBlockNumber();
|
|
6600
|
+
metaPromise = getBlockMeta({
|
|
6601
|
+
client,
|
|
6602
|
+
blockNumber
|
|
6603
|
+
});
|
|
6604
|
+
metaPromise.catch(() => {});
|
|
6605
|
+
if (closingTokenIds.length === 0 || closingTokenIds.some((id) => !positionIdList.includes(id))) throw new PanopticError("Premium protection requires currently held positions to close");
|
|
6606
|
+
const positionSizes = await getCurrentPositionSizes({
|
|
6607
|
+
client,
|
|
6608
|
+
poolAddress,
|
|
6609
|
+
account,
|
|
6610
|
+
positionIdList: closingTokenIds,
|
|
6611
|
+
blockNumber
|
|
6612
|
+
});
|
|
6613
|
+
const { collectionDispatch } = buildProtectedSettlePlan({
|
|
6614
|
+
positionIdList: closingTokenIds,
|
|
6615
|
+
finalPositionIdList: positionIdList,
|
|
6616
|
+
positionSizes,
|
|
6617
|
+
builderCode: params.builderCode
|
|
6618
|
+
});
|
|
6619
|
+
const calls = (targets.length ? buildSettleSequenceCalls({
|
|
6620
|
+
positionIdListFrom: params.signerPositionIdList,
|
|
6621
|
+
targets
|
|
6622
|
+
}) : []).map((data) => ({
|
|
6623
|
+
to: poolAddress,
|
|
6624
|
+
data,
|
|
6625
|
+
account: params.signerAddress
|
|
6626
|
+
}));
|
|
6627
|
+
if (collectionDispatch !== void 0) {
|
|
6628
|
+
const [dispatchData] = buildSettleSequenceCalls({
|
|
6629
|
+
positionIdListFrom: positionIdList,
|
|
6630
|
+
targets: [],
|
|
6631
|
+
dispatch: collectionDispatch
|
|
6632
|
+
});
|
|
6633
|
+
if (dispatchData === void 0) throw new PanopticError("Premium protection collection dispatch is missing");
|
|
6634
|
+
calls.push({
|
|
6635
|
+
...params.buildCollectionCall(dispatchData),
|
|
6636
|
+
account: params.signerAddress
|
|
6637
|
+
});
|
|
6638
|
+
}
|
|
6639
|
+
for (const includePendingPremium of [true, false]) calls.push({
|
|
6640
|
+
to: poolAddress,
|
|
6641
|
+
account: params.signerAddress,
|
|
6642
|
+
data: encodeFunctionData({
|
|
6643
|
+
abi: panopticPoolV2Abi,
|
|
6644
|
+
functionName: "getFullPositionsData",
|
|
6645
|
+
args: [
|
|
6646
|
+
account,
|
|
6647
|
+
includePendingPremium,
|
|
6648
|
+
closingTokenIds
|
|
6649
|
+
]
|
|
6650
|
+
})
|
|
6651
|
+
});
|
|
6652
|
+
const blocks = await client.simulateBlocks({
|
|
6653
|
+
blocks: [{ calls }],
|
|
6654
|
+
blockNumber
|
|
6655
|
+
});
|
|
6656
|
+
const results = blocks[0]?.calls;
|
|
6657
|
+
if (results === void 0 || results.length !== calls.length) throw new PanopticError("Premium protection simulation returned incomplete results");
|
|
6658
|
+
for (const result$1 of results) if (result$1.status === "failure") throw result$1.error;
|
|
6659
|
+
const result = results.map((call$1) => call$1.data);
|
|
6660
|
+
const owedResult = result[result.length - 2];
|
|
6661
|
+
const availableResult = result[result.length - 1];
|
|
6662
|
+
if (owedResult === void 0 || availableResult === void 0) throw new PanopticError("Premium protection simulation returned incomplete results");
|
|
6663
|
+
const decodeShortPremium = (data) => decodeLeftRightUnsigned(decodeFunctionResult({
|
|
6664
|
+
abi: panopticPoolV2Abi,
|
|
6665
|
+
functionName: "getFullPositionsData",
|
|
6666
|
+
data
|
|
6667
|
+
})[0]);
|
|
6668
|
+
const owed = decodeShortPremium(owedResult);
|
|
6669
|
+
const available = decodeShortPremium(availableResult);
|
|
6670
|
+
return {
|
|
6671
|
+
success: true,
|
|
6672
|
+
gasEstimate: 0n,
|
|
6673
|
+
data: {
|
|
6674
|
+
owed0: owed.right,
|
|
6675
|
+
owed1: owed.left,
|
|
6676
|
+
available0: available.right,
|
|
6677
|
+
available1: available.left,
|
|
6678
|
+
forfeit0: owed.right > available.right ? owed.right - available.right : 0n,
|
|
6679
|
+
forfeit1: owed.left > available.left ? owed.left - available.left : 0n
|
|
6680
|
+
},
|
|
6681
|
+
_meta: await metaPromise
|
|
6682
|
+
};
|
|
6683
|
+
} catch (error) {
|
|
6684
|
+
const simulationError = error instanceof PanopticError ? error : new PanopticError(String(error));
|
|
6685
|
+
if (metaPromise === void 0) throw simulationError;
|
|
6686
|
+
return {
|
|
6687
|
+
success: false,
|
|
6688
|
+
error: simulationError,
|
|
6689
|
+
_meta: await metaPromise
|
|
6690
|
+
};
|
|
6691
|
+
}
|
|
6692
|
+
}
|
|
6693
|
+
|
|
6506
6694
|
//#endregion
|
|
6507
6695
|
//#region src/panoptic/v2/simulations/simulateForceExercise.ts
|
|
6508
6696
|
/**
|
|
@@ -7403,6 +7591,42 @@ async function quoteOneTokenFlow(params) {
|
|
|
7403
7591
|
};
|
|
7404
7592
|
}
|
|
7405
7593
|
|
|
7594
|
+
//#endregion
|
|
7595
|
+
//#region src/panoptic/v2/simulations/quoteTokenShortfallSwap.ts
|
|
7596
|
+
/** Quote the opposite pool token needed to buy the deficit in a NotEnoughTokens revert. */
|
|
7597
|
+
async function quoteTokenShortfallSwap({ client, chainId, poolAddress, error, slippageBps = 50n }) {
|
|
7598
|
+
const shortfall = getNotEnoughTokensError(error);
|
|
7599
|
+
if (shortfall === null || shortfall.deficit === 0n) return null;
|
|
7600
|
+
const metadata = await getPoolMetadata({
|
|
7601
|
+
client,
|
|
7602
|
+
poolAddress
|
|
7603
|
+
});
|
|
7604
|
+
const matches0 = [metadata.token0Asset, metadata.collateralToken0Address].some((address) => isAddressEqual(address, shortfall.tokenAddress));
|
|
7605
|
+
const matches1 = [metadata.token1Asset, metadata.collateralToken1Address].some((address) => isAddressEqual(address, shortfall.tokenAddress));
|
|
7606
|
+
if (matches0 === matches1) return null;
|
|
7607
|
+
const tokenIn = matches0 ? metadata.token1Asset : metadata.token0Asset;
|
|
7608
|
+
const quote = await (metadata.isV4 ? quoteSwapExactOutViaRouter : quoteSwapExactOutViaV3Router)({
|
|
7609
|
+
client,
|
|
7610
|
+
chainId,
|
|
7611
|
+
poolAddress,
|
|
7612
|
+
tokenIn,
|
|
7613
|
+
amountOut: shortfall.deficit,
|
|
7614
|
+
slippageBps
|
|
7615
|
+
});
|
|
7616
|
+
return {
|
|
7617
|
+
deficit: shortfall.deficit,
|
|
7618
|
+
outputSymbol: matches0 ? metadata.token0Symbol : metadata.token1Symbol,
|
|
7619
|
+
outputDecimals: matches0 ? metadata.token0Decimals : metadata.token1Decimals,
|
|
7620
|
+
inputSymbol: matches0 ? metadata.token1Symbol : metadata.token0Symbol,
|
|
7621
|
+
inputDecimals: matches0 ? metadata.token1Decimals : metadata.token0Decimals,
|
|
7622
|
+
tokenIn,
|
|
7623
|
+
slippageBps,
|
|
7624
|
+
poolFeePips: metadata.fee <= 1000000n ? metadata.fee : null,
|
|
7625
|
+
estimatedPoolFee: quote.success && metadata.fee <= 1000000n ? (quote.data.amountIn * metadata.fee + 999999n) / 1000000n : null,
|
|
7626
|
+
quote: quote.success ? quote.data : null
|
|
7627
|
+
};
|
|
7628
|
+
}
|
|
7629
|
+
|
|
7406
7630
|
//#endregion
|
|
7407
7631
|
//#region src/panoptic/v2/simulations/temporaryLoanRecovery.ts
|
|
7408
7632
|
const BPS_DENOMINATOR = 10000n;
|
|
@@ -8505,7 +8729,7 @@ const DEFAULT_INTERVAL_MS = 12000n;
|
|
|
8505
8729
|
/**
|
|
8506
8730
|
* Default maximum block range per poll.
|
|
8507
8731
|
*/
|
|
8508
|
-
const DEFAULT_MAX_BLOCK_RANGE = 1000n;
|
|
8732
|
+
const DEFAULT_MAX_BLOCK_RANGE$1 = 1000n;
|
|
8509
8733
|
/**
|
|
8510
8734
|
* Create an HTTP polling-based event fetcher.
|
|
8511
8735
|
*
|
|
@@ -8542,7 +8766,7 @@ const DEFAULT_MAX_BLOCK_RANGE = 1000n;
|
|
|
8542
8766
|
* ```
|
|
8543
8767
|
*/
|
|
8544
8768
|
function createEventPoller(params) {
|
|
8545
|
-
const { client, poolAddress, collateralTracker0, collateralTracker1, riskEngineAddress, sfpmAddress, poolManagerAddress, eventTypes, onLogs, onError, intervalMs = DEFAULT_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, fromBlock } = params;
|
|
8769
|
+
const { client, poolAddress, collateralTracker0, collateralTracker1, riskEngineAddress, sfpmAddress, poolManagerAddress, eventTypes, onLogs, onError, intervalMs = DEFAULT_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE$1, fromBlock } = params;
|
|
8546
8770
|
let isRunning = false;
|
|
8547
8771
|
let lastPolledBlock = fromBlock ?? 0n;
|
|
8548
8772
|
let pollTimeout = null;
|
|
@@ -8730,6 +8954,431 @@ function createEventPoller(params) {
|
|
|
8730
8954
|
};
|
|
8731
8955
|
}
|
|
8732
8956
|
|
|
8957
|
+
//#endregion
|
|
8958
|
+
//#region src/panoptic/v2/events/poolSwapStream.ts
|
|
8959
|
+
const DEFAULT_POLL_INTERVAL_MS$1 = 3e3;
|
|
8960
|
+
const FAILURE_WINDOW_MS = 3e4;
|
|
8961
|
+
const FAILURES_BEFORE_POLL = 3;
|
|
8962
|
+
const STREAM_RETRY_MIN_MS = 15e3;
|
|
8963
|
+
const STREAM_RETRY_MAX_MS = 3e5;
|
|
8964
|
+
const RESYNC_JITTER_MS = 2e3;
|
|
8965
|
+
const EVENT_SOURCE_CLOSED = 2;
|
|
8966
|
+
function parseRecord(data) {
|
|
8967
|
+
const value = JSON.parse(data);
|
|
8968
|
+
if (typeof value !== "object" || value === null) throw new Error("Malformed stream frame");
|
|
8969
|
+
return value;
|
|
8970
|
+
}
|
|
8971
|
+
function bigintField(record, field) {
|
|
8972
|
+
const value = record[field];
|
|
8973
|
+
if (typeof value !== "string") throw new Error(`Stream frame is missing ${field}`);
|
|
8974
|
+
return BigInt(value);
|
|
8975
|
+
}
|
|
8976
|
+
function numberField(record, field) {
|
|
8977
|
+
const value = record[field];
|
|
8978
|
+
if (typeof value !== "number") throw new Error(`Stream frame is missing ${field}`);
|
|
8979
|
+
return value;
|
|
8980
|
+
}
|
|
8981
|
+
function parseStreamedKey(data) {
|
|
8982
|
+
const record = parseRecord(data);
|
|
8983
|
+
return {
|
|
8984
|
+
blockNumber: bigintField(record, "blockNumber"),
|
|
8985
|
+
logIndex: numberField(record, "logIndex")
|
|
8986
|
+
};
|
|
8987
|
+
}
|
|
8988
|
+
function parseStreamedSwap(data) {
|
|
8989
|
+
const record = parseRecord(data);
|
|
8990
|
+
const transactionHash = record.transactionHash;
|
|
8991
|
+
if (typeof transactionHash !== "string") throw new Error("Stream frame is missing transactionHash");
|
|
8992
|
+
return {
|
|
8993
|
+
...parseStreamedKey(data),
|
|
8994
|
+
timestamp: bigintField(record, "timestamp"),
|
|
8995
|
+
transactionHash,
|
|
8996
|
+
tick: numberField(record, "tick"),
|
|
8997
|
+
amount0: bigintField(record, "amount0"),
|
|
8998
|
+
amount1: bigintField(record, "amount1"),
|
|
8999
|
+
sqrtPriceX96: bigintField(record, "sqrtPriceX96"),
|
|
9000
|
+
liquidity: bigintField(record, "liquidity")
|
|
9001
|
+
};
|
|
9002
|
+
}
|
|
9003
|
+
function parseHead(data) {
|
|
9004
|
+
return bigintField(parseRecord(data ?? ""), "head");
|
|
9005
|
+
}
|
|
9006
|
+
function defaultEventSource() {
|
|
9007
|
+
const EventSourceCtor = globalThis.EventSource;
|
|
9008
|
+
return EventSourceCtor && ((url) => new EventSourceCtor(url));
|
|
9009
|
+
}
|
|
9010
|
+
function toError$1(error) {
|
|
9011
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
9012
|
+
}
|
|
9013
|
+
/**
|
|
9014
|
+
* Stream a pool's swaps from the relay at `streamUrl`.
|
|
9015
|
+
*
|
|
9016
|
+
* Every `ready`/`resync` frame carries the relay's head; swaps from the cursor up
|
|
9017
|
+
* to that head are fetched over HTTP so nothing is lost across reconnects. A
|
|
9018
|
+
* stream that closes, or errors three times in 30 s, is replaced by HTTP polling
|
|
9019
|
+
* and retried with backoff; one that closes before ever opening is not retried.
|
|
9020
|
+
*/
|
|
9021
|
+
function streamPoolSwaps(params) {
|
|
9022
|
+
const { client, pool, fromBlock, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS$1, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, streamUrl, onSwaps, onError, onRemoved, onTransport, eventSource = defaultEventSource() } = params;
|
|
9023
|
+
let running = true;
|
|
9024
|
+
let cursor = fromBlock === void 0 ? void 0 : fromBlock - 1n;
|
|
9025
|
+
let transport = "off";
|
|
9026
|
+
let failures = [];
|
|
9027
|
+
let source;
|
|
9028
|
+
let poller;
|
|
9029
|
+
let retryTimer;
|
|
9030
|
+
let retryDelayMs = STREAM_RETRY_MIN_MS;
|
|
9031
|
+
let catchUpTimer;
|
|
9032
|
+
let catchUpTarget;
|
|
9033
|
+
let catchingUp = false;
|
|
9034
|
+
let everOpened = false;
|
|
9035
|
+
const setTransport = (next) => {
|
|
9036
|
+
if (next === transport) return;
|
|
9037
|
+
transport = next;
|
|
9038
|
+
onTransport?.(next);
|
|
9039
|
+
};
|
|
9040
|
+
const advance = (block) => {
|
|
9041
|
+
if (block !== void 0 && (cursor === void 0 || block > cursor)) cursor = block;
|
|
9042
|
+
};
|
|
9043
|
+
const report = (error) => {
|
|
9044
|
+
if (running) onError?.(toError$1(error));
|
|
9045
|
+
};
|
|
9046
|
+
const catchUpPending = () => catchingUp || catchUpTarget !== void 0;
|
|
9047
|
+
const runCatchUp = async () => {
|
|
9048
|
+
catchingUp = true;
|
|
9049
|
+
while (running && catchUpTarget !== void 0) {
|
|
9050
|
+
const head = catchUpTarget;
|
|
9051
|
+
catchUpTarget = void 0;
|
|
9052
|
+
if (cursor === void 0) {
|
|
9053
|
+
cursor = head;
|
|
9054
|
+
continue;
|
|
9055
|
+
}
|
|
9056
|
+
try {
|
|
9057
|
+
const { swaps } = await fetchPoolSwaps(client, pool, cursor + 1n, head, maxBlockRange);
|
|
9058
|
+
if (!running) break;
|
|
9059
|
+
const first = swaps[0];
|
|
9060
|
+
const last = swaps[swaps.length - 1];
|
|
9061
|
+
if (first && last) onSwaps(swaps, {
|
|
9062
|
+
fromBlock: first.blockNumber,
|
|
9063
|
+
toBlock: last.blockNumber
|
|
9064
|
+
});
|
|
9065
|
+
advance(head);
|
|
9066
|
+
} catch (error) {
|
|
9067
|
+
report(error);
|
|
9068
|
+
if (catchUpTarget === void 0 || catchUpTarget < head) catchUpTarget = head;
|
|
9069
|
+
catchingUp = false;
|
|
9070
|
+
catchUpTimer = setTimeout(() => void runCatchUp(), pollIntervalMs);
|
|
9071
|
+
return;
|
|
9072
|
+
}
|
|
9073
|
+
}
|
|
9074
|
+
catchingUp = false;
|
|
9075
|
+
};
|
|
9076
|
+
const catchUp = (head, delayMs = 0) => {
|
|
9077
|
+
if (catchUpTarget === void 0 || head > catchUpTarget) catchUpTarget = head;
|
|
9078
|
+
if (catchingUp) return;
|
|
9079
|
+
if (catchUpTimer !== void 0) clearTimeout(catchUpTimer);
|
|
9080
|
+
catchUpTimer = setTimeout(() => {
|
|
9081
|
+
catchUpTimer = void 0;
|
|
9082
|
+
runCatchUp();
|
|
9083
|
+
}, delayMs);
|
|
9084
|
+
};
|
|
9085
|
+
const startPolling = () => {
|
|
9086
|
+
if (poller) return;
|
|
9087
|
+
poller = watchPoolSwaps({
|
|
9088
|
+
client,
|
|
9089
|
+
pool,
|
|
9090
|
+
fromBlock: cursor === void 0 ? void 0 : cursor + 1n,
|
|
9091
|
+
pollIntervalMs,
|
|
9092
|
+
maxBlockRange,
|
|
9093
|
+
onSwaps,
|
|
9094
|
+
onError
|
|
9095
|
+
});
|
|
9096
|
+
setTransport("poll");
|
|
9097
|
+
};
|
|
9098
|
+
const stopPolling = () => {
|
|
9099
|
+
if (!poller) return;
|
|
9100
|
+
advance(poller.lastScannedBlock());
|
|
9101
|
+
poller.stop();
|
|
9102
|
+
poller = void 0;
|
|
9103
|
+
};
|
|
9104
|
+
const closeStream = () => {
|
|
9105
|
+
source?.close();
|
|
9106
|
+
source = void 0;
|
|
9107
|
+
};
|
|
9108
|
+
const scheduleStreamRetry = () => {
|
|
9109
|
+
retryTimer = setTimeout(() => {
|
|
9110
|
+
retryTimer = void 0;
|
|
9111
|
+
if (running) openStream();
|
|
9112
|
+
}, retryDelayMs);
|
|
9113
|
+
retryDelayMs = Math.min(retryDelayMs * 2, STREAM_RETRY_MAX_MS);
|
|
9114
|
+
};
|
|
9115
|
+
const openStream = () => {
|
|
9116
|
+
if (!eventSource) {
|
|
9117
|
+
startPolling();
|
|
9118
|
+
return;
|
|
9119
|
+
}
|
|
9120
|
+
const es = eventSource(streamUrl);
|
|
9121
|
+
source = es;
|
|
9122
|
+
failures = [];
|
|
9123
|
+
let opened = false;
|
|
9124
|
+
const listen = (type, handle) => es.addEventListener(type, (event) => {
|
|
9125
|
+
if (!running || source !== es) return;
|
|
9126
|
+
try {
|
|
9127
|
+
handle(event.data);
|
|
9128
|
+
} catch (error) {
|
|
9129
|
+
report(error);
|
|
9130
|
+
}
|
|
9131
|
+
});
|
|
9132
|
+
listen("open", () => {
|
|
9133
|
+
opened = true;
|
|
9134
|
+
everOpened = true;
|
|
9135
|
+
failures = [];
|
|
9136
|
+
retryDelayMs = STREAM_RETRY_MIN_MS;
|
|
9137
|
+
});
|
|
9138
|
+
listen("ready", (data) => {
|
|
9139
|
+
const head = parseHead(data);
|
|
9140
|
+
stopPolling();
|
|
9141
|
+
setTransport("stream");
|
|
9142
|
+
catchUp(head);
|
|
9143
|
+
});
|
|
9144
|
+
listen("resync", (data) => {
|
|
9145
|
+
catchUp(parseHead(data), Math.random() * RESYNC_JITTER_MS);
|
|
9146
|
+
});
|
|
9147
|
+
listen("swap", (data) => {
|
|
9148
|
+
const swap = parseStreamedSwap(data ?? "");
|
|
9149
|
+
onSwaps([swap], {
|
|
9150
|
+
fromBlock: swap.blockNumber,
|
|
9151
|
+
toBlock: swap.blockNumber
|
|
9152
|
+
});
|
|
9153
|
+
if (!catchUpPending()) advance(swap.blockNumber);
|
|
9154
|
+
});
|
|
9155
|
+
listen("removed", (data) => {
|
|
9156
|
+
onRemoved?.(parseStreamedKey(data ?? ""));
|
|
9157
|
+
});
|
|
9158
|
+
listen("error", () => {
|
|
9159
|
+
const now = Date.now();
|
|
9160
|
+
failures = failures.filter((at) => now - at < FAILURE_WINDOW_MS);
|
|
9161
|
+
failures.push(now);
|
|
9162
|
+
const closed = es.readyState === EVENT_SOURCE_CLOSED;
|
|
9163
|
+
if (!closed && failures.length < FAILURES_BEFORE_POLL) return;
|
|
9164
|
+
closeStream();
|
|
9165
|
+
startPolling();
|
|
9166
|
+
if (closed && !opened && !everOpened) return;
|
|
9167
|
+
scheduleStreamRetry();
|
|
9168
|
+
});
|
|
9169
|
+
};
|
|
9170
|
+
openStream();
|
|
9171
|
+
return {
|
|
9172
|
+
stop() {
|
|
9173
|
+
running = false;
|
|
9174
|
+
closeStream();
|
|
9175
|
+
stopPolling();
|
|
9176
|
+
if (retryTimer !== void 0) clearTimeout(retryTimer);
|
|
9177
|
+
if (catchUpTimer !== void 0) clearTimeout(catchUpTimer);
|
|
9178
|
+
setTransport("off");
|
|
9179
|
+
},
|
|
9180
|
+
lastScannedBlock: () => cursor,
|
|
9181
|
+
transport: () => transport
|
|
9182
|
+
};
|
|
9183
|
+
}
|
|
9184
|
+
|
|
9185
|
+
//#endregion
|
|
9186
|
+
//#region src/panoptic/v2/events/poolSwaps.ts
|
|
9187
|
+
const DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
9188
|
+
const DEFAULT_MAX_BLOCK_RANGE = 2000n;
|
|
9189
|
+
const SHARED_BUFFER_LIMIT = 4096;
|
|
9190
|
+
/**
|
|
9191
|
+
* Parse a decoded v3 `UniswapV3Pool.Swap` or v4 `PoolManager.Swap` log.
|
|
9192
|
+
*/
|
|
9193
|
+
function parseSwapLog(log, timestamp) {
|
|
9194
|
+
if (log.blockNumber === null || log.logIndex === null || log.transactionHash === null) throw new Error("Cannot parse a pending Swap log");
|
|
9195
|
+
const args = log.args;
|
|
9196
|
+
return {
|
|
9197
|
+
blockNumber: log.blockNumber,
|
|
9198
|
+
logIndex: log.logIndex,
|
|
9199
|
+
timestamp,
|
|
9200
|
+
transactionHash: log.transactionHash,
|
|
9201
|
+
tick: Number(args.tick),
|
|
9202
|
+
amount0: args.amount0,
|
|
9203
|
+
amount1: args.amount1,
|
|
9204
|
+
sqrtPriceX96: args.sqrtPriceX96,
|
|
9205
|
+
liquidity: args.liquidity
|
|
9206
|
+
};
|
|
9207
|
+
}
|
|
9208
|
+
function toError(error) {
|
|
9209
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
9210
|
+
}
|
|
9211
|
+
async function fetchSwapLogs(client, pool, fromBlock, toBlock) {
|
|
9212
|
+
if (pool.version === "v3") return client.getContractEvents({
|
|
9213
|
+
address: pool.poolAddress,
|
|
9214
|
+
abi: UniswapV3PoolAbi,
|
|
9215
|
+
eventName: "Swap",
|
|
9216
|
+
fromBlock,
|
|
9217
|
+
toBlock
|
|
9218
|
+
});
|
|
9219
|
+
return client.getContractEvents({
|
|
9220
|
+
address: pool.poolManager,
|
|
9221
|
+
abi: poolManagerAbi,
|
|
9222
|
+
eventName: "Swap",
|
|
9223
|
+
args: { id: pool.poolId },
|
|
9224
|
+
fromBlock,
|
|
9225
|
+
toBlock
|
|
9226
|
+
});
|
|
9227
|
+
}
|
|
9228
|
+
async function fetchSwaps(client, pool, fromBlock, toBlock) {
|
|
9229
|
+
const logs = await fetchSwapLogs(client, pool, fromBlock, toBlock);
|
|
9230
|
+
if (logs.length === 0) return [];
|
|
9231
|
+
const blockNumbers = [...new Set(logs.flatMap((log) => log.blockNumber === null ? [] : [log.blockNumber]))];
|
|
9232
|
+
const blocks = await Promise.all(blockNumbers.map((blockNumber) => client.getBlock({ blockNumber })));
|
|
9233
|
+
const timestamps = new Map(blocks.map((block, i) => [blockNumbers[i], block.timestamp]));
|
|
9234
|
+
return logs.map((log) => parseSwapLog(log, timestamps.get(log.blockNumber ?? -1n) ?? 0n)).sort((a, b) => a.blockNumber === b.blockNumber ? a.logIndex - b.logIndex : a.blockNumber < b.blockNumber ? -1 : 1);
|
|
9235
|
+
}
|
|
9236
|
+
/**
|
|
9237
|
+
* Fetch a pool's swaps in `[fromBlock, toBlock]` (default: the current head), in
|
|
9238
|
+
* chain order. Returns no swaps when `fromBlock > toBlock`.
|
|
9239
|
+
*/
|
|
9240
|
+
async function fetchPoolSwaps(client, pool, fromBlock, toBlock, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE) {
|
|
9241
|
+
const end = toBlock ?? await client.getBlockNumber();
|
|
9242
|
+
const swaps = [];
|
|
9243
|
+
for (let from = fromBlock; from <= end; from += maxBlockRange) {
|
|
9244
|
+
const to = from + maxBlockRange - 1n < end ? from + maxBlockRange - 1n : end;
|
|
9245
|
+
swaps.push(...await fetchSwaps(client, pool, from, to));
|
|
9246
|
+
}
|
|
9247
|
+
return {
|
|
9248
|
+
swaps,
|
|
9249
|
+
toBlock: end
|
|
9250
|
+
};
|
|
9251
|
+
}
|
|
9252
|
+
/**
|
|
9253
|
+
* Poll a single pool's `Swap` logs with `eth_getLogs`, timestamped by block.
|
|
9254
|
+
*
|
|
9255
|
+
* Works over plain HTTP (no filters or websockets). A chunk that fails is retried on
|
|
9256
|
+
* the next tick; errors never stop the loop.
|
|
9257
|
+
*/
|
|
9258
|
+
function watchPoolSwaps(params) {
|
|
9259
|
+
const { client, pool, fromBlock, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, onSwaps, onError } = params;
|
|
9260
|
+
let running = true;
|
|
9261
|
+
let lastScanned;
|
|
9262
|
+
let timer;
|
|
9263
|
+
const poll = async () => {
|
|
9264
|
+
try {
|
|
9265
|
+
const head = await client.getBlockNumber();
|
|
9266
|
+
let from = lastScanned !== void 0 ? lastScanned + 1n : fromBlock ?? head;
|
|
9267
|
+
while (running && from <= head) {
|
|
9268
|
+
const to = from + maxBlockRange - 1n < head ? from + maxBlockRange - 1n : head;
|
|
9269
|
+
const swaps = await fetchSwaps(client, pool, from, to);
|
|
9270
|
+
if (!running) return;
|
|
9271
|
+
if (swaps.length > 0) onSwaps(swaps, {
|
|
9272
|
+
fromBlock: from,
|
|
9273
|
+
toBlock: to
|
|
9274
|
+
});
|
|
9275
|
+
lastScanned = to;
|
|
9276
|
+
from = to + 1n;
|
|
9277
|
+
}
|
|
9278
|
+
} catch (error) {
|
|
9279
|
+
if (running) onError?.(toError(error));
|
|
9280
|
+
}
|
|
9281
|
+
if (running) timer = setTimeout(() => void poll(), pollIntervalMs);
|
|
9282
|
+
};
|
|
9283
|
+
poll();
|
|
9284
|
+
return {
|
|
9285
|
+
stop() {
|
|
9286
|
+
running = false;
|
|
9287
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
9288
|
+
},
|
|
9289
|
+
lastScannedBlock: () => lastScanned
|
|
9290
|
+
};
|
|
9291
|
+
}
|
|
9292
|
+
const sharedWatchers = new Map();
|
|
9293
|
+
function swapKey(key) {
|
|
9294
|
+
return `${key.blockNumber}:${key.logIndex}`;
|
|
9295
|
+
}
|
|
9296
|
+
/**
|
|
9297
|
+
* Ref-counted pool swap feed: subscribers with the same `key` share one watcher
|
|
9298
|
+
* (relay stream when `streamUrl` is set, else HTTP polling), duplicates are
|
|
9299
|
+
* dropped, late subscribers first receive the swaps already seen, and the watcher
|
|
9300
|
+
* stops when the last subscriber unsubscribes.
|
|
9301
|
+
*/
|
|
9302
|
+
function subscribePoolSwaps(params) {
|
|
9303
|
+
const { key, streamUrl, onSwaps, onError, onRemoved, onTransport,...watchParams } = params;
|
|
9304
|
+
const listener = {
|
|
9305
|
+
onSwaps,
|
|
9306
|
+
onError,
|
|
9307
|
+
onRemoved,
|
|
9308
|
+
onTransport
|
|
9309
|
+
};
|
|
9310
|
+
const existing = sharedWatchers.get(key);
|
|
9311
|
+
if (existing) {
|
|
9312
|
+
existing.listeners.add(listener);
|
|
9313
|
+
const buffered = [...existing.buffer.values()];
|
|
9314
|
+
const first = buffered[0];
|
|
9315
|
+
const last = buffered[buffered.length - 1];
|
|
9316
|
+
if (first && last) onSwaps(buffered, {
|
|
9317
|
+
fromBlock: first.blockNumber,
|
|
9318
|
+
toBlock: last.blockNumber
|
|
9319
|
+
});
|
|
9320
|
+
onTransport?.(existing.transport);
|
|
9321
|
+
} else {
|
|
9322
|
+
const listeners = new Set([listener]);
|
|
9323
|
+
const buffer = new Map();
|
|
9324
|
+
const entry = {
|
|
9325
|
+
watcher: {
|
|
9326
|
+
stop: () => void 0,
|
|
9327
|
+
lastScannedBlock: () => void 0
|
|
9328
|
+
},
|
|
9329
|
+
listeners,
|
|
9330
|
+
buffer,
|
|
9331
|
+
transport: "off"
|
|
9332
|
+
};
|
|
9333
|
+
const setTransport = (transport) => {
|
|
9334
|
+
entry.transport = transport;
|
|
9335
|
+
for (const l of listeners) l.onTransport?.(transport);
|
|
9336
|
+
};
|
|
9337
|
+
const callbacks = {
|
|
9338
|
+
onSwaps: (swaps, range) => {
|
|
9339
|
+
const fresh = swaps.filter((swap) => !buffer.has(swapKey(swap)));
|
|
9340
|
+
if (fresh.length === 0) return;
|
|
9341
|
+
for (const swap of fresh) buffer.set(swapKey(swap), swap);
|
|
9342
|
+
for (const k of buffer.keys()) {
|
|
9343
|
+
if (buffer.size <= SHARED_BUFFER_LIMIT) break;
|
|
9344
|
+
buffer.delete(k);
|
|
9345
|
+
}
|
|
9346
|
+
for (const l of listeners) l.onSwaps(fresh, range);
|
|
9347
|
+
},
|
|
9348
|
+
onError: (error) => {
|
|
9349
|
+
for (const l of listeners) l.onError?.(error);
|
|
9350
|
+
}
|
|
9351
|
+
};
|
|
9352
|
+
sharedWatchers.set(key, entry);
|
|
9353
|
+
if (streamUrl !== void 0) entry.watcher = streamPoolSwaps({
|
|
9354
|
+
...watchParams,
|
|
9355
|
+
...callbacks,
|
|
9356
|
+
streamUrl,
|
|
9357
|
+
onRemoved: (removed) => {
|
|
9358
|
+
buffer.delete(swapKey(removed));
|
|
9359
|
+
for (const l of listeners) l.onRemoved?.(removed);
|
|
9360
|
+
},
|
|
9361
|
+
onTransport: setTransport
|
|
9362
|
+
});
|
|
9363
|
+
else {
|
|
9364
|
+
entry.watcher = watchPoolSwaps({
|
|
9365
|
+
...watchParams,
|
|
9366
|
+
...callbacks
|
|
9367
|
+
});
|
|
9368
|
+
setTransport("poll");
|
|
9369
|
+
}
|
|
9370
|
+
}
|
|
9371
|
+
return () => {
|
|
9372
|
+
const entry = sharedWatchers.get(key);
|
|
9373
|
+
if (!entry) return;
|
|
9374
|
+
entry.listeners.delete(listener);
|
|
9375
|
+
if (entry.listeners.size === 0) {
|
|
9376
|
+
entry.watcher.stop();
|
|
9377
|
+
sharedWatchers.delete(key);
|
|
9378
|
+
}
|
|
9379
|
+
};
|
|
9380
|
+
}
|
|
9381
|
+
|
|
8733
9382
|
//#endregion
|
|
8734
9383
|
//#region src/panoptic/v2/strike/ladder.ts
|
|
8735
9384
|
/** Target number of rungs across a leg's full range (lower tick → upper tick). */
|
|
@@ -10093,4 +10742,4 @@ async function getPositionVolatilityHistory({ client, poolAddress, account, toke
|
|
|
10093
10742
|
}
|
|
10094
10743
|
|
|
10095
10744
|
//#endregion
|
|
10096
|
-
export { DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, MARKET_INDICATOR_PERIODS, REQUIRED_BASE_ERROR_SENTINEL, STRIKE_LADDER_TARGET_STRIKES, VARIANCE_RATIO_LAG, addPendingPosition, addTrackedChunks, apportion, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, buildCreditWrappedDispatch, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, calculateAccountGreeksPure, calculateMarketIndicator, calculateSpreadWad, calculateVarianceProfile, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearPendingPositions, clearTrackedChunks, clearTradeHistory, collateralCurveTicks, collateralRuleKindFor, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, createEventPoller, createEventSubscription, createFlowNeutralTokenId, decodePanopticTokenURI, emptyLiquidateParams, encodePoolKeyBytes, encodeV3PoolKeyBytes, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, failPendingPosition, feeGrowthInsideX128, fetchSfpmV3PoolId, fetchUniswapFeeData, getAccountBuyingPower, getAccountGreeks, getAccountHistory, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getCollateralCurve, getCollateralCurveInputs, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getGuardianUnlockState, getHedgeLimits, getItmAmounts, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNotEnoughTokensError, getOpenPositionPreview, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPoolCollateralAddresses, getPoolLiquidities, getPortfolioValue, getPositionChunkData, getPositionEnrichmentData, getPositionValueCurve, getPositionVolatilityHistory, getRealizedPnL, getRequiredCreditForITM, getSafeMode, getStreamiaHistory, getSyncStatus, getTrackedChunks, getTradeHistory, getUniswapFeeHistory, getUniswapV3PoolFromId, getUniswapV3PoolInfo, getUniswapV3PoolLiquidities, getUniswapV4PoolBasicState, getUniswapV4PoolInfo, getUniswapV4PoolKeyFromId, getUniswapV4PoolLiquidities, interpolateBlocks, isGasError, isNonceError, isRetryableRpcError, isolateGroupTokenId, ladderStrikeSequence, logReturns, marketPnlInQuote, marketRiskFromValues, marketScenario, minePoolAddress, minePoolAddressLocalAsync, multicallRead, netLiquidationValueInQuote, optimizeTokenIdRiskPartners, parseCollateralLog, parsePoolLog, positionValueKey, positionValueTicks, prepareIndicatorCandles, preparePositionValueCurve, previewDeposit, previewMint, previewRedeem, previewWithdraw, quoteLiquidation, quoteOneTokenFlow, quoteSfpmSwap, quoteTemporaryLoanRecovery, quoteTokenShortfallRecovery, realizedBeta, removeTrackedChunks, resolveBlockNumbers, resolveLadderStrike, resolvePanopticPoolFromPoolId, resolveUniswapV4PoolKey, saveClosedPosition, scaleCollateralRequired, scanChunks, screenAccountExact, simulateBatchDispatch, simulateClosePosition, simulateDeployNewPool, simulateDeposit, simulateForceExercise, simulateLiquidate, simulateSFPMBurn, simulateSFPMMint, simulateSwapExactIn, simulateSwapExactOut, simulateWithdraw, slippageBpsToTickDistance, watchEvents };
|
|
10745
|
+
export { DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, MARKET_INDICATOR_PERIODS, REQUIRED_BASE_ERROR_SENTINEL, STRIKE_LADDER_TARGET_STRIKES, VARIANCE_RATIO_LAG, addPendingPosition, addTrackedChunks, apportion, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, buildCreditWrappedDispatch, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, calculateAccountGreeksPure, calculateMarketIndicator, calculateSpreadWad, calculateVarianceProfile, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearPendingPositions, clearTrackedChunks, clearTradeHistory, collateralCurveTicks, collateralRuleKindFor, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, createEventPoller, createEventSubscription, createFlowNeutralTokenId, decodePanopticTokenURI, emptyLiquidateParams, encodePoolKeyBytes, encodeV3PoolKeyBytes, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, failPendingPosition, feeGrowthInsideX128, fetchPoolSwaps, fetchSfpmV3PoolId, fetchUniswapFeeData, getAccountBuyingPower, getAccountGreeks, getAccountHistory, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getCollateralCurve, getCollateralCurveInputs, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getGuardianUnlockState, getHedgeLimits, getItmAmounts, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNotEnoughTokensError, getOpenPositionPreview, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPoolCollateralAddresses, getPoolLiquidities, getPortfolioValue, getPositionChunkData, getPositionEnrichmentData, getPositionMintFunding, getPositionValueCurve, getPositionVolatilityHistory, getRealizedPnL, getRequiredCreditForITM, getSafeMode, getStreamiaHistory, getSyncStatus, getTrackedChunks, getTradeHistory, getUniswapFeeHistory, getUniswapV3PoolFromId, getUniswapV3PoolInfo, getUniswapV3PoolLiquidities, getUniswapV4PoolBasicState, getUniswapV4PoolInfo, getUniswapV4PoolKeyFromId, getUniswapV4PoolLiquidities, interpolateBlocks, isGasError, isNonceError, isRetryableRpcError, isolateGroupTokenId, ladderStrikeSequence, logReturns, marketPnlInQuote, marketRiskFromValues, marketScenario, minePoolAddress, minePoolAddressLocalAsync, multicallRead, netLiquidationValueInQuote, optimizeTokenIdRiskPartners, parseCollateralLog, parsePoolLog, parseStreamedKey, parseStreamedSwap, parseSwapLog, positionValueKey, positionValueTicks, prepareIndicatorCandles, preparePositionValueCurve, previewDeposit, previewMint, previewRedeem, previewWithdraw, quoteLiquidation, quoteOneTokenFlow, quoteSfpmSwap, quoteTemporaryLoanRecovery, quoteTokenShortfallRecovery, quoteTokenShortfallSwap, realizedBeta, removeTrackedChunks, resolveBlockNumbers, resolveLadderStrike, resolvePanopticPoolFromPoolId, resolveUniswapV4PoolKey, saveClosedPosition, scaleCollateralRequired, scanChunks, screenAccountExact, simulateBatchDispatch, simulateClosePosition, simulateClosePremiumProtection, simulateDeployNewPool, simulateDeposit, simulateForceExercise, simulateLiquidate, simulateSFPMBurn, simulateSFPMMint, simulateSwapExactIn, simulateSwapExactOut, simulateWithdraw, slippageBpsToTickDistance, streamPoolSwaps, subscribePoolSwaps, watchEvents, watchPoolSwaps };
|