@exponent-labs/market-three-math 0.1.8

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +197 -0
  3. package/build/addLiquidity.d.ts +67 -0
  4. package/build/addLiquidity.js +269 -0
  5. package/build/addLiquidity.js.map +1 -0
  6. package/build/bisect.d.ts +1 -0
  7. package/build/bisect.js +62 -0
  8. package/build/bisect.js.map +1 -0
  9. package/build/index.d.ts +24 -0
  10. package/build/index.js +76 -0
  11. package/build/index.js.map +1 -0
  12. package/build/liquidityHistogram.d.ts +50 -0
  13. package/build/liquidityHistogram.js +162 -0
  14. package/build/liquidityHistogram.js.map +1 -0
  15. package/build/quote.d.ts +18 -0
  16. package/build/quote.js +106 -0
  17. package/build/quote.js.map +1 -0
  18. package/build/swap-v2.d.ts +20 -0
  19. package/build/swap-v2.js +261 -0
  20. package/build/swap-v2.js.map +1 -0
  21. package/build/swap.d.ts +15 -0
  22. package/build/swap.js +249 -0
  23. package/build/swap.js.map +1 -0
  24. package/build/swapLegacy.d.ts +16 -0
  25. package/build/swapLegacy.js +229 -0
  26. package/build/swapLegacy.js.map +1 -0
  27. package/build/swapV2.d.ts +11 -0
  28. package/build/swapV2.js +406 -0
  29. package/build/swapV2.js.map +1 -0
  30. package/build/types.d.ts +73 -0
  31. package/build/types.js +9 -0
  32. package/build/types.js.map +1 -0
  33. package/build/utils.d.ts +119 -0
  34. package/build/utils.js +219 -0
  35. package/build/utils.js.map +1 -0
  36. package/build/utilsV2.d.ts +88 -0
  37. package/build/utilsV2.js +180 -0
  38. package/build/utilsV2.js.map +1 -0
  39. package/build/withdrawLiquidity.d.ts +8 -0
  40. package/build/withdrawLiquidity.js +174 -0
  41. package/build/withdrawLiquidity.js.map +1 -0
  42. package/build/ytTrades.d.ts +106 -0
  43. package/build/ytTrades.js +292 -0
  44. package/build/ytTrades.js.map +1 -0
  45. package/build/ytTradesLegacy.d.ts +106 -0
  46. package/build/ytTradesLegacy.js +292 -0
  47. package/build/ytTradesLegacy.js.map +1 -0
  48. package/examples/.env.example +1 -0
  49. package/examples/test-histogram-simple.ts +172 -0
  50. package/examples/test-histogram.ts +112 -0
  51. package/package.json +26 -0
  52. package/src/addLiquidity.ts +384 -0
  53. package/src/bisect.ts +72 -0
  54. package/src/index.ts +74 -0
  55. package/src/liquidityHistogram.ts +192 -0
  56. package/src/quote.ts +128 -0
  57. package/src/swap.ts +299 -0
  58. package/src/swapLegacy.ts +272 -0
  59. package/src/types.ts +80 -0
  60. package/src/utils.ts +235 -0
  61. package/src/withdrawLiquidity.ts +240 -0
  62. package/src/ytTrades.ts +419 -0
  63. package/tsconfig.json +17 -0
