sally-defi-ts-sdk 0.3.2

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 (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -0
  3. package/dist/aio/client.d.ts +93 -0
  4. package/dist/aio/client.d.ts.map +1 -0
  5. package/dist/aio/client.js +283 -0
  6. package/dist/aio/client.js.map +1 -0
  7. package/dist/aio/index.d.ts +20 -0
  8. package/dist/aio/index.d.ts.map +1 -0
  9. package/dist/aio/index.js +19 -0
  10. package/dist/aio/index.js.map +1 -0
  11. package/dist/aio/modules/fees.d.ts +19 -0
  12. package/dist/aio/modules/fees.d.ts.map +1 -0
  13. package/dist/aio/modules/fees.js +47 -0
  14. package/dist/aio/modules/fees.js.map +1 -0
  15. package/dist/aio/modules/liquidity.d.ts +47 -0
  16. package/dist/aio/modules/liquidity.d.ts.map +1 -0
  17. package/dist/aio/modules/liquidity.js +115 -0
  18. package/dist/aio/modules/liquidity.js.map +1 -0
  19. package/dist/aio/modules/prices.d.ts +18 -0
  20. package/dist/aio/modules/prices.d.ts.map +1 -0
  21. package/dist/aio/modules/prices.js +48 -0
  22. package/dist/aio/modules/prices.js.map +1 -0
  23. package/dist/aio/modules/swap.d.ts +50 -0
  24. package/dist/aio/modules/swap.d.ts.map +1 -0
  25. package/dist/aio/modules/swap.js +267 -0
  26. package/dist/aio/modules/swap.js.map +1 -0
  27. package/dist/aio/modules/wallet.d.ts +13 -0
  28. package/dist/aio/modules/wallet.d.ts.map +1 -0
  29. package/dist/aio/modules/wallet.js +27 -0
  30. package/dist/aio/modules/wallet.js.map +1 -0
  31. package/dist/aio/token.d.ts +19 -0
  32. package/dist/aio/token.d.ts.map +1 -0
  33. package/dist/aio/token.js +50 -0
  34. package/dist/aio/token.js.map +1 -0
  35. package/dist/client.d.ts +142 -0
  36. package/dist/client.d.ts.map +1 -0
  37. package/dist/client.js +452 -0
  38. package/dist/client.js.map +1 -0
  39. package/dist/constants.d.ts +36 -0
  40. package/dist/constants.d.ts.map +1 -0
  41. package/dist/constants.js +39 -0
  42. package/dist/constants.js.map +1 -0
  43. package/dist/data/deployment.json +1 -0
  44. package/dist/deployment.d.ts +44 -0
  45. package/dist/deployment.d.ts.map +1 -0
  46. package/dist/deployment.js +118 -0
  47. package/dist/deployment.js.map +1 -0
  48. package/dist/errors.d.ts +57 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +197 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/index.d.ts +48 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +47 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/modules/fees.d.ts +32 -0
  57. package/dist/modules/fees.d.ts.map +1 -0
  58. package/dist/modules/fees.js +64 -0
  59. package/dist/modules/fees.js.map +1 -0
  60. package/dist/modules/liquidity.d.ts +134 -0
  61. package/dist/modules/liquidity.d.ts.map +1 -0
  62. package/dist/modules/liquidity.js +277 -0
  63. package/dist/modules/liquidity.js.map +1 -0
  64. package/dist/modules/prices.d.ts +47 -0
  65. package/dist/modules/prices.d.ts.map +1 -0
  66. package/dist/modules/prices.js +85 -0
  67. package/dist/modules/prices.js.map +1 -0
  68. package/dist/modules/swap.d.ts +102 -0
  69. package/dist/modules/swap.d.ts.map +1 -0
  70. package/dist/modules/swap.js +400 -0
  71. package/dist/modules/swap.js.map +1 -0
  72. package/dist/modules/wallet.d.ts +16 -0
  73. package/dist/modules/wallet.d.ts.map +1 -0
  74. package/dist/modules/wallet.js +30 -0
  75. package/dist/modules/wallet.js.map +1 -0
  76. package/dist/permit2.d.ts +97 -0
  77. package/dist/permit2.d.ts.map +1 -0
  78. package/dist/permit2.js +130 -0
  79. package/dist/permit2.js.map +1 -0
  80. package/dist/previews.d.ts +57 -0
  81. package/dist/previews.d.ts.map +1 -0
  82. package/dist/previews.js +69 -0
  83. package/dist/previews.js.map +1 -0
  84. package/dist/safety.d.ts +80 -0
  85. package/dist/safety.d.ts.map +1 -0
  86. package/dist/safety.js +133 -0
  87. package/dist/safety.js.map +1 -0
  88. package/dist/token.d.ts +215 -0
  89. package/dist/token.d.ts.map +1 -0
  90. package/dist/token.js +239 -0
  91. package/dist/token.js.map +1 -0
  92. package/dist/types.d.ts +229 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +462 -0
  95. package/dist/types.js.map +1 -0
  96. package/dist/util.d.ts +13 -0
  97. package/dist/util.d.ts.map +1 -0
  98. package/dist/util.js +22 -0
  99. package/dist/util.js.map +1 -0
  100. package/package.json +48 -0
  101. package/src/aio/client.ts +329 -0
  102. package/src/aio/index.ts +20 -0
  103. package/src/aio/modules/fees.ts +60 -0
  104. package/src/aio/modules/liquidity.ts +181 -0
  105. package/src/aio/modules/prices.ts +57 -0
  106. package/src/aio/modules/swap.ts +347 -0
  107. package/src/aio/modules/wallet.ts +34 -0
  108. package/src/aio/token.ts +59 -0
  109. package/src/client.ts +526 -0
  110. package/src/constants.ts +43 -0
  111. package/src/data/deployment.json +1 -0
  112. package/src/deployment.ts +132 -0
  113. package/src/errors.ts +215 -0
  114. package/src/index.ts +90 -0
  115. package/src/modules/fees.ts +78 -0
  116. package/src/modules/liquidity.ts +446 -0
  117. package/src/modules/prices.ts +97 -0
  118. package/src/modules/swap.ts +502 -0
  119. package/src/modules/wallet.ts +37 -0
  120. package/src/permit2.ts +169 -0
  121. package/src/previews.ts +95 -0
  122. package/src/safety.ts +152 -0
  123. package/src/token.ts +254 -0
  124. package/src/types.ts +438 -0
  125. package/src/util.ts +20 -0
@@ -0,0 +1,446 @@
1
+ /**
2
+ * Liquidity management: add / increase / decrease / remove / lock / harvest,
3
+ * plus position & pool reads (Sidecar views served through the liq proxy).
4
+ *
5
+ * Add-liquidity takes a single struct on-chain; the SDK exposes explicit options
6
+ * with sane defaults (mins = 0, lockDays = 0, referral = zero, deadline auto) and
7
+ * auto-approves the ERC-20 sides to the liq proxy before sending.
8
+ */
9
+
10
+ import { Contract, getAddress } from "ethers";
11
+ import type { SallyClient } from "../client.js";
12
+ import { ZERO, isNative } from "../token.js";
13
+ import {
14
+ ClaimableFees,
15
+ Lock,
16
+ V2PoolState,
17
+ V2Position,
18
+ V3PoolState,
19
+ V3Position,
20
+ V4PoolState,
21
+ V4Position,
22
+ } from "../types.js";
23
+
24
+ const DEFAULT_DEADLINE_SECS = 1200; // 20 min
25
+
26
+ type Tx = Record<string, any>;
27
+ type PoolKey = [string, string, number, number, string];
28
+
29
+ export class Liquidity {
30
+ private _c: SallyClient;
31
+ private _liq: Contract;
32
+ private _side: Contract;
33
+
34
+ constructor(client: SallyClient) {
35
+ this._c = client;
36
+ this._liq = client.liquidityContract;
37
+ this._side = client.sidecarContract;
38
+ }
39
+
40
+ // ------------------------------------------------------------------ //
41
+ // helpers
42
+ // ------------------------------------------------------------------ //
43
+ private _a(x: string): string {
44
+ return getAddress(x);
45
+ }
46
+
47
+ deadline(secs: number = DEFAULT_DEADLINE_SECS): number {
48
+ return Math.floor(Date.now() / 1000) + secs;
49
+ }
50
+
51
+ /**
52
+ * Approve each [token, amount] ERC-20 side to the liq proxy.
53
+ * Returns the native value to attach (sum of any native-token sides).
54
+ */
55
+ private async _approveAndValue(pairs: [string, bigint][]): Promise<bigint> {
56
+ const spender = this._c.addresses["liquidity"];
57
+ let value = 0n;
58
+ for (const [token, amount] of pairs) {
59
+ if (amount <= 0n) continue;
60
+ if (isNative(token)) {
61
+ value += amount;
62
+ } else {
63
+ await this._c.token(token).ensureAllowance(spender, amount);
64
+ }
65
+ }
66
+ return value;
67
+ }
68
+
69
+ // ------------------------------------------------------------------ //
70
+ // add liquidity
71
+ // ------------------------------------------------------------------ //
72
+ async addV2(
73
+ dexId: number,
74
+ tokenA: string,
75
+ tokenB: string,
76
+ amountA: bigint,
77
+ amountB: bigint,
78
+ opts: {
79
+ amountAMin?: bigint;
80
+ amountBMin?: bigint;
81
+ lockDays?: number;
82
+ referral?: string;
83
+ deadline?: number | null;
84
+ approve?: boolean;
85
+ tx?: Tx;
86
+ } = {},
87
+ ): Promise<any> {
88
+ tokenA = this._a(tokenA);
89
+ tokenB = this._a(tokenB);
90
+ const approve = opts.approve ?? true;
91
+ const value = approve ? await this._approveAndValue([[tokenA, amountA], [tokenB, amountB]]) : 0n;
92
+ const p = [
93
+ dexId, tokenA, tokenB, amountA, amountB,
94
+ opts.amountAMin ?? 0n, opts.amountBMin ?? 0n, opts.lockDays ?? 0, this._a(opts.referral ?? ZERO),
95
+ opts.deadline ?? this.deadline(),
96
+ ];
97
+ return this._c.send(this._liq.getFunction("addLiquidityV2"), [p], { value, ...(opts.tx ?? {}) });
98
+ }
99
+
100
+ async addV3(
101
+ dexId: number,
102
+ token0: string,
103
+ token1: string,
104
+ fee: number,
105
+ tickLower: number,
106
+ tickUpper: number,
107
+ amount0: bigint,
108
+ amount1: bigint,
109
+ opts: {
110
+ amount0Min?: bigint;
111
+ amount1Min?: bigint;
112
+ lockDays?: number;
113
+ referral?: string;
114
+ deadline?: number | null;
115
+ approve?: boolean;
116
+ tx?: Tx;
117
+ } = {},
118
+ ): Promise<any> {
119
+ token0 = this._a(token0);
120
+ token1 = this._a(token1);
121
+ const approve = opts.approve ?? true;
122
+ const value = approve ? await this._approveAndValue([[token0, amount0], [token1, amount1]]) : 0n;
123
+ const p = [
124
+ dexId, token0, token1, fee, tickLower, tickUpper,
125
+ amount0, amount1, opts.amount0Min ?? 0n, opts.amount1Min ?? 0n,
126
+ opts.lockDays ?? 0, this._a(opts.referral ?? ZERO), opts.deadline ?? this.deadline(),
127
+ ];
128
+ return this._c.send(this._liq.getFunction("addLiquidityV3"), [p], { value, ...(opts.tx ?? {}) });
129
+ }
130
+
131
+ /** poolKey = [currency0, currency1, fee, tickSpacing, hooks]. */
132
+ async addV4(
133
+ dexId: number,
134
+ poolKey: PoolKey,
135
+ tickLower: number,
136
+ tickUpper: number,
137
+ liquidity: bigint,
138
+ amount0Max: bigint,
139
+ amount1Max: bigint,
140
+ amount0: bigint,
141
+ amount1: bigint,
142
+ opts: {
143
+ lockDays?: number;
144
+ referral?: string;
145
+ deadline?: number | null;
146
+ approve?: boolean;
147
+ tx?: Tx;
148
+ } = {},
149
+ ): Promise<any> {
150
+ const c0 = this._a(poolKey[0]);
151
+ const c1 = this._a(poolKey[1]);
152
+ const approve = opts.approve ?? true;
153
+ const value = approve ? await this._approveAndValue([[c0, amount0], [c1, amount1]]) : 0n;
154
+ const key = [c0, c1, poolKey[2], poolKey[3], this._a(poolKey[4])];
155
+ const p = [
156
+ dexId, key, tickLower, tickUpper, liquidity,
157
+ amount0Max, amount1Max, amount0, amount1,
158
+ opts.lockDays ?? 0, this._a(opts.referral ?? ZERO), opts.deadline ?? this.deadline(),
159
+ ];
160
+ return this._c.send(this._liq.getFunction("addLiquidityV4"), [p], { value, ...(opts.tx ?? {}) });
161
+ }
162
+
163
+ async addSlipstream(
164
+ dexId: number,
165
+ token0: string,
166
+ token1: string,
167
+ tickSpacing: number,
168
+ tickLower: number,
169
+ tickUpper: number,
170
+ amount0: bigint,
171
+ amount1: bigint,
172
+ opts: {
173
+ amount0Min?: bigint;
174
+ amount1Min?: bigint;
175
+ referral?: string;
176
+ lockDays?: number;
177
+ deadline?: number | null;
178
+ sqrtPriceX96?: bigint;
179
+ approve?: boolean;
180
+ tx?: Tx;
181
+ } = {},
182
+ ): Promise<any> {
183
+ token0 = this._a(token0);
184
+ token1 = this._a(token1);
185
+ const approve = opts.approve ?? true;
186
+ const value = approve ? await this._approveAndValue([[token0, amount0], [token1, amount1]]) : 0n;
187
+ const p = [
188
+ dexId, token0, token1, tickSpacing, tickLower, tickUpper,
189
+ amount0, amount1, opts.amount0Min ?? 0n, opts.amount1Min ?? 0n, this._a(opts.referral ?? ZERO),
190
+ opts.lockDays ?? 0, opts.deadline ?? this.deadline(), opts.sqrtPriceX96 ?? 0n,
191
+ ];
192
+ return this._c.send(this._liq.getFunction("addLiquiditySlipstream"), [p], { value, ...(opts.tx ?? {}) });
193
+ }
194
+
195
+ // ------------------------------------------------------------------ //
196
+ // increase / decrease / remove
197
+ // ------------------------------------------------------------------ //
198
+ async increaseV3(
199
+ npm: string,
200
+ tokenId: bigint,
201
+ amount0: bigint,
202
+ amount1: bigint,
203
+ opts: { amount0Min?: bigint; amount1Min?: bigint; deadline?: number | null; referral?: string; tx?: Tx } = {},
204
+ ): Promise<any> {
205
+ const fn = this._liq.getFunction("increaseLiquidityV3");
206
+ return this._c.send(fn, [
207
+ this._a(npm), tokenId, amount0, amount1, opts.amount0Min ?? 0n, opts.amount1Min ?? 0n,
208
+ opts.deadline ?? this.deadline(), this._a(opts.referral ?? ZERO),
209
+ ], opts.tx ?? {});
210
+ }
211
+
212
+ async decreaseV3(
213
+ npm: string,
214
+ tokenId: bigint,
215
+ liquidity: bigint,
216
+ opts: { amount0Min?: bigint; amount1Min?: bigint; deadline?: number | null; referral?: string; tx?: Tx } = {},
217
+ ): Promise<any> {
218
+ const fn = this._liq.getFunction("decreaseLiquidityV3");
219
+ return this._c.send(fn, [
220
+ this._a(npm), tokenId, liquidity, opts.amount0Min ?? 0n, opts.amount1Min ?? 0n,
221
+ opts.deadline ?? this.deadline(), this._a(opts.referral ?? ZERO),
222
+ ], opts.tx ?? {});
223
+ }
224
+
225
+ async increaseV4(
226
+ npm: string,
227
+ tokenId: bigint,
228
+ liquidity: bigint,
229
+ amount0Max: bigint,
230
+ amount1Max: bigint,
231
+ amount0: bigint,
232
+ amount1: bigint,
233
+ opts: { deadline?: number | null; referral?: string; tx?: Tx } = {},
234
+ ): Promise<any> {
235
+ const fn = this._liq.getFunction("increaseLiquidityV4");
236
+ return this._c.send(fn, [
237
+ this._a(npm), tokenId, liquidity, amount0Max, amount1Max, amount0, amount1,
238
+ opts.deadline ?? this.deadline(), this._a(opts.referral ?? ZERO),
239
+ ], opts.tx ?? {});
240
+ }
241
+
242
+ async decreaseV4(
243
+ npm: string,
244
+ tokenId: bigint,
245
+ liquidity: bigint,
246
+ amount0Min: bigint,
247
+ amount1Min: bigint,
248
+ opts: { deadline?: number | null; referral?: string; tx?: Tx } = {},
249
+ ): Promise<any> {
250
+ const fn = this._liq.getFunction("decreaseLiquidityV4");
251
+ return this._c.send(fn, [
252
+ this._a(npm), tokenId, liquidity, amount0Min, amount1Min,
253
+ opts.deadline ?? this.deadline(), this._a(opts.referral ?? ZERO),
254
+ ], opts.tx ?? {});
255
+ }
256
+
257
+ /** Remove V2 LP. `removeLiquidityV2(dexId, tokenA, tokenB, lpAmount, …)`. */
258
+ async removeV2(
259
+ dexId: number,
260
+ tokenA: string,
261
+ tokenB: string,
262
+ liquidity: bigint,
263
+ opts: { amountAMin?: bigint; amountBMin?: bigint; deadline?: number | null; referral?: string; tx?: Tx } = {},
264
+ ): Promise<any> {
265
+ const fn = this._liq.getFunction("removeLiquidityV2");
266
+ return this._c.send(fn, [
267
+ dexId, this._a(tokenA), this._a(tokenB), liquidity,
268
+ opts.amountAMin ?? 0n, opts.amountBMin ?? 0n, opts.deadline ?? this.deadline(), this._a(opts.referral ?? ZERO),
269
+ ], opts.tx ?? {});
270
+ }
271
+
272
+ // ------------------------------------------------------------------ //
273
+ // locks
274
+ // ------------------------------------------------------------------ //
275
+ async lockV2(pair: string, amount: bigint, lockDays: number, tx: Tx = {}): Promise<any> {
276
+ return this._c.send(this._liq.getFunction("lockV2LP"), [this._a(pair), amount, lockDays], tx);
277
+ }
278
+
279
+ async lockV3(npm: string, tokenId: bigint, lockDays: number, tx: Tx = {}): Promise<any> {
280
+ return this._c.send(this._liq.getFunction("lockV3Position"), [this._a(npm), tokenId, lockDays], tx);
281
+ }
282
+
283
+ async lockV4(npm: string, tokenId: bigint, lockDays: number, tx: Tx = {}): Promise<any> {
284
+ return this._c.send(this._liq.getFunction("lockV4Position"), [this._a(npm), tokenId, lockDays], tx);
285
+ }
286
+
287
+ async unlockV2(lockKey: string, tx: Tx = {}): Promise<any> {
288
+ return this._c.send(this._liq.getFunction("unlockV2"), [lockKey], tx);
289
+ }
290
+
291
+ async unlockV3(npm: string, tokenId: bigint, tx: Tx = {}): Promise<any> {
292
+ return this._c.send(this._liq.getFunction("unlockV3"), [this._a(npm), tokenId], tx);
293
+ }
294
+
295
+ async unlockV4(npm: string, tokenId: bigint, tx: Tx = {}): Promise<any> {
296
+ return this._c.send(this._liq.getFunction("unlockV4"), [this._a(npm), tokenId], tx);
297
+ }
298
+
299
+ // ------------------------------------------------------------------ //
300
+ // claim fees / harvest
301
+ // ------------------------------------------------------------------ //
302
+ async claimFeesV3(npm: string, tokenId: bigint, recipient: string | null = null, tx: Tx = {}): Promise<any> {
303
+ recipient = recipient ?? this._c.requireAddress();
304
+ return this._c.send(this._liq.getFunction("claimFeesV3"), [this._a(npm), tokenId, this._a(recipient)], tx);
305
+ }
306
+
307
+ async claimFeesV4(npm: string, tokenId: bigint, recipient: string | null = null, tx: Tx = {}): Promise<any> {
308
+ recipient = recipient ?? this._c.requireAddress();
309
+ return this._c.send(this._liq.getFunction("claimFeesV4"), [this._a(npm), tokenId, this._a(recipient)], tx);
310
+ }
311
+
312
+ async claimFeesV3Locked(tokenId: bigint, recipient: string, outputToken: string, tx: Tx = {}): Promise<any> {
313
+ return this._c.send(
314
+ this._liq.getFunction("claimFeesV3Locked"),
315
+ [tokenId, this._a(recipient), this._a(outputToken)],
316
+ tx,
317
+ );
318
+ }
319
+
320
+ async claimFeesV4Locked(npm: string, tokenId: bigint, recipient: string, tx: Tx = {}): Promise<any> {
321
+ return this._c.send(this._liq.getFunction("claimFeesV4Locked"), [this._a(npm), tokenId, this._a(recipient)], tx);
322
+ }
323
+
324
+ /** Claim fees from many positions at once into one token. `massClaimFees`. */
325
+ async massClaimFees(npms: string[], tokenIds: bigint[], outputToken: string, tx: Tx = {}): Promise<any> {
326
+ return this._c.send(
327
+ this._liq.getFunction("massClaimFees"),
328
+ [npms.map((a) => this._a(a)), tokenIds, this._a(outputToken)],
329
+ tx,
330
+ );
331
+ }
332
+
333
+ async harvestOp(op: number, data: string, tx: Tx = {}): Promise<any> {
334
+ return this._c.send(this._liq.getFunction("harvestOp"), [op, data], tx);
335
+ }
336
+
337
+ async claimBatchFees(tokens: string[], tx: Tx = {}): Promise<any> {
338
+ return this._c.send(this._liq.getFunction("claimBatchFees"), [tokens.map((a) => this._a(a))], tx);
339
+ }
340
+
341
+ async claimReferralFees(tokens: string[], tx: Tx = {}): Promise<any> {
342
+ return this._c.send(this._liq.getFunction("claimReferralFees"), [tokens.map((a) => this._a(a))], tx);
343
+ }
344
+
345
+ // ------------------------------------------------------------------ //
346
+ // reads (sidecar via liq proxy)
347
+ // ------------------------------------------------------------------ //
348
+ async positionsV2(wallet: string, pairs: string[]): Promise<V2Position[]> {
349
+ const r = await this._c.call(this._side.getFunction("getV2Positions"), [this._a(wallet), pairs.map((p) => this._a(p))]);
350
+ return [...r].map((x) => V2Position.fromRaw(x));
351
+ }
352
+
353
+ async positionsV3(wallet: string, start = 0, end = 0): Promise<V3Position[]> {
354
+ const r = await this._c.call(this._side.getFunction("getV3Positions"), [this._a(wallet), start, end]);
355
+ return [...r].map((x) => V3Position.fromRaw(x));
356
+ }
357
+
358
+ async positionsV4(wallet: string, start = 0, end = 0): Promise<V4Position[]> {
359
+ const r = await this._c.call(this._side.getFunction("getV4Positions"), [this._a(wallet), start, end]);
360
+ return [...r].map((x) => V4Position.fromRaw(x));
361
+ }
362
+
363
+ async poolStateV2(pair: string): Promise<V2PoolState> {
364
+ return V2PoolState.fromRaw(await this._c.call(this._side.getFunction("getV2PoolState"), [this._a(pair)]));
365
+ }
366
+
367
+ async poolStateV3(pool: string): Promise<V3PoolState> {
368
+ return V3PoolState.fromRaw(await this._c.call(this._side.getFunction("getV3PoolState"), [this._a(pool)]));
369
+ }
370
+
371
+ async poolStateV4(poolKey: PoolKey): Promise<V4PoolState> {
372
+ const key = [this._a(poolKey[0]), this._a(poolKey[1]), poolKey[2], poolKey[3], this._a(poolKey[4])];
373
+ return V4PoolState.fromRaw(await this._c.call(this._side.getFunction("getV4PoolState"), [key]));
374
+ }
375
+
376
+ async locks(wallet: string): Promise<Lock[]> {
377
+ const r = await this._c.call(this._side.getFunction("getLocks"), [this._a(wallet)]);
378
+ return [...r].map((x) => Lock.fromRaw(x));
379
+ }
380
+
381
+ async lockKeys(wallet: string): Promise<string[]> {
382
+ const r = await this._c.call(this._liq.getFunction("getLockKeys"), [this._a(wallet)]);
383
+ return [...r].map((x) => String(x));
384
+ }
385
+
386
+ async claimableFees(npm: string, tokenId: bigint): Promise<ClaimableFees> {
387
+ return ClaimableFees.fromRaw(await this._c.call(this._side.getFunction("getClaimableFees"), [this._a(npm), tokenId]));
388
+ }
389
+
390
+ /** USD value (1e18) of `amount` of `token`. `usdValue`. */
391
+ async usdValue(token: string, amount: bigint): Promise<bigint> {
392
+ return BigInt(await this._c.call(this._side.getFunction("usdValue"), [this._a(token), amount]));
393
+ }
394
+
395
+ // -- state / config reads --------------------------------------------- //
396
+ async isPaused(): Promise<boolean> {
397
+ return Boolean(await this._c.call(this._liq.getFunction("paused"), []));
398
+ }
399
+
400
+ async totalLockedLp(pair: string): Promise<bigint> {
401
+ return BigInt(await this._c.call(this._liq.getFunction("totalLockedLp"), [this._a(pair)]));
402
+ }
403
+
404
+ /** Current V2 lock nonce of a wallet (input to {@link removeV2}). */
405
+ async v2LockNonce(wallet: string): Promise<bigint> {
406
+ return BigInt(await this._c.call(this._liq.getFunction("v2LockNonce"), [this._a(wallet)]));
407
+ }
408
+
409
+ async priceOracle(): Promise<string> {
410
+ return String(await this._c.call(this._liq.getFunction("priceOracle"), []));
411
+ }
412
+
413
+ /** Harvest/op fee split. `getOpFee(amount) -> [fee, net]`. */
414
+ async opFee(amount: bigint): Promise<[bigint, bigint]> {
415
+ const r = await this._c.call(this._liq.getFunction("getOpFee"), [amount]);
416
+ return [BigInt(r[0]), BigInt(r[1])];
417
+ }
418
+
419
+ async minLockDays(): Promise<number> {
420
+ return Number(await this._c.call(this._liq.getFunction("MIN_LOCK_DAYS"), []));
421
+ }
422
+
423
+ async maxLocksPerOwner(): Promise<number> {
424
+ return Number(await this._c.call(this._liq.getFunction("MAX_LOCKS_PER_OWNER"), []));
425
+ }
426
+
427
+ // -- dex registry ------------------------------------------------------ //
428
+ async dexCount(version: number): Promise<number> {
429
+ const name = { 2: "v2DexCount", 3: "v3DexCount", 4: "v4DexCount" }[version];
430
+ return Number(await this._c.call(this._liq.getFunction(name!), []));
431
+ }
432
+
433
+ async dex(version: number, index: number): Promise<any[]> {
434
+ const name = { 2: "v2Dexes", 3: "v3Dexes", 4: "v4Dexes" }[version];
435
+ const r = await this._c.call(this._liq.getFunction(name!), [index]);
436
+ return [...r];
437
+ }
438
+
439
+ /** All registered DEXes for a version (name, router/factory, …, enabled). */
440
+ async dexes(version: number): Promise<any[][]> {
441
+ const n = await this.dexCount(version);
442
+ const out: any[][] = [];
443
+ for (let i = 0; i < n; i++) out.push(await this.dex(version, i));
444
+ return out;
445
+ }
446
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Pricing & token-safety reads (Lens views via the swap proxy).
3
+ *
4
+ * v2.0.2 pricing model:
5
+ *
6
+ * - {@link Prices.usd} — `getUsdPrice` = **spot-mid**, for *display*.
7
+ * - {@link Prices.usdImpact} — `getUsdPriceImpact` = **execution-aware** realised
8
+ * price, for quotes / slippage math.
9
+ * - {@link Prices.spot} — `getSpotPrice(tokenIn, tokenOut)`, raw mid between two tokens.
10
+ */
11
+
12
+ import { Contract, getAddress } from "ethers";
13
+ import type { SallyClient } from "../client.js";
14
+ import { PriceResult, TokenInfo } from "../types.js";
15
+ import { SafetyConfig } from "../safety.js";
16
+ import { ZERO } from "../token.js";
17
+
18
+ export class Prices {
19
+ private _c: SallyClient;
20
+ private _lens: Contract;
21
+
22
+ constructor(client: SallyClient) {
23
+ this._c = client;
24
+ this._lens = client.lensContract;
25
+ }
26
+
27
+ private _addr(a: string): string {
28
+ return getAddress(a);
29
+ }
30
+
31
+ // -- USD pricing ------------------------------------------------------- //
32
+ /** Spot-mid USD price (1e18) — for display. `getUsdPrice`. */
33
+ async usd(token: string): Promise<PriceResult> {
34
+ const r = await this._c.call(this._lens.getFunction("getUsdPrice"), [this._addr(token)]);
35
+ return PriceResult.fromRaw(r);
36
+ }
37
+
38
+ /** Execution-aware USD price (1e18) — for quotes. `getUsdPriceImpact`. */
39
+ async usdImpact(token: string): Promise<PriceResult> {
40
+ const r = await this._c.call(this._lens.getFunction("getUsdPriceImpact"), [this._addr(token)]);
41
+ return PriceResult.fromRaw(r);
42
+ }
43
+
44
+ /** Price denominated in WETH (1e18). `getWethPrice`. */
45
+ async weth(token: string): Promise<PriceResult> {
46
+ const r = await this._c.call(this._lens.getFunction("getWethPrice"), [this._addr(token)]);
47
+ return PriceResult.fromRaw(r);
48
+ }
49
+
50
+ /**
51
+ * Raw spot mid-price of `tokenIn` in `tokenOut` (1e18).
52
+ *
53
+ * `getSpotPrice(tokenIn, tokenOut)`.
54
+ */
55
+ async spot(tokenIn: string, tokenOut: string): Promise<bigint> {
56
+ return BigInt(
57
+ await this._c.call(this._lens.getFunction("getSpotPrice"), [this._addr(tokenIn), this._addr(tokenOut)]),
58
+ );
59
+ }
60
+
61
+ // -- USD liquidity ----------------------------------------------------- //
62
+ /**
63
+ * Aggregate USD liquidity behind a token (1e18).
64
+ *
65
+ * `version` in {2,3,4} targets a single DEX generation; `null`/`undefined` sums all.
66
+ */
67
+ async usdLiquidity(token: string, version: number | null = null): Promise<bigint> {
68
+ const a = this._addr(token);
69
+ const name = {
70
+ null: "getUsdLiquidity",
71
+ 2: "getUsdLiquidityV2",
72
+ 3: "getUsdLiquidityV3",
73
+ 4: "getUsdLiquidityV4",
74
+ }[version === null ? "null" : version];
75
+ return BigInt(await this._c.call(this._lens.getFunction(name!), [a]));
76
+ }
77
+
78
+ // -- token safety ------------------------------------------------------ //
79
+ /**
80
+ * Honeypot / buy-sell-tax round-trip probe. `getTokenInfos`.
81
+ *
82
+ * The on-chain probe only runs with `tx.origin == 0` and a native probe
83
+ * balance, so this is called with `from = 0x0` and `probeValue` attached —
84
+ * anything else returns all-zero.
85
+ */
86
+ async tokenInfo(token: string, opts: { probeValue?: bigint | null } = {}): Promise<TokenInfo> {
87
+ let probeValue = opts.probeValue ?? null;
88
+ if (probeValue === null) {
89
+ probeValue = new SafetyConfig().probeValue;
90
+ }
91
+ const r = await this._lens.getFunction("getTokenInfos").staticCall(this._addr(token), {
92
+ from: ZERO,
93
+ value: probeValue,
94
+ });
95
+ return TokenInfo.fromRaw(r);
96
+ }
97
+ }