package/build/index.js ADDED
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * Market Three Math - CLMM Simulation Package
4
+ *
5
+ * This package provides TypeScript implementations of the CLMM (Concentrated Liquidity Market Maker)
6
+ * mathematical functions from the Exponent CLMM program. It allows for client-side simulation of:
7
+ * - Swap operations (PT <-> SY trades)
8
+ * - Liquidity deposits (add_liquidity)
9
+ * - Price and liquidity calculations
10
+ *
11
+ * The implementations are ported from Rust code in solana/programs/exponent_clmm
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
25
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.SwapDirection = exports.buildLiquidityHistogramSimple = exports.buildLiquidityHistogram = exports.bisectSearch2 = exports.getPtAndSyOnWithdrawLiquidity = exports.simulateWrapperProvideLiquidity = exports.calcDepositSyAndPtFromBaseAmount = exports.estimateBalancedDeposit = exports.calculateLpOut = exports.computeLiquidityTargetAndTokenNeeds = exports.simulateAddLiquidity = exports.simulateBuyYtWithSyIn = exports.simulateSellYt = exports.simulateBuyYt = exports.QuoteDirection = exports.getSwapQuote = exports.simulateSwap = exports.getSuccessorTickByIdx = exports.calcPtPriceInAsset = exports.convertApyBpToApy = exports.convertApyToApyBp = exports.findTickByKey = exports.getImpliedRate = exports.getPredecessorTickKey = exports.getSuccessorTickKey = exports.getActiveLiquidity = exports.getFeeFromAmount = exports.calculateFeeRate = exports.normalizedTimeRemaining = exports.EffSnap = void 0;
29
+ // Export types
30
+ __exportStar(require("./types"), exports);
31
+ // Export utility functions
32
+ var utils_1 = require("./utils");
33
+ Object.defineProperty(exports, "EffSnap", { enumerable: true, get: function () { return utils_1.EffSnap; } });
34
+ Object.defineProperty(exports, "normalizedTimeRemaining", { enumerable: true, get: function () { return utils_1.normalizedTimeRemaining; } });
35
+ Object.defineProperty(exports, "calculateFeeRate", { enumerable: true, get: function () { return utils_1.calculateFeeRate; } });
36
+ Object.defineProperty(exports, "getFeeFromAmount", { enumerable: true, get: function () { return utils_1.getFeeFromAmount; } });
37
+ Object.defineProperty(exports, "getActiveLiquidity", { enumerable: true, get: function () { return utils_1.getActiveLiquidity; } });
38
+ Object.defineProperty(exports, "getSuccessorTickKey", { enumerable: true, get: function () { return utils_1.getSuccessorTickKey; } });
39
+ Object.defineProperty(exports, "getPredecessorTickKey", { enumerable: true, get: function () { return utils_1.getPredecessorTickKey; } });
40
+ Object.defineProperty(exports, "getImpliedRate", { enumerable: true, get: function () { return utils_1.getImpliedRate; } });
41
+ Object.defineProperty(exports, "findTickByKey", { enumerable: true, get: function () { return utils_1.findTickByKey; } });
42
+ Object.defineProperty(exports, "convertApyToApyBp", { enumerable: true, get: function () { return utils_1.convertApyToApyBp; } });
43
+ Object.defineProperty(exports, "convertApyBpToApy", { enumerable: true, get: function () { return utils_1.convertApyBpToApy; } });
44
+ Object.defineProperty(exports, "calcPtPriceInAsset", { enumerable: true, get: function () { return utils_1.calcPtPriceInAsset; } });
45
+ Object.defineProperty(exports, "getSuccessorTickByIdx", { enumerable: true, get: function () { return utils_1.getSuccessorTickByIdx; } });
46
+ // Export swap functions
47
+ var swap_1 = require("./swap");
48
+ Object.defineProperty(exports, "simulateSwap", { enumerable: true, get: function () { return swap_1.simulateSwap; } });
49
+ var quote_1 = require("./quote");
50
+ Object.defineProperty(exports, "getSwapQuote", { enumerable: true, get: function () { return quote_1.getSwapQuote; } });
51
+ Object.defineProperty(exports, "QuoteDirection", { enumerable: true, get: function () { return quote_1.QuoteDirection; } });
52
+ // Export YT trade functions
53
+ var ytTrades_1 = require("./ytTrades");
54
+ Object.defineProperty(exports, "simulateBuyYt", { enumerable: true, get: function () { return ytTrades_1.simulateBuyYt; } });
55
+ Object.defineProperty(exports, "simulateSellYt", { enumerable: true, get: function () { return ytTrades_1.simulateSellYt; } });
56
+ Object.defineProperty(exports, "simulateBuyYtWithSyIn", { enumerable: true, get: function () { return ytTrades_1.simulateBuyYtWithSyIn; } });
57
+ // Export add liquidity functions
58
+ var addLiquidity_1 = require("./addLiquidity");
59
+ Object.defineProperty(exports, "simulateAddLiquidity", { enumerable: true, get: function () { return addLiquidity_1.simulateAddLiquidity; } });
60
+ Object.defineProperty(exports, "computeLiquidityTargetAndTokenNeeds", { enumerable: true, get: function () { return addLiquidity_1.computeLiquidityTargetAndTokenNeeds; } });
61
+ Object.defineProperty(exports, "calculateLpOut", { enumerable: true, get: function () { return addLiquidity_1.calculateLpOut; } });
62
+ Object.defineProperty(exports, "estimateBalancedDeposit", { enumerable: true, get: function () { return addLiquidity_1.estimateBalancedDeposit; } });
63
+ Object.defineProperty(exports, "calcDepositSyAndPtFromBaseAmount", { enumerable: true, get: function () { return addLiquidity_1.calcDepositSyAndPtFromBaseAmount; } });
64
+ Object.defineProperty(exports, "simulateWrapperProvideLiquidity", { enumerable: true, get: function () { return addLiquidity_1.simulateWrapperProvideLiquidity; } });
65
+ var withdrawLiquidity_1 = require("./withdrawLiquidity");
66
+ Object.defineProperty(exports, "getPtAndSyOnWithdrawLiquidity", { enumerable: true, get: function () { return withdrawLiquidity_1.getPtAndSyOnWithdrawLiquidity; } });
67
+ // Export bisect search utility
68
+ var bisect_1 = require("./bisect");
69
+ Object.defineProperty(exports, "bisectSearch2", { enumerable: true, get: function () { return bisect_1.bisectSearch2; } });
70
+ // Export liquidity histogram functions
71
+ var liquidityHistogram_1 = require("./liquidityHistogram");
72
+ Object.defineProperty(exports, "buildLiquidityHistogram", { enumerable: true, get: function () { return liquidityHistogram_1.buildLiquidityHistogram; } });
73
+ Object.defineProperty(exports, "buildLiquidityHistogramSimple", { enumerable: true, get: function () { return liquidityHistogram_1.buildLiquidityHistogramSimple; } });
74
+ var types_1 = require("./types");
75
+ Object.defineProperty(exports, "SwapDirection", { enumerable: true, get: function () { return types_1.SwapDirection; } });
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;AAEH,eAAe;AACf,0CAAuB;AAEvB,2BAA2B;AAC3B,iCAcgB;AAbd,gGAAA,OAAO,OAAA;AACP,gHAAA,uBAAuB,OAAA;AACvB,yGAAA,gBAAgB,OAAA;AAChB,yGAAA,gBAAgB,OAAA;AAChB,2GAAA,kBAAkB,OAAA;AAClB,4GAAA,mBAAmB,OAAA;AACnB,8GAAA,qBAAqB,OAAA;AACrB,uGAAA,cAAc,OAAA;AACd,sGAAA,aAAa,OAAA;AACb,0GAAA,iBAAiB,OAAA;AACjB,0GAAA,iBAAiB,OAAA;AACjB,2GAAA,kBAAkB,OAAA;AAClB,8GAAA,qBAAqB,OAAA;AAGvB,wBAAwB;AACxB,+BAAqC;AAA5B,oGAAA,YAAY,OAAA;AACrB,iCAAsD;AAA7C,qGAAA,YAAY,OAAA;AAAE,uGAAA,cAAc,OAAA;AAErC,4BAA4B;AAC5B,uCAAiF;AAAxE,yGAAA,aAAa,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAQ7D,iCAAiC;AACjC,+CAOuB;AANrB,oHAAA,oBAAoB,OAAA;AACpB,mIAAA,mCAAmC,OAAA;AACnC,8GAAA,cAAc,OAAA;AACd,uHAAA,uBAAuB,OAAA;AACvB,gIAAA,gCAAgC,OAAA;AAChC,+HAAA,+BAA+B,OAAA;AAGjC,yDAAmE;AAA1D,kIAAA,6BAA6B,OAAA;AAEtC,+BAA+B;AAC/B,mCAAwC;AAA/B,uGAAA,aAAa,OAAA;AAEtB,uCAAuC;AACvC,2DAA6F;AAApF,6HAAA,uBAAuB,OAAA;AAAE,mIAAA,6BAA6B,OAAA;AAY/D,iCAAuC;AAA9B,sGAAA,aAAa,OAAA"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Liquidity histogram utilities for CLMM markets
3
+ * Builds a histogram of liquidity distribution across tick_space aligned bins
4
+ */
5
+ import { Ticks } from "@exponent-labs/exponent-fetcher";
6
+ export interface LiquidityHistogramBin {
7
+ /** APY for this bin (tick_space aligned) */
8
+ apy: number;
9
+ /** Principal PT amount in this bin */
10
+ principalPt: number;
11
+ /** Principal SY amount in this bin */
12
+ principalSy: number;
13
+ /** Tick key (basis points) */
14
+ tickKey: number;
15
+ }
16
+ /**
17
+ * Build a liquidity distribution histogram with tick_space aligned bins
18
+ *
19
+ * This function projects liquidity from created ticks onto virtual bins aligned
20
+ * to tickSpace. The projection logic is analogous to project_anchor_shares_to_current_ticks
21
+ * from remove_liquidity.rs, where liquidity is distributed proportionally based on
22
+ * the spot price ranges.
23
+ *
24
+ * Example:
25
+ * - Created ticks at: 1%, 5%, 6%
26
+ * - tickSpace: 1% (100 basis points)
27
+ * - Result bins: 1%, 2%, 3%, 4%, 5%, 6%
28
+ *
29
+ * For a tick interval [1%, 5%] with principalPt=1000:
30
+ * - Range: 5% - 1% = 4%
31
+ * - Bin [1%, 2%]: gets 1000 * (2%-1%)/(5%-1%) = 250
32
+ * - Bin [2%, 3%]: gets 1000 * (3%-2%)/(5%-1%) = 250
33
+ * - Bin [3%, 4%]: gets 1000 * (4%-3%)/(5%-1%) = 250
34
+ * - Bin [4%, 5%]: gets 1000 * (5%-4%)/(5%-1%) = 250
35
+ *
36
+ * @param ticks - The market's ticks state
37
+ * @param tickSpace - The tick spacing in basis points (e.g., 100 for 1%)
38
+ * @returns Array of histogram bins aligned to tickSpace
39
+ */
40
+ export declare function buildLiquidityHistogram(ticks: Ticks, tickSpace: number): LiquidityHistogramBin[];
41
+ /**
42
+ * Build a simplified histogram without projection
43
+ *
44
+ * This version simply returns the principal amounts at each created tick,
45
+ * without projecting onto tickSpace-aligned bins.
46
+ *
47
+ * @param ticks - The market's ticks state
48
+ * @returns Array of histogram bins for created ticks only
49
+ */
50
+ export declare function buildLiquidityHistogramSimple(ticks: Ticks): LiquidityHistogramBin[];
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * Liquidity histogram utilities for CLMM markets
4
+ * Builds a histogram of liquidity distribution across tick_space aligned bins
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.buildLiquidityHistogramSimple = exports.buildLiquidityHistogram = void 0;
8
+ const utils_1 = require("./utils");
9
+ /**
10
+ * Build a liquidity distribution histogram with tick_space aligned bins
11
+ *
12
+ * This function projects liquidity from created ticks onto virtual bins aligned
13
+ * to tickSpace. The projection logic is analogous to project_anchor_shares_to_current_ticks
14
+ * from remove_liquidity.rs, where liquidity is distributed proportionally based on
15
+ * the spot price ranges.
16
+ *
17
+ * Example:
18
+ * - Created ticks at: 1%, 5%, 6%
19
+ * - tickSpace: 1% (100 basis points)
20
+ * - Result bins: 1%, 2%, 3%, 4%, 5%, 6%
21
+ *
22
+ * For a tick interval [1%, 5%] with principalPt=1000:
23
+ * - Range: 5% - 1% = 4%
24
+ * - Bin [1%, 2%]: gets 1000 * (2%-1%)/(5%-1%) = 250
25
+ * - Bin [2%, 3%]: gets 1000 * (3%-2%)/(5%-1%) = 250
26
+ * - Bin [3%, 4%]: gets 1000 * (4%-3%)/(5%-1%) = 250
27
+ * - Bin [4%, 5%]: gets 1000 * (5%-4%)/(5%-1%) = 250
28
+ *
29
+ * @param ticks - The market's ticks state
30
+ * @param tickSpace - The tick spacing in basis points (e.g., 100 for 1%)
31
+ * @returns Array of histogram bins aligned to tickSpace
32
+ */
33
+ function buildLiquidityHistogram(ticks, tickSpace) {
34
+ const histogram = [];
35
+ // Edge case: no ticks created yet
36
+ if (!ticks.ticksTree.length || ticks.ticksTree.length === 0) {
37
+ return histogram;
38
+ }
39
+ // Find min and max tick keys (apyBasePoints)
40
+ const tickKeys = ticks.ticksTree.map((t) => t.apyBasePoints).sort((a, b) => a - b);
41
+ const minTickKey = tickKeys[0];
42
+ const maxTickKey = tickKeys[tickKeys.length - 1];
43
+ // Align min and max to tickSpace boundaries
44
+ const minAlignedKey = Math.floor(minTickKey / tickSpace) * tickSpace;
45
+ const maxAlignedKey = Math.ceil(maxTickKey / tickSpace) * tickSpace;
46
+ // Create map of created ticks for fast lookup
47
+ const tickMap = new Map();
48
+ for (const tick of ticks.ticksTree) {
49
+ tickMap.set(tick.apyBasePoints, tick);
50
+ }
51
+ // Create bins map (virtual ticks aligned to tickSpace)
52
+ const binMap = new Map();
53
+ // Initialize all bins from min to max with tickSpace steps
54
+ for (let binKey = minAlignedKey; binKey <= maxAlignedKey; binKey += tickSpace) {
55
+ binMap.set(binKey, { principalPt: 0, principalSy: 0 });
56
+ }
57
+ // Iterate through all created tick intervals and project liquidity
58
+ let currentTickKey = minTickKey;
59
+ while (currentTickKey !== null) {
60
+ const currentTick = tickMap.get(currentTickKey);
61
+ const nextTickKey = (0, utils_1.getSuccessorTickKey)(ticks, currentTickKey);
62
+ if (currentTick) {
63
+ // Principal amounts in this tick
64
+ const intervalPrincipalPt = currentTick.principalPt;
65
+ const intervalPrincipalSy = currentTick.principalSy;
66
+ // Skip if no liquidity in this tick
67
+ if (intervalPrincipalPt > 0 || intervalPrincipalSy > 0) {
68
+ if (nextTickKey !== null) {
69
+ // We have an interval [currentTickKey, nextTickKey)
70
+ const intervalStartKey = currentTickKey;
71
+ const intervalEndKey = nextTickKey;
72
+ const fullRange = intervalEndKey - intervalStartKey;
73
+ // Find all bins that intersect with this interval
74
+ const firstBinKey = Math.ceil(intervalStartKey / tickSpace) * tickSpace;
75
+ const lastBinKey = Math.floor((intervalEndKey - 1) / tickSpace) * tickSpace;
76
+ // Special case: interval is smaller than tickSpace
77
+ if (firstBinKey > lastBinKey) {
78
+ // Put all liquidity in the bin that contains the interval start
79
+ const containingBinKey = Math.floor(intervalStartKey / tickSpace) * tickSpace;
80
+ const bin = binMap.get(containingBinKey);
81
+ if (bin) {
82
+ bin.principalPt += Number(intervalPrincipalPt);
83
+ bin.principalSy += Number(intervalPrincipalSy);
84
+ }
85
+ }
86
+ else {
87
+ // Distribute proportionally across bins
88
+ for (let binKey = firstBinKey; binKey <= lastBinKey; binKey += tickSpace) {
89
+ const bin = binMap.get(binKey);
90
+ if (!bin)
91
+ continue;
92
+ // Calculate the range of this bin that overlaps with the interval
93
+ const binStart = Math.max(binKey, intervalStartKey);
94
+ const binEnd = Math.min(binKey + tickSpace, intervalEndKey);
95
+ const binRange = binEnd - binStart;
96
+ // Proportional share of liquidity for this bin
97
+ const share = binRange / fullRange;
98
+ bin.principalPt += Math.floor(Number(intervalPrincipalPt) * share);
99
+ bin.principalSy += Math.floor(Number(intervalPrincipalSy) * share);
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ // Last tick - put all liquidity in its bin
105
+ const containingBinKey = Math.floor(currentTickKey / tickSpace) * tickSpace;
106
+ const bin = binMap.get(containingBinKey);
107
+ if (bin) {
108
+ bin.principalPt += Number(intervalPrincipalPt);
109
+ bin.principalSy += Number(intervalPrincipalSy);
110
+ }
111
+ }
112
+ }
113
+ }
114
+ currentTickKey = nextTickKey;
115
+ }
116
+ // Convert map to sorted array
117
+ const sortedBinKeys = Array.from(binMap.keys()).sort((a, b) => a - b);
118
+ for (const binKey of sortedBinKeys) {
119
+ const bin = binMap.get(binKey);
120
+ // Only include bins with non-zero liquidity
121
+ if (bin.principalPt > 0 || bin.principalSy > 0) {
122
+ histogram.push({
123
+ apy: (0, utils_1.convertApyBpToApy)(binKey),
124
+ principalPt: bin.principalPt,
125
+ principalSy: bin.principalSy,
126
+ tickKey: binKey,
127
+ });
128
+ }
129
+ }
130
+ return histogram;
131
+ }
132
+ exports.buildLiquidityHistogram = buildLiquidityHistogram;
133
+ /**
134
+ * Build a simplified histogram without projection
135
+ *
136
+ * This version simply returns the principal amounts at each created tick,
137
+ * without projecting onto tickSpace-aligned bins.
138
+ *
139
+ * @param ticks - The market's ticks state
140
+ * @returns Array of histogram bins for created ticks only
141
+ */
142
+ function buildLiquidityHistogramSimple(ticks) {
143
+ const histogram = [];
144
+ if (!ticks.ticksTree || ticks.ticksTree.length === 0) {
145
+ return histogram;
146
+ }
147
+ // Sort by apyBasePoints and iterate
148
+ const sortedTicks = [...ticks.ticksTree].sort((a, b) => a.apyBasePoints - b.apyBasePoints);
149
+ for (const tick of sortedTicks) {
150
+ if (tick.principalPt > 0 || tick.principalSy > 0) {
151
+ histogram.push({
152
+ apy: (0, utils_1.convertApyBpToApy)(tick.apyBasePoints),
153
+ principalPt: Number(tick.principalPt),
154
+ principalSy: Number(tick.principalSy),
155
+ tickKey: tick.apyBasePoints,
156
+ });
157
+ }
158
+ }
159
+ return histogram;
160
+ }
161
+ exports.buildLiquidityHistogramSimple = buildLiquidityHistogramSimple;
162
+ //# sourceMappingURL=liquidityHistogram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liquidityHistogram.js","sourceRoot":"","sources":["../src/liquidityHistogram.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,mCAAiE;AAajE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,uBAAuB,CAAC,KAAY,EAAE,SAAiB;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAA;IAE7C,kCAAkC;IAClC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAClF,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAEhD,4CAA4C;IAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IACpE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAEnE,8CAA8C;IAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuC,CAAA;IAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,uDAAuD;IACvD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwD,CAAA;IAE9E,2DAA2D;IAC3D,KAAK,IAAI,MAAM,GAAG,aAAa,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC;QAC9E,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,mEAAmE;IACnE,IAAI,cAAc,GAAkB,UAAU,CAAA;IAE9C,OAAO,cAAc,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAC/C,MAAM,WAAW,GAAG,IAAA,2BAAmB,EAAC,KAAK,EAAE,cAAc,CAAC,CAAA;QAE9D,IAAI,WAAW,EAAE,CAAC;YAChB,iCAAiC;YACjC,MAAM,mBAAmB,GAAG,WAAW,CAAC,WAAW,CAAA;YACnD,MAAM,mBAAmB,GAAG,WAAW,CAAC,WAAW,CAAA;YAEnD,oCAAoC;YACpC,IAAI,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;gBACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACzB,oDAAoD;oBACpD,MAAM,gBAAgB,GAAG,cAAc,CAAA;oBACvC,MAAM,cAAc,GAAG,WAAW,CAAA;oBAClC,MAAM,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAAA;oBAEnD,kDAAkD;oBAClD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;oBACvE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;oBAE3E,mDAAmD;oBACnD,IAAI,WAAW,GAAG,UAAU,EAAE,CAAC;wBAC7B,gEAAgE;wBAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;wBAC7E,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;wBACxC,IAAI,GAAG,EAAE,CAAC;4BACR,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;4BAC9C,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;wBAChD,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,wCAAwC;wBACxC,KAAK,IAAI,MAAM,GAAG,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC;4BACzE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;4BAC9B,IAAI,CAAC,GAAG;gCAAE,SAAQ;4BAElB,kEAAkE;4BAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;4BACnD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,cAAc,CAAC,CAAA;4BAC3D,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;4BAElC,+CAA+C;4BAC/C,MAAM,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAA;4BAElC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,CAAA;4BAClE,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,CAAA;wBACpE,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,2CAA2C;oBAC3C,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;oBAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;oBACxC,IAAI,GAAG,EAAE,CAAC;wBACR,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;wBAC9C,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;oBAChD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,cAAc,GAAG,WAAW,CAAA;IAC9B,CAAC;IAED,8BAA8B;IAC9B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAErE,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAE,CAAA;QAE/B,4CAA4C;QAC5C,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YAC/C,SAAS,CAAC,IAAI,CAAC;gBACb,GAAG,EAAE,IAAA,yBAAiB,EAAC,MAAM,CAAC;gBAC9B,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,OAAO,EAAE,MAAM;aAChB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAnHD,0DAmHC;AAED;;;;;;;;GAQG;AACH,SAAgB,6BAA6B,CAAC,KAAY;IACxD,MAAM,SAAS,GAA4B,EAAE,CAAA;IAE7C,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,oCAAoC;IACpC,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC,CAAA;IAE1F,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACjD,SAAS,CAAC,IAAI,CAAC;gBACb,GAAG,EAAE,IAAA,yBAAiB,EAAC,IAAI,CAAC,aAAa,CAAC;gBAC1C,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;gBACrC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;gBACrC,OAAO,EAAE,IAAI,CAAC,aAAa;aAC5B,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAtBD,sEAsBC"}
@@ -0,0 +1,18 @@
1
+ import { MarketThreeState } from "./types";
2
+ export declare enum QuoteDirection {
3
+ PtToSy = "PtToSy",
4
+ SyToPt = "SyToPt",
5
+ YtToSy = "YtToSy",
6
+ SyToYt = "SyToYt"
7
+ }
8
+ export type Quote = {
9
+ amountIn: number;
10
+ amountOut: number;
11
+ lpFee: number;
12
+ protocolFee: number;
13
+ };
14
+ /**
15
+ * Calculate the expected output for a given input amount
16
+ * This is a convenience wrapper around simulateSwap
17
+ */
18
+ export declare function getSwapQuote(marketState: MarketThreeState, amountIn: number, direction: QuoteDirection): Quote;
package/build/quote.js ADDED
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSwapQuote = exports.QuoteDirection = void 0;
4
+ const swap_1 = require("./swap");
5
+ const types_1 = require("./types");
6
+ const ytTrades_1 = require("./ytTrades");
7
+ var QuoteDirection;
8
+ (function (QuoteDirection) {
9
+ QuoteDirection["PtToSy"] = "PtToSy";
10
+ QuoteDirection["SyToPt"] = "SyToPt";
11
+ QuoteDirection["YtToSy"] = "YtToSy";
12
+ QuoteDirection["SyToYt"] = "SyToYt";
13
+ })(QuoteDirection || (exports.QuoteDirection = QuoteDirection = {}));
14
+ /**
15
+ * Calculate the expected output for a given input amount
16
+ * This is a convenience wrapper around simulateSwap
17
+ */
18
+ function getSwapQuote(marketState, amountIn, direction) {
19
+ //? Calculate correct currentTick index
20
+ //TODO Remove this logic when contract is updated!!!
21
+ const currentTickIndex = calculateCurrentTickIndex(marketState.ticks);
22
+ const marketStateMutated = {
23
+ ...marketState,
24
+ ticks: {
25
+ ...marketState.ticks,
26
+ currentTick: currentTickIndex,
27
+ },
28
+ };
29
+ if (direction === QuoteDirection.PtToSy) {
30
+ const { amountInConsumed, amountOut, lpFeeChargedOutToken, protocolFeeChargedOutToken } = (0, swap_1.simulateSwap)(marketStateMutated, {
31
+ direction: types_1.SwapDirection.PtToSy,
32
+ amountIn,
33
+ syExchangeRate: marketStateMutated.currentSyExchangeRate,
34
+ isCurrentFlashSwap: false,
35
+ });
36
+ return {
37
+ amountIn: amountInConsumed,
38
+ amountOut: amountOut,
39
+ lpFee: lpFeeChargedOutToken,
40
+ protocolFee: protocolFeeChargedOutToken,
41
+ };
42
+ }
43
+ if (direction === QuoteDirection.SyToPt) {
44
+ const { amountInConsumed, amountOut, lpFeeChargedOutToken, protocolFeeChargedOutToken } = (0, swap_1.simulateSwap)(marketStateMutated, {
45
+ direction: types_1.SwapDirection.SyToPt,
46
+ amountIn,
47
+ syExchangeRate: marketStateMutated.currentSyExchangeRate,
48
+ isCurrentFlashSwap: false,
49
+ });
50
+ return {
51
+ amountIn: amountInConsumed,
52
+ amountOut: amountOut,
53
+ lpFee: lpFeeChargedOutToken,
54
+ protocolFee: protocolFeeChargedOutToken,
55
+ };
56
+ }
57
+ if (direction === QuoteDirection.YtToSy) {
58
+ const { ytIn, netSyReceived, lpFee, protocolFee } = (0, ytTrades_1.simulateSellYt)(marketStateMutated, {
59
+ ytIn: amountIn,
60
+ syExchangeRate: marketStateMutated.currentSyExchangeRate,
61
+ });
62
+ return {
63
+ amountIn: ytIn,
64
+ amountOut: netSyReceived,
65
+ lpFee: lpFee,
66
+ protocolFee: protocolFee,
67
+ };
68
+ }
69
+ if (direction === QuoteDirection.SyToYt) {
70
+ const { ytOut, netSyCost, lpFee, protocolFee } = (0, ytTrades_1.simulateBuyYtWithSyIn)(marketStateMutated, {
71
+ syIn: amountIn,
72
+ syExchangeRate: marketStateMutated.currentSyExchangeRate,
73
+ });
74
+ return {
75
+ amountIn: netSyCost,
76
+ amountOut: ytOut,
77
+ lpFee: lpFee,
78
+ protocolFee,
79
+ };
80
+ }
81
+ throw new Error(`Unknown quote direction: ${direction}`);
82
+ }
83
+ exports.getSwapQuote = getSwapQuote;
84
+ /**
85
+ * Calculate the correct currentTick index for the market state
86
+ *
87
+ * IMPORTANT: currentTick must be a 1-based ARRAY INDEX, not apyBasePoints!
88
+ * The simulateSwap function uses findTickByIndex which does: ticksTree.at(index - 1)
89
+ *
90
+ * @returns The 1-based array index of the tick where impliedRate <= currentSpotPrice
91
+ */
92
+ function calculateCurrentTickIndex(ticksData) {
93
+ // Find the tick with highest impliedRate <= currentSpotPrice
94
+ let currentTickApyBps = ticksData.ticksTree[0]?.apyBasePoints || 0;
95
+ for (const tick of ticksData.ticksTree) {
96
+ const tickRate = Number(tick.impliedRate);
97
+ if (tickRate <= ticksData.currentSpotPrice) {
98
+ currentTickApyBps = tick.apyBasePoints;
99
+ }
100
+ }
101
+ // Find the array index (0-based) of this tick
102
+ const arrayIndex = ticksData.ticksTree.findIndex((t) => t.apyBasePoints === currentTickApyBps);
103
+ // Convert to 1-based index for simulateSwap
104
+ return arrayIndex !== -1 ? arrayIndex + 1 : 1;
105
+ }
106
+ //# sourceMappingURL=quote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote.js","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * CLMM Swap simulation - V2
3
+ * Updated to match the latest Rust on-chain implementation
4
+ * Key changes:
5
+ * - Uses currentPrefixSum for active liquidity
6
+ * - Implements kappa scaling for principal-limited swaps
7
+ * - Correct tick key conversions (1e6 basis)
8
+ */
9
+ import { MarketThreeState, SwapArgs, SwapDirection, SwapOutcome } from "./types";
10
+ /**
11
+ * Simulate a swap on the CLMM market
12
+ * This is a pure function that does not mutate the market state
13
+ * Returns the swap outcome including amounts and final state
14
+ */
15
+ export declare function simulateSwap(marketState: MarketThreeState, args: SwapArgs): SwapOutcome;
16
+ /**
17
+ * Calculate the expected output for a given input amount
18
+ * This is a convenience wrapper around simulateSwap
19
+ */
20
+ export declare function getSwapQuote(marketState: MarketThreeState, amountIn: number, direction: SwapDirection): SwapOutcome;