@latchprotocol/widgets 0.1.0

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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +649 -0
  3. package/dist/adapters/binDistribution.d.ts +19 -0
  4. package/dist/adapters/binDistribution.d.ts.map +1 -0
  5. package/dist/adapters/protocol.d.ts +409 -0
  6. package/dist/adapters/protocol.d.ts.map +1 -0
  7. package/dist/adapters/sale.d.ts +142 -0
  8. package/dist/adapters/sale.d.ts.map +1 -0
  9. package/dist/adapters/viem.d.ts +89 -0
  10. package/dist/adapters/viem.d.ts.map +1 -0
  11. package/dist/callpath/constants.d.ts +218 -0
  12. package/dist/callpath/constants.d.ts.map +1 -0
  13. package/dist/callpath/launch.d.ts +1979 -0
  14. package/dist/callpath/launch.d.ts.map +1 -0
  15. package/dist/callpath/liquidity.d.ts +103 -0
  16. package/dist/callpath/liquidity.d.ts.map +1 -0
  17. package/dist/callpath/plan.d.ts +34 -0
  18. package/dist/callpath/plan.d.ts.map +1 -0
  19. package/dist/callpath/swap.d.ts +129 -0
  20. package/dist/callpath/swap.d.ts.map +1 -0
  21. package/dist/chunks/SwapWidget-DgyHAVc8.js +2404 -0
  22. package/dist/chunks/SwapWidget-DgyHAVc8.js.map +1 -0
  23. package/dist/chunks/scan-Dhu7f4Nl.js +2497 -0
  24. package/dist/chunks/scan-Dhu7f4Nl.js.map +1 -0
  25. package/dist/chunks/useLocker-D1c_NTk-.js +1613 -0
  26. package/dist/chunks/useLocker-D1c_NTk-.js.map +1 -0
  27. package/dist/components/LaunchWidget.d.ts +117 -0
  28. package/dist/components/LaunchWidget.d.ts.map +1 -0
  29. package/dist/components/LiquidityWidget.d.ts +33 -0
  30. package/dist/components/LiquidityWidget.d.ts.map +1 -0
  31. package/dist/components/LockerWidget.d.ts +51 -0
  32. package/dist/components/LockerWidget.d.ts.map +1 -0
  33. package/dist/components/LocksWidgets.d.ts +61 -0
  34. package/dist/components/LocksWidgets.d.ts.map +1 -0
  35. package/dist/components/SwapWidget.d.ts +165 -0
  36. package/dist/components/SwapWidget.d.ts.map +1 -0
  37. package/dist/components/TokenTrustPanel.d.ts +32 -0
  38. package/dist/components/TokenTrustPanel.d.ts.map +1 -0
  39. package/dist/components/lockCharts.d.ts +29 -0
  40. package/dist/components/lockCharts.d.ts.map +1 -0
  41. package/dist/components/portal.d.ts +10 -0
  42. package/dist/components/portal.d.ts.map +1 -0
  43. package/dist/components/primitives.d.ts +139 -0
  44. package/dist/components/primitives.d.ts.map +1 -0
  45. package/dist/components/swap/SwapSettings.d.ts +12 -0
  46. package/dist/components/swap/SwapSettings.d.ts.map +1 -0
  47. package/dist/components/swap/TokenSelect.d.ts +61 -0
  48. package/dist/components/swap/TokenSelect.d.ts.map +1 -0
  49. package/dist/components/swap/state.d.ts +208 -0
  50. package/dist/components/swap/state.d.ts.map +1 -0
  51. package/dist/config/chain.d.ts +163 -0
  52. package/dist/config/chain.d.ts.map +1 -0
  53. package/dist/config/integrator.d.ts +121 -0
  54. package/dist/config/integrator.d.ts.map +1 -0
  55. package/dist/context/WidgetProvider.d.ts +78 -0
  56. package/dist/context/WidgetProvider.d.ts.map +1 -0
  57. package/dist/core/clMath.d.ts +98 -0
  58. package/dist/core/clMath.d.ts.map +1 -0
  59. package/dist/core/errors.d.ts +18 -0
  60. package/dist/core/errors.d.ts.map +1 -0
  61. package/dist/core/format.d.ts +47 -0
  62. package/dist/core/format.d.ts.map +1 -0
  63. package/dist/core/liquidityGuards.d.ts +53 -0
  64. package/dist/core/liquidityGuards.d.ts.map +1 -0
  65. package/dist/core/liquidityRefresh.d.ts +35 -0
  66. package/dist/core/liquidityRefresh.d.ts.map +1 -0
  67. package/dist/core/math.d.ts +129 -0
  68. package/dist/core/math.d.ts.map +1 -0
  69. package/dist/core/pool.d.ts +33 -0
  70. package/dist/core/pool.d.ts.map +1 -0
  71. package/dist/core/tokenLists.d.ts +46 -0
  72. package/dist/core/tokenLists.d.ts.map +1 -0
  73. package/dist/embed/iframe.d.ts +185 -0
  74. package/dist/embed/iframe.d.ts.map +1 -0
  75. package/dist/embed/lockBadge.d.ts +55 -0
  76. package/dist/embed/lockBadge.d.ts.map +1 -0
  77. package/dist/embed/webComponent.d.ts +83 -0
  78. package/dist/embed/webComponent.d.ts.map +1 -0
  79. package/dist/embed.d.ts +25 -0
  80. package/dist/embed.d.ts.map +1 -0
  81. package/dist/embed.js +543 -0
  82. package/dist/embed.js.map +1 -0
  83. package/dist/headless.d.ts +60 -0
  84. package/dist/headless.d.ts.map +1 -0
  85. package/dist/headless.js +223 -0
  86. package/dist/headless.js.map +1 -0
  87. package/dist/hooks/useAsyncResource.d.ts +38 -0
  88. package/dist/hooks/useAsyncResource.d.ts.map +1 -0
  89. package/dist/hooks/useLaunch.d.ts +140 -0
  90. package/dist/hooks/useLaunch.d.ts.map +1 -0
  91. package/dist/hooks/useLiquidity.d.ts +91 -0
  92. package/dist/hooks/useLiquidity.d.ts.map +1 -0
  93. package/dist/hooks/useLocker.d.ts +77 -0
  94. package/dist/hooks/useLocker.d.ts.map +1 -0
  95. package/dist/hooks/useLocks.d.ts +33 -0
  96. package/dist/hooks/useLocks.d.ts.map +1 -0
  97. package/dist/hooks/useSwapExecute.d.ts +46 -0
  98. package/dist/hooks/useSwapExecute.d.ts.map +1 -0
  99. package/dist/hooks/useSwapQuote.d.ts +51 -0
  100. package/dist/hooks/useSwapQuote.d.ts.map +1 -0
  101. package/dist/hooks/useTokenLists.d.ts +26 -0
  102. package/dist/hooks/useTokenLists.d.ts.map +1 -0
  103. package/dist/hooks/useTokenTrust.d.ts +40 -0
  104. package/dist/hooks/useTokenTrust.d.ts.map +1 -0
  105. package/dist/hooks/useTokens.d.ts +15 -0
  106. package/dist/hooks/useTokens.d.ts.map +1 -0
  107. package/dist/index.d.ts +59 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +1052 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/latch-embed.d.ts +19 -0
  112. package/dist/latch-embed.d.ts.map +1 -0
  113. package/dist/latch-embed.js +950 -0
  114. package/dist/latch-embed.js.map +1 -0
  115. package/dist/latch-embed.mjs +13162 -0
  116. package/dist/latch-embed.mjs.map +1 -0
  117. package/dist/locker/model.d.ts +73 -0
  118. package/dist/locker/model.d.ts.map +1 -0
  119. package/dist/locks/embedModel.d.ts +22 -0
  120. package/dist/locks/embedModel.d.ts.map +1 -0
  121. package/dist/locks/fetch.d.ts +60 -0
  122. package/dist/locks/fetch.d.ts.map +1 -0
  123. package/dist/locks/model.d.ts +143 -0
  124. package/dist/locks/model.d.ts.map +1 -0
  125. package/dist/locks/scan.d.ts +25 -0
  126. package/dist/locks/scan.d.ts.map +1 -0
  127. package/dist/styles/css.d.ts +32 -0
  128. package/dist/styles/css.d.ts.map +1 -0
  129. package/dist/styles.css +895 -0
  130. package/dist/trust/model.d.ts +48 -0
  131. package/dist/trust/model.d.ts.map +1 -0
  132. package/package.json +102 -0
@@ -0,0 +1,1613 @@
1
+ import { encodeAbiParameters as A, encodeFunctionData as $, isAddressEqual as b, BaseError as J, ExecutionRevertedError as Z, decodeAbiParameters as Le, zeroAddress as Ie, parseUnits as Ae } from "viem";
2
+ import { NATIVE_CURRENCY as Ce, quoterAbiFor as Te, isDynamicLPFee as Me, BIN_LAUNCH_GUARD_HOOK_ABI as ee, readBinPoolKeyParameters as te, binRawPriceFromId as ne, poolKeyToId as oe, readCLPoolKeyParameters as Ne, LAUNCHPAD_KIT_V2_ABI as Se, getDeployment as $e, CLOCK_MODE_CALLDATA as Pe, TIMESTAMP_CLOCK_MODE as Be, readContractClock as xe, readTokenMeta as De } from "@latchprotocol/sdk";
3
+ import { B as O, b6 as F, A as C, t as j, u as G, p as Q, E as N, w as f, bj as L, P as ie, m as Oe, l as Ee, n as _e, aT as ae, W as E, a4 as Re, bu as Fe, aI as Ge, aJ as se, G as U, _ as qe, bA as Ue, X as re, ae as Ke, aN as Xe, aY as Ye, F as We, b$ as me, bF as P, b9 as He, ao as Ve, ap as je, bx as Qe, bq as ce, aj as ze, bL as Je } from "./scan-Dhu7f4Nl.js";
4
+ import { useState as he, useEffect as Ze, useRef as et, useCallback as ue, useMemo as tt } from "react";
5
+ import { describeTokenLocks as nt, describeLaunch as ot, summarizeTokenTrust as it, describeLiquidity as at, describeLpFee as st, describeProtocolFee as rt, describeCreatorTax as ye, describeRegistry as ct, formatTrustSource as ut, readTokenTrust as lt } from "@latchprotocol/sdk/trust";
6
+ import { readFeeGate as le, readChainNow as dt, readPositionLocksOf as pt, readBeneficiaryLocks as mt } from "@latchprotocol/sdk/lock";
7
+ function ht(t, e, o) {
8
+ if (t > e)
9
+ throw new RangeError(`binIdLower ${t} exceeds binIdUpper ${e}`);
10
+ const n = [];
11
+ for (let p = t; p <= e; p += 1) n.push(p);
12
+ const a = n.filter((p) => p >= o).length, i = n.filter((p) => p <= o).length, s = e, r = Math.min(o, e), l = [];
13
+ let c = 0n, d = 0n;
14
+ for (const p of n) {
15
+ const m = p >= o && a > 0 ? O / BigInt(a) : 0n, u = p <= o && i > 0 ? O / BigInt(i) : 0n, h = p === s && m > 0n ? O - c : m, y = p === r && u > 0n ? O - d : u;
16
+ c += h, d += y, l.push({ binId: p, deltaId: p - o, distributionX: h, distributionY: y });
17
+ }
18
+ return l;
19
+ }
20
+ class Et extends Error {
21
+ constructor() {
22
+ super(
23
+ "[@latchprotocol/widgets] no sale adapter is configured. Latch has no sale contract - a launch is a pool with LaunchGuardHook attached, and buying into one is a swap. Set ProtocolAdapter.sale only if you run your own sale contract."
24
+ ), this.name = "NoSaleAdapterError";
25
+ }
26
+ }
27
+ function _t(t) {
28
+ return t.sale !== void 0;
29
+ }
30
+ const yt = [
31
+ { name: "poolKey", type: "tuple", components: j },
32
+ { name: "tickLower", type: "int24" },
33
+ { name: "tickUpper", type: "int24" },
34
+ { name: "liquidity", type: "uint256" },
35
+ { name: "amount0Max", type: "uint128" },
36
+ { name: "amount1Max", type: "uint128" },
37
+ { name: "owner", type: "address" },
38
+ { name: "hookData", type: "bytes" }
39
+ ], ft = [
40
+ { name: "tokenId", type: "uint256" },
41
+ { name: "liquidity", type: "uint256" },
42
+ { name: "amount0", type: "uint128" },
43
+ { name: "amount1", type: "uint128" },
44
+ { name: "hookData", type: "bytes" }
45
+ ], fe = [
46
+ { name: "currency0", type: "address" },
47
+ { name: "currency1", type: "address" }
48
+ ], ke = [
49
+ { name: "currency0", type: "address" },
50
+ { name: "currency1", type: "address" },
51
+ { name: "recipient", type: "address" }
52
+ ], kt = [
53
+ { name: "currency", type: "address" },
54
+ { name: "to", type: "address" }
55
+ ];
56
+ function be() {
57
+ return [
58
+ C.SWEEP,
59
+ A(kt, [Ce, Q]),
60
+ "sweep unspent native value back to the caller"
61
+ ];
62
+ }
63
+ const bt = [
64
+ {
65
+ name: "params",
66
+ type: "tuple",
67
+ components: [
68
+ { name: "poolKey", type: "tuple", components: j },
69
+ { name: "amount0", type: "uint128" },
70
+ { name: "amount1", type: "uint128" },
71
+ { name: "amount0Max", type: "uint128" },
72
+ { name: "amount1Max", type: "uint128" },
73
+ { name: "activeIdDesired", type: "uint256" },
74
+ { name: "idSlippage", type: "uint256" },
75
+ { name: "deltaIds", type: "int256[]" },
76
+ { name: "distributionX", type: "uint256[]" },
77
+ { name: "distributionY", type: "uint256[]" },
78
+ { name: "minLiquidities", type: "uint256[]" },
79
+ { name: "to", type: "address" },
80
+ { name: "hookData", type: "bytes" }
81
+ ]
82
+ }
83
+ ], wt = [
84
+ {
85
+ name: "params",
86
+ type: "tuple",
87
+ components: [
88
+ { name: "poolKey", type: "tuple", components: j },
89
+ { name: "amount0Min", type: "uint128" },
90
+ { name: "amount1Min", type: "uint128" },
91
+ { name: "ids", type: "uint256[]" },
92
+ { name: "amounts", type: "uint256[]" },
93
+ { name: "from", type: "address" },
94
+ { name: "hookData", type: "bytes" }
95
+ ]
96
+ }
97
+ ];
98
+ function z(t) {
99
+ return {
100
+ currency0: t.currency0,
101
+ currency1: t.currency1,
102
+ hooks: t.hooks,
103
+ poolManager: t.poolManager,
104
+ fee: t.fee,
105
+ parameters: t.parameters
106
+ };
107
+ }
108
+ function gt(t) {
109
+ if (At(t.tickLower, t.tickUpper), t.liquidity <= 0n)
110
+ throw new RangeError(`[@latchprotocol/widgets] liquidity must be positive: ${t.liquidity}`);
111
+ const e = F().add(
112
+ C.CL_MINT_POSITION,
113
+ A(yt, [
114
+ z(t.poolKey),
115
+ t.tickLower,
116
+ t.tickUpper,
117
+ t.liquidity,
118
+ t.amount0Max,
119
+ t.amount1Max,
120
+ t.owner,
121
+ t.hookData ?? "0x"
122
+ ]),
123
+ `mint CL position [${t.tickLower}, ${t.tickUpper}]`
124
+ ).add(
125
+ C.SETTLE_PAIR,
126
+ A(fe, [t.poolKey.currency0, t.poolKey.currency1]),
127
+ "settle both currencies from the caller"
128
+ );
129
+ return (t.value ?? 0n) > 0n && e.add(...be()), {
130
+ to: t.positionManager,
131
+ data: $({
132
+ abi: G,
133
+ functionName: "modifyLiquidities",
134
+ args: [e.encode(), t.deadline]
135
+ }),
136
+ value: t.value ?? 0n,
137
+ planTrace: e.describe()
138
+ };
139
+ }
140
+ function vt(t) {
141
+ if (t.liquidity <= 0n)
142
+ throw new RangeError(
143
+ `[@latchprotocol/widgets] liquidity to remove must be positive: ${t.liquidity}`
144
+ );
145
+ const e = t.recipient === t.owner ? Q : t.recipient, o = F().add(
146
+ C.CL_DECREASE_LIQUIDITY,
147
+ A(ft, [
148
+ t.tokenId,
149
+ t.liquidity,
150
+ t.amount0Min,
151
+ t.amount1Min,
152
+ t.hookData ?? "0x"
153
+ ]),
154
+ `decrease CL position #${t.tokenId} by ${t.liquidity}`
155
+ ).add(
156
+ C.TAKE_PAIR,
157
+ A(ke, [
158
+ t.poolKey.currency0,
159
+ t.poolKey.currency1,
160
+ e
161
+ ]),
162
+ "take both currencies to the recipient"
163
+ );
164
+ return {
165
+ to: t.positionManager,
166
+ data: $({
167
+ abi: G,
168
+ functionName: "modifyLiquidities",
169
+ args: [o.encode(), t.deadline]
170
+ }),
171
+ value: 0n,
172
+ planTrace: o.describe()
173
+ };
174
+ }
175
+ function Lt(t) {
176
+ const e = t.deltaIds.length;
177
+ if (e === 0)
178
+ throw new RangeError("[@latchprotocol/widgets] a bin mint must target at least one bin");
179
+ if (t.distributionX.length !== e || t.distributionY.length !== e)
180
+ throw new RangeError(
181
+ "[@latchprotocol/widgets] deltaIds, distributionX and distributionY must be the same length"
182
+ );
183
+ if (!Number.isInteger(t.activeIdDesired) || t.activeIdDesired < 0)
184
+ throw new RangeError(
185
+ `[@latchprotocol/widgets] activeIdDesired must be a non-negative integer: ${t.activeIdDesired}`
186
+ );
187
+ const o = F().add(
188
+ C.BIN_ADD_LIQUIDITY,
189
+ A(bt, [
190
+ {
191
+ poolKey: z(t.poolKey),
192
+ amount0: t.amount0,
193
+ amount1: t.amount1,
194
+ amount0Max: t.amount0Max,
195
+ amount1Max: t.amount1Max,
196
+ activeIdDesired: BigInt(t.activeIdDesired),
197
+ idSlippage: BigInt(t.idSlippage),
198
+ deltaIds: t.deltaIds.map((n) => BigInt(n)),
199
+ distributionX: [...t.distributionX],
200
+ distributionY: [...t.distributionY],
201
+ // One entry per bin. Zero means "accept whatever the pool mints"; the
202
+ // real slippage guard for a bin mint is idSlippage plus amountNMax.
203
+ minLiquidities: t.deltaIds.map(() => 0n),
204
+ to: t.to,
205
+ hookData: t.hookData ?? "0x"
206
+ }
207
+ ]),
208
+ `add bin liquidity across ${e} bins around id ${t.activeIdDesired}`
209
+ ).add(
210
+ C.SETTLE_PAIR,
211
+ A(fe, [t.poolKey.currency0, t.poolKey.currency1]),
212
+ "settle both currencies from the caller"
213
+ );
214
+ return (t.value ?? 0n) > 0n && o.add(...be()), {
215
+ to: t.positionManager,
216
+ data: $({
217
+ abi: G,
218
+ functionName: "modifyLiquidities",
219
+ args: [o.encode(), t.deadline]
220
+ }),
221
+ value: t.value ?? 0n,
222
+ planTrace: o.describe()
223
+ };
224
+ }
225
+ function It(t) {
226
+ if (t.ids.length === 0)
227
+ throw new RangeError("[@latchprotocol/widgets] a bin burn must target at least one bin");
228
+ if (t.ids.length !== t.amounts.length)
229
+ throw new RangeError("[@latchprotocol/widgets] ids and amounts must be the same length");
230
+ const e = t.recipient === t.from ? Q : t.recipient, o = F().add(
231
+ C.BIN_REMOVE_LIQUIDITY,
232
+ A(wt, [
233
+ {
234
+ poolKey: z(t.poolKey),
235
+ amount0Min: t.amount0Min,
236
+ amount1Min: t.amount1Min,
237
+ ids: t.ids.map((n) => BigInt(n)),
238
+ amounts: [...t.amounts],
239
+ from: t.from,
240
+ hookData: t.hookData ?? "0x"
241
+ }
242
+ ]),
243
+ `remove bin liquidity from ${t.ids.length} bins`
244
+ ).add(
245
+ C.TAKE_PAIR,
246
+ A(ke, [
247
+ t.poolKey.currency0,
248
+ t.poolKey.currency1,
249
+ e
250
+ ]),
251
+ "take both currencies to the recipient"
252
+ );
253
+ return {
254
+ to: t.positionManager,
255
+ data: $({
256
+ abi: G,
257
+ functionName: "modifyLiquidities",
258
+ args: [o.encode(), t.deadline]
259
+ }),
260
+ value: 0n,
261
+ planTrace: o.describe()
262
+ };
263
+ }
264
+ function At(t, e) {
265
+ if (!Number.isInteger(t) || !Number.isInteger(e))
266
+ throw new RangeError(
267
+ `[@latchprotocol/widgets] ticks must be integers: [${t}, ${e}]`
268
+ );
269
+ if (t >= e)
270
+ throw new RangeError(
271
+ `[@latchprotocol/widgets] tickLower must be below tickUpper: [${t}, ${e}]`
272
+ );
273
+ }
274
+ const K = [
275
+ {
276
+ type: "function",
277
+ name: "getSlot0",
278
+ stateMutability: "view",
279
+ inputs: [{ name: "id", type: "bytes32" }],
280
+ outputs: [
281
+ { name: "sqrtPriceX96", type: "uint160" },
282
+ { name: "tick", type: "int24" },
283
+ { name: "protocolFee", type: "uint24" },
284
+ { name: "lpFee", type: "uint24" }
285
+ ]
286
+ }
287
+ ], X = [
288
+ {
289
+ type: "function",
290
+ name: "getSlot0",
291
+ stateMutability: "view",
292
+ inputs: [{ name: "id", type: "bytes32" }],
293
+ outputs: [
294
+ { name: "activeId", type: "uint24" },
295
+ { name: "protocolFee", type: "uint24" },
296
+ { name: "lpFee", type: "uint24" }
297
+ ]
298
+ }
299
+ ], de = 2n ** 192n, _ = [
300
+ {
301
+ type: "function",
302
+ name: "getLiquidity",
303
+ stateMutability: "view",
304
+ inputs: [{ name: "id", type: "bytes32" }],
305
+ outputs: [{ name: "liquidity", type: "uint128" }]
306
+ },
307
+ {
308
+ type: "function",
309
+ name: "getFeeGrowthGlobals",
310
+ stateMutability: "view",
311
+ inputs: [{ name: "id", type: "bytes32" }],
312
+ outputs: [
313
+ { name: "feeGrowthGlobal0x128", type: "uint256" },
314
+ { name: "feeGrowthGlobal1x128", type: "uint256" }
315
+ ]
316
+ },
317
+ {
318
+ type: "function",
319
+ name: "getPoolTickInfo",
320
+ stateMutability: "view",
321
+ inputs: [
322
+ { name: "id", type: "bytes32" },
323
+ { name: "tick", type: "int24" }
324
+ ],
325
+ outputs: [
326
+ {
327
+ name: "info",
328
+ type: "tuple",
329
+ components: [
330
+ { name: "liquidityGross", type: "uint128" },
331
+ { name: "liquidityNet", type: "int128" },
332
+ { name: "feeGrowthOutside0X128", type: "uint256" },
333
+ { name: "feeGrowthOutside1X128", type: "uint256" }
334
+ ]
335
+ }
336
+ ]
337
+ }
338
+ ], pe = [
339
+ {
340
+ type: "function",
341
+ name: "getBin",
342
+ stateMutability: "view",
343
+ inputs: [
344
+ { name: "id", type: "bytes32" },
345
+ { name: "binId", type: "uint24" }
346
+ ],
347
+ outputs: [
348
+ { name: "binReserveX", type: "uint128" },
349
+ { name: "binReserveY", type: "uint128" },
350
+ { name: "binLiquidity", type: "uint256" },
351
+ { name: "totalShares", type: "uint256" }
352
+ ]
353
+ }
354
+ ], we = {
355
+ name: "poolKey",
356
+ type: "tuple",
357
+ components: [
358
+ { name: "currency0", type: "address" },
359
+ { name: "currency1", type: "address" },
360
+ { name: "hooks", type: "address" },
361
+ { name: "poolManager", type: "address" },
362
+ { name: "fee", type: "uint24" },
363
+ { name: "parameters", type: "bytes32" }
364
+ ]
365
+ }, Y = [
366
+ {
367
+ type: "function",
368
+ name: "ownerOf",
369
+ stateMutability: "view",
370
+ inputs: [{ name: "id", type: "uint256" }],
371
+ outputs: [{ name: "owner", type: "address" }]
372
+ },
373
+ {
374
+ type: "function",
375
+ name: "positions",
376
+ stateMutability: "view",
377
+ inputs: [{ name: "tokenId", type: "uint256" }],
378
+ outputs: [
379
+ we,
380
+ { name: "tickLower", type: "int24" },
381
+ { name: "tickUpper", type: "int24" },
382
+ { name: "liquidity", type: "uint128" },
383
+ { name: "feeGrowthInside0LastX128", type: "uint256" },
384
+ { name: "feeGrowthInside1LastX128", type: "uint256" },
385
+ { name: "subscriber", type: "address" }
386
+ ]
387
+ },
388
+ {
389
+ type: "event",
390
+ name: "Transfer",
391
+ inputs: [
392
+ { name: "from", type: "address", indexed: !0 },
393
+ { name: "to", type: "address", indexed: !0 },
394
+ { name: "id", type: "uint256", indexed: !0 }
395
+ ]
396
+ }
397
+ ], W = [
398
+ {
399
+ type: "function",
400
+ name: "positions",
401
+ stateMutability: "view",
402
+ inputs: [{ name: "tokenId", type: "uint256" }],
403
+ outputs: [we, { name: "binId", type: "uint24" }]
404
+ },
405
+ {
406
+ type: "function",
407
+ name: "balanceOf",
408
+ stateMutability: "view",
409
+ inputs: [
410
+ { name: "owner", type: "address" },
411
+ { name: "id", type: "uint256" }
412
+ ],
413
+ outputs: [{ name: "balance", type: "uint256" }]
414
+ },
415
+ {
416
+ type: "event",
417
+ name: "TransferBatch",
418
+ inputs: [
419
+ { name: "sender", type: "address", indexed: !0 },
420
+ { name: "from", type: "address", indexed: !0 },
421
+ { name: "to", type: "address", indexed: !0 },
422
+ { name: "ids", type: "uint256[]", indexed: !1 },
423
+ { name: "amounts", type: "uint256[]", indexed: !1 }
424
+ ]
425
+ }
426
+ ], S = "0x0000000000000000000000000000000000000000";
427
+ class Ct {
428
+ kind = "viem";
429
+ isMock = !1;
430
+ chain;
431
+ #t;
432
+ constructor(e) {
433
+ this.#t = e, this.chain = e.chain;
434
+ }
435
+ get #e() {
436
+ return this.#t.publicClient;
437
+ }
438
+ get #n() {
439
+ return this.#t.overrides ?? {};
440
+ }
441
+ async getAccount() {
442
+ const e = this.#t.wallet;
443
+ return e === void 0 ? null : e.getAccount();
444
+ }
445
+ async listTokens() {
446
+ return this.#t.tokens;
447
+ }
448
+ async getToken(e) {
449
+ const o = this.#t.tokens.find((s) => b(s.address, e));
450
+ if (o !== void 0) return o;
451
+ if (b(e, S))
452
+ return {
453
+ address: S,
454
+ symbol: this.chain.nativeCurrency.symbol,
455
+ name: this.chain.nativeCurrency.name,
456
+ decimals: this.chain.nativeCurrency.decimals,
457
+ isNative: !0
458
+ };
459
+ const [n, a, i] = await Promise.all([
460
+ this.#e.readContract({ address: e, abi: N, functionName: "symbol" }),
461
+ this.#e.readContract({ address: e, abi: N, functionName: "name" }),
462
+ this.#e.readContract({ address: e, abi: N, functionName: "decimals" })
463
+ ]);
464
+ return { address: e, symbol: n, name: a, decimals: Number(i) };
465
+ }
466
+ async getBalance(e, o) {
467
+ return e.isNative === !0 || b(e.address, S) ? this.#e.getBalance({ address: o }) : this.#e.readContract({
468
+ address: e.address,
469
+ abi: N,
470
+ functionName: "balanceOf",
471
+ args: [o]
472
+ });
473
+ }
474
+ async listPools() {
475
+ return this.#t.pools;
476
+ }
477
+ /**
478
+ * The pool's live state from its manager's `getSlot0` (plus `getLiquidity`
479
+ * for a CL pool). An uninitialised pool answers a zero price, which is
480
+ * reported as an error rather than as tick 0.
481
+ */
482
+ async getPoolState(e) {
483
+ const o = this.#n.getPoolState;
484
+ if (o !== void 0) return o(e);
485
+ if (e.poolType === "CL") {
486
+ const [[a, i], s] = await Promise.all([
487
+ this.#e.readContract({ address: e.key.poolManager, abi: K, functionName: "getSlot0", args: [e.id] }),
488
+ this.#e.readContract({ address: e.key.poolManager, abi: _, functionName: "getLiquidity", args: [e.id] })
489
+ ]);
490
+ if (a === 0n)
491
+ throw new f("getPoolState", `pool ${e.id} is not initialised on ${e.key.poolManager}`);
492
+ return { poolId: e.id, poolType: "CL", currentTick: i, sqrtPriceX96: a, liquidity: s, source: "live" };
493
+ }
494
+ const [n] = await this.#e.readContract({ address: e.key.poolManager, abi: X, functionName: "getSlot0", args: [e.id] });
495
+ if (n === 0)
496
+ throw new f("getPoolState", `pool ${e.id} is not initialised on ${e.key.poolManager}`);
497
+ return { poolId: e.id, poolType: "BIN", activeId: n, source: "live" };
498
+ }
499
+ /**
500
+ * The two allowances `spender` needs before it can pull `token` through
501
+ * Permit2: ERC-20 to Permit2, then Permit2 to the spender. The spender is
502
+ * the router for a swap (the default) and a position manager for a
503
+ * liquidity add; the liquidity hooks pass it, because an allowance to the
504
+ * router does nothing for a mint.
505
+ */
506
+ async getApprovalRequirements(e, o, n, a) {
507
+ if (e.isNative === !0 || b(e.address, S)) return [];
508
+ const i = L(this.chain, "permit2", "pull the input token for a swap"), s = a ?? L(this.chain, "universalRouter", "execute a swap"), r = [], l = await this.#e.readContract({
509
+ address: e.address,
510
+ abi: N,
511
+ functionName: "allowance",
512
+ args: [o, i]
513
+ });
514
+ l < n && r.push({
515
+ kind: "erc20-to-permit2",
516
+ token: e,
517
+ spender: i,
518
+ current: l,
519
+ required: n
520
+ });
521
+ const [c, d] = await this.#e.readContract({
522
+ address: i,
523
+ abi: ie,
524
+ functionName: "allowance",
525
+ args: [o, e.address, s]
526
+ }), p = BigInt(Math.floor(Date.now() / 1e3)), m = BigInt(d) !== 0n && BigInt(d) <= p;
527
+ return (BigInt(c) < n || m) && r.push({
528
+ kind: "permit2-to-router",
529
+ token: e,
530
+ spender: s,
531
+ current: m ? 0n : BigInt(c),
532
+ required: n
533
+ }), r;
534
+ }
535
+ async buildApproval(e) {
536
+ return e.kind === "erc20-to-permit2" ? {
537
+ to: e.token.address,
538
+ data: $({
539
+ abi: N,
540
+ functionName: "approve",
541
+ args: [e.spender, Oe]
542
+ }),
543
+ value: 0n,
544
+ summary: `Approve ${e.token.symbol} for Permit2`,
545
+ source: "live"
546
+ } : {
547
+ to: L(this.chain, "permit2", "approve the router through Permit2"),
548
+ data: $({
549
+ abi: ie,
550
+ functionName: "approve",
551
+ args: [e.token.address, e.spender, Ee, Number(_e)]
552
+ }),
553
+ value: 0n,
554
+ summary: `Approve ${e.spender} to spend ${e.token.symbol} via Permit2`,
555
+ source: "live"
556
+ };
557
+ }
558
+ /**
559
+ * Quotes an exact-input swap.
560
+ *
561
+ * With `overrides.quoteSwap` the host answers. Otherwise every configured
562
+ * pool holding both tokens is quoted DIRECTLY against the deployed quoter for
563
+ * its type (`contracts.quoter` for CL, `contracts.binQuoter` for Bin) and the
564
+ * best output wins. No multi-hop routing: a route this adapter did not quote
565
+ * is a route it cannot vouch for. Throws when no quoter can answer.
566
+ *
567
+ * The LP fee shown beside the quote is the pool's static fee, or, for a
568
+ * dynamic-fee pool whose hook is a launch guard, the guard's `currentFee`.
569
+ * Any other dynamic pool is reported `lpFeeUnknown`, which the widget renders
570
+ * as "dynamic" rather than as a rate it did not read.
571
+ */
572
+ async quoteSwap(e) {
573
+ const o = this.#n.quoteSwap;
574
+ if (o !== void 0) return o(e, this.#t.pools);
575
+ const n = this.chain.contracts, a = this.#t.pools.filter(
576
+ (u) => (e.poolId === void 0 || u.id === e.poolId) && (b(u.token0.address, e.tokenIn.address) && b(u.token1.address, e.tokenOut.address) || b(u.token1.address, e.tokenIn.address) && b(u.token0.address, e.tokenOut.address))
577
+ );
578
+ if (a.length === 0)
579
+ throw new f(
580
+ "quoteSwap",
581
+ e.poolId !== void 0 ? `pool ${e.poolId} is not a configured pool holding both ${e.tokenIn.symbol} and ${e.tokenOut.symbol}.` : `no configured pool holds both ${e.tokenIn.symbol} and ${e.tokenOut.symbol}. This adapter quotes direct pools only; supply \`overrides.quoteSwap\` for multi-hop routes.`
582
+ );
583
+ const i = a.filter(
584
+ (u) => u.poolType === "CL" ? n.quoter !== void 0 : n.binQuoter !== void 0
585
+ );
586
+ if (i.length === 0)
587
+ throw new f(
588
+ "quoteSwap",
589
+ `a pool for this pair exists but no quoter is configured for its type (${a.map((u) => u.poolType).join(", ")}). Set \`contracts.quoter\` (CL) / \`contracts.binQuoter\` (Bin), or supply \`overrides.quoteSwap\`. This adapter will not estimate a price it cannot verify.`
590
+ );
591
+ const s = await Promise.all(
592
+ i.map(async (u) => {
593
+ const h = u.poolType === "CL" ? n.quoter : n.binQuoter;
594
+ try {
595
+ const { result: y } = await this.#e.simulateContract({
596
+ address: h,
597
+ abi: Te(u.poolType),
598
+ functionName: "quoteExactInputSingle",
599
+ args: [
600
+ {
601
+ poolKey: u.key,
602
+ zeroForOne: b(u.key.currency0, e.tokenIn.address),
603
+ exactAmount: e.amountIn,
604
+ hookData: "0x"
605
+ }
606
+ ]
607
+ }), [w, k] = y;
608
+ return { pool: u, amountOut: w, gasEstimate: k, error: null };
609
+ } catch (y) {
610
+ return { pool: u, amountOut: 0n, gasEstimate: 0n, error: y instanceof Error ? y : new Error(String(y)) };
611
+ }
612
+ })
613
+ ), r = s.filter((u) => u.error === null);
614
+ if (r.length === 0) {
615
+ const u = s[0]?.error;
616
+ throw new f(
617
+ "quoteSwap",
618
+ `every direct pool for this pair failed to quote${u == null ? "" : `: ${u.message}`}`
619
+ );
620
+ }
621
+ const l = r.reduce((u, h) => h.amountOut > u.amountOut ? h : u), c = l.pool;
622
+ let d = c.lpFeePips, p = !1;
623
+ if (Me(c.lpFeePips)) {
624
+ const u = await this.#c(c);
625
+ u === null ? (d = 0, p = !0) : d = u;
626
+ }
627
+ const m = p ? null : await this.#u(c, e.tokenIn.address, e.amountIn, d);
628
+ return {
629
+ route: [
630
+ {
631
+ poolId: c.id,
632
+ poolType: c.poolType,
633
+ tokenIn: e.tokenIn,
634
+ tokenOut: e.tokenOut,
635
+ lpFeePips: d,
636
+ hooks: c.hooks
637
+ }
638
+ ],
639
+ amountIn: e.amountIn,
640
+ grossAmountOut: l.amountOut,
641
+ spotAmountOut: m,
642
+ lpFeeAmount: e.amountIn * BigInt(d) / 1000000n,
643
+ lpFeePips: d,
644
+ ...p ? { lpFeeUnknown: p } : {},
645
+ estimatedGas: l.gasEstimate,
646
+ source: "live"
647
+ };
648
+ }
649
+ /**
650
+ * `currentFee(poolId)` when the pool's hook is one of the configured launch
651
+ * guards; `null` when the hook is not a guard (the fee is then genuinely
652
+ * unreadable in advance). A guard that REVERTS `currentFee` — an unclaimed
653
+ * pool id — is also `null`. Anything else (transport failure, an unknown
654
+ * `CLOCK_MODE`) is thrown: an unreachable RPC is an error state, never a
655
+ * quote annotated "dynamic".
656
+ */
657
+ async #c(e) {
658
+ const o = this.#o(e);
659
+ if (o === null) return null;
660
+ const n = o.poolType === "CL" ? ae(await this.#r(o.hook, "CL")) : ee;
661
+ try {
662
+ const a = await this.#e.readContract({ address: o.hook, abi: n, functionName: "currentFee", args: [e.id] });
663
+ return Number(a);
664
+ } catch (a) {
665
+ if (a instanceof J && a.walk((i) => i instanceof Z) !== null)
666
+ return null;
667
+ throw a;
668
+ }
669
+ }
670
+ /** The configured launch guard this pool names, if any, with the pool type it serves. */
671
+ #o(e) {
672
+ const { launchGuardHook: o, binLaunchGuardHook: n } = this.chain.contracts;
673
+ return e.poolType === "CL" && o !== void 0 && b(e.hooks, o) ? { hook: o, poolType: "CL" } : e.poolType === "BIN" && n !== void 0 && b(e.hooks, n) ? { hook: n, poolType: "BIN" } : null;
674
+ }
675
+ /** `amountIn` priced at the pool's spot from `getSlot0`, less `lpFeePips`; `null` when the read fails. */
676
+ async #u(e, o, n, a) {
677
+ const i = b(e.key.currency0, o), s = n * BigInt(1e6 - a) / 1000000n;
678
+ try {
679
+ if (e.poolType === "CL") {
680
+ const [m] = await this.#e.readContract({ address: e.key.poolManager, abi: K, functionName: "getSlot0", args: [e.id] });
681
+ if (m === 0n) return null;
682
+ const u = m * m;
683
+ return i ? s * u / de : s * de / u;
684
+ }
685
+ const [r] = await this.#e.readContract({ address: e.key.poolManager, abi: X, functionName: "getSlot0", args: [e.id] }), { binStep: l } = te(e.key), c = ne(Number(r), l);
686
+ if (!Number.isFinite(c) || c <= 0) return null;
687
+ const d = 10n ** 18n, p = BigInt(Math.round(c * 1e18));
688
+ return p === 0n ? null : i ? s * p / d : s * d / p;
689
+ } catch {
690
+ return null;
691
+ }
692
+ }
693
+ async buildSwap(e) {
694
+ const o = L(this.chain, "universalRouter", "execute a swap"), n = await this.getAccount();
695
+ if (n === null) throw new E("build a swap");
696
+ const a = this.#l(e), i = Re({
697
+ router: o,
698
+ hops: a,
699
+ amountIn: e.amountIn,
700
+ minAmountOutGross: e.minAmountOutGross,
701
+ minAmountOutNet: e.minAmountOutNet,
702
+ expectedAmountOutGross: e.quote.grossAmountOut,
703
+ integrator: e.integrator,
704
+ recipient: e.recipient,
705
+ sender: n,
706
+ deadline: e.deadline
707
+ });
708
+ return {
709
+ to: i.to,
710
+ data: i.data,
711
+ value: i.value,
712
+ summary: `Swap ${e.tokenIn.symbol} for ${e.tokenOut.symbol}`,
713
+ ...i.integratorFee ? {
714
+ integratorFee: {
715
+ referrer: i.integratorFee.referrer,
716
+ feeBps: i.integratorFee.feeBps,
717
+ currency: i.integratorFee.currency,
718
+ expectedAmount: i.integratorFee.expectedAmount
719
+ }
720
+ } : {},
721
+ source: "live"
722
+ };
723
+ }
724
+ #l(e) {
725
+ const o = this.#n.findRoute;
726
+ if (o !== void 0)
727
+ return o(e.tokenIn, e.tokenOut, this.#t.pools);
728
+ const n = [];
729
+ for (const a of e.quote.route) {
730
+ const i = this.#t.pools.find((s) => s.id === a.poolId);
731
+ if (i === void 0)
732
+ throw new f(
733
+ "buildSwap",
734
+ `the quote routes through pool ${a.poolId}, which is not in the configured pool list`
735
+ );
736
+ n.push({
737
+ poolKey: i.key,
738
+ poolType: i.poolType,
739
+ currencyIn: a.tokenIn.address,
740
+ currencyOut: a.tokenOut.address,
741
+ ...e.hookData ? { hookData: e.hookData } : {}
742
+ });
743
+ }
744
+ return n;
745
+ }
746
+ /**
747
+ * Turns desired amounts into the liquidity the pool will mint and the
748
+ * amounts it will pull, from live state and the pool's own formulas
749
+ * (`core/clMath.ts`; `adapters/binDistribution.ts`). The amounts reported
750
+ * are what the position manager settles: an add rounds towards the pool.
751
+ */
752
+ async quoteAddLiquidity(e) {
753
+ const o = this.#n.quoteAddLiquidity;
754
+ if (o !== void 0) return o(e);
755
+ const { pool: n, range: a } = e;
756
+ if (a.type === "CL") {
757
+ if (n.poolType !== "CL")
758
+ throw new f("quoteAddLiquidity", "tick range given for a bin pool");
759
+ const h = Fe(n);
760
+ if (a.tickLower % h !== 0 || a.tickUpper % h !== 0)
761
+ throw new RangeError(
762
+ `[@latchprotocol/widgets] ticks must be multiples of the pool's spacing ${h}: [${a.tickLower}, ${a.tickUpper}]`
763
+ );
764
+ const y = await this.getPoolState(n), w = y.sqrtPriceX96, k = Ge(
765
+ w,
766
+ se(a.tickLower),
767
+ se(a.tickUpper),
768
+ e.amount0Desired,
769
+ e.amount1Desired
770
+ );
771
+ if (k === 0n)
772
+ throw new f(
773
+ "quoteAddLiquidity",
774
+ "these amounts mint no liquidity in this range: at the pool's price the range needs the other token, or the amounts are too small"
775
+ );
776
+ const T = U(w, a.tickLower, a.tickUpper, k, !0), B = y.currentTick >= a.tickLower && y.currentTick < a.tickUpper, g = y.liquidity ?? 0n, M = B ? Number(k * 10000n / (g + k)) : null;
777
+ return { pool: n, range: a, amount0: T.amount0, amount1: T.amount1, liquidity: k, shareBps: M, source: "live" };
778
+ }
779
+ if (n.poolType !== "BIN")
780
+ throw new f("quoteAddLiquidity", "bin range given for a CL pool");
781
+ const s = (await this.getPoolState(n)).activeId;
782
+ if (Math.abs(s - a.activeIdDesired) > a.idSlippage)
783
+ throw new f(
784
+ "quoteAddLiquidity",
785
+ `the active bin is ${s}, more than ${a.idSlippage} bins from the ${a.activeIdDesired} the range was built around; rebuild the range`
786
+ );
787
+ const r = ht(a.binIdLower, a.binIdUpper, a.activeIdDesired), l = r.some((h) => h.distributionX > 0n), c = r.some((h) => h.distributionY > 0n), d = l ? e.amount0Desired : 0n, p = c ? e.amount1Desired : 0n;
788
+ if (d + p === 0n)
789
+ throw new f(
790
+ "quoteAddLiquidity",
791
+ "nothing to deposit: the chosen bins take only the token whose amount is zero"
792
+ );
793
+ const m = qe(n);
794
+ let u = 0n;
795
+ for (const h of r) {
796
+ const y = d * h.distributionX / 10n ** 18n, w = p * h.distributionY / 10n ** 18n, k = ne(h.binId, m);
797
+ u += BigInt(Math.floor(Number(y) * k)) + w;
798
+ }
799
+ return { pool: n, range: a, amount0: d, amount1: p, liquidity: u, shareBps: null, binDistribution: r, source: "live" };
800
+ }
801
+ async buildAddLiquidity(e) {
802
+ if (await this.getAccount() === null) throw new E("add liquidity");
803
+ const { quote: n } = e, a = this.#d(n.pool, e.amount0Max, e.amount1Max);
804
+ if (n.range.type === "CL") {
805
+ const l = L(
806
+ this.chain,
807
+ "clPositionManager",
808
+ "mint a concentrated-liquidity position"
809
+ ), c = gt({
810
+ positionManager: l,
811
+ poolKey: n.pool.key,
812
+ tickLower: n.range.tickLower,
813
+ tickUpper: n.range.tickUpper,
814
+ liquidity: n.liquidity,
815
+ amount0Max: e.amount0Max,
816
+ amount1Max: e.amount1Max,
817
+ owner: e.recipient,
818
+ deadline: e.deadline,
819
+ value: a,
820
+ ...e.hookData ? { hookData: e.hookData } : {}
821
+ });
822
+ return {
823
+ to: c.to,
824
+ data: c.data,
825
+ value: c.value,
826
+ summary: `Add liquidity to ${n.pool.token0.symbol}/${n.pool.token1.symbol}`,
827
+ source: "live"
828
+ };
829
+ }
830
+ const i = L(
831
+ this.chain,
832
+ "binPositionManager",
833
+ "add liquidity to a bin pool"
834
+ ), s = n.binDistribution;
835
+ if (s === void 0 || s.length === 0)
836
+ throw new f(
837
+ "buildAddLiquidity",
838
+ "a bin mint needs a per-bin distribution; the quote did not supply one"
839
+ );
840
+ const r = Lt({
841
+ positionManager: i,
842
+ poolKey: n.pool.key,
843
+ amount0: n.amount0,
844
+ amount1: n.amount1,
845
+ amount0Max: e.amount0Max,
846
+ amount1Max: e.amount1Max,
847
+ activeIdDesired: n.range.activeIdDesired,
848
+ idSlippage: n.range.idSlippage,
849
+ deltaIds: s.map((l) => l.deltaId),
850
+ distributionX: s.map((l) => l.distributionX),
851
+ distributionY: s.map((l) => l.distributionY),
852
+ to: e.recipient,
853
+ deadline: e.deadline,
854
+ value: a,
855
+ ...e.hookData ? { hookData: e.hookData } : {}
856
+ });
857
+ return {
858
+ to: r.to,
859
+ data: r.data,
860
+ value: r.value,
861
+ summary: `Add liquidity to ${n.pool.token0.symbol}/${n.pool.token1.symbol}`,
862
+ source: "live"
863
+ };
864
+ }
865
+ #d(e, o, n) {
866
+ return b(e.token0.address, S) ? o : b(e.token1.address, S) ? n : 0n;
867
+ }
868
+ /**
869
+ * A holder's positions, reconstructed from position-manager logs and
870
+ * confirmed against live state. Needs `positionsFromBlock`.
871
+ *
872
+ * CL: `Transfer(to = owner)` candidates, each confirmed by `ownerOf`, then
873
+ * `positions(tokenId)` for the key, ticks and liquidity; amounts and fees
874
+ * from the pool's slot0, tick info and fee-growth globals, exactly as the
875
+ * pool would credit them. Bin: `TransferBatch(to = owner)` candidates, each
876
+ * confirmed by `balanceOf`, grouped by pool; amounts from each bin's
877
+ * reserves and share supply. A position on a pool not in the configured
878
+ * list still appears, with its tokens read off their contracts.
879
+ */
880
+ async listPositions(e, o) {
881
+ const n = this.#n.listPositions;
882
+ if (n !== void 0) return n(e, o);
883
+ const a = this.#t.positionsFromBlock;
884
+ if (a === void 0)
885
+ throw new f(
886
+ "listPositions",
887
+ "position enumeration scans the position managers' transfer logs and needs `positionsFromBlock` (the block they were deployed at) in the adapter options."
888
+ );
889
+ const i = o?.poolType, [s, r] = await Promise.all([
890
+ i === "BIN" ? Promise.resolve([]) : this.#p(e, a, o),
891
+ i === "CL" ? Promise.resolve([]) : this.#m(e, a, o)
892
+ ]);
893
+ return [...s, ...r];
894
+ }
895
+ async #p(e, o, n) {
896
+ const a = this.chain.contracts.clPositionManager;
897
+ if (a === void 0) return [];
898
+ const i = await this.#e.getLogs({
899
+ address: a,
900
+ event: Y[2],
901
+ args: { to: e },
902
+ fromBlock: o,
903
+ toBlock: "latest"
904
+ }), s = [...new Set(i.map((l) => l.args.id))], r = [];
905
+ for (const l of s) {
906
+ let c;
907
+ try {
908
+ c = await this.#e.readContract({ address: a, abi: Y, functionName: "ownerOf", args: [l] });
909
+ } catch {
910
+ continue;
911
+ }
912
+ if (!b(c, e)) continue;
913
+ const [d, p, m, u, h, y] = await this.#e.readContract({
914
+ address: a,
915
+ abi: Y,
916
+ functionName: "positions",
917
+ args: [l]
918
+ }), w = await this.#a(d, "CL", n);
919
+ if (w === null) continue;
920
+ const [[k, T], [B, g], M, q] = await Promise.all([
921
+ this.#e.readContract({ address: d.poolManager, abi: K, functionName: "getSlot0", args: [w.id] }),
922
+ this.#e.readContract({ address: d.poolManager, abi: _, functionName: "getFeeGrowthGlobals", args: [w.id] }),
923
+ this.#e.readContract({ address: d.poolManager, abi: _, functionName: "getPoolTickInfo", args: [w.id, p] }),
924
+ this.#e.readContract({ address: d.poolManager, abi: _, functionName: "getPoolTickInfo", args: [w.id, m] })
925
+ ]), D = U(k, p, m, u, !1), x = Ue({
926
+ liquidity: u,
927
+ tickLower: p,
928
+ tickUpper: m,
929
+ currentTick: T,
930
+ feeGrowthGlobal0X128: B,
931
+ feeGrowthGlobal1X128: g,
932
+ lower: M,
933
+ upper: q,
934
+ feeGrowthInside0LastX128: h,
935
+ feeGrowthInside1LastX128: y
936
+ });
937
+ r.push({
938
+ id: `cl:${l}`,
939
+ tokenId: l,
940
+ pool: w,
941
+ range: { type: "CL", tickLower: p, tickUpper: m },
942
+ liquidity: u,
943
+ amount0: D.amount0,
944
+ amount1: D.amount1,
945
+ feesOwed0: x.fees0,
946
+ feesOwed1: x.fees1,
947
+ inRange: T >= p && T < m,
948
+ source: "live"
949
+ });
950
+ }
951
+ return r;
952
+ }
953
+ async #m(e, o, n) {
954
+ const a = this.chain.contracts.binPositionManager;
955
+ if (a === void 0) return [];
956
+ const i = await this.#e.getLogs({
957
+ address: a,
958
+ event: W[2],
959
+ args: { to: e },
960
+ fromBlock: o,
961
+ toBlock: "latest"
962
+ }), s = [...new Set(i.flatMap((c) => c.args.ids ?? []))], r = /* @__PURE__ */ new Map();
963
+ for (const c of s) {
964
+ const d = await this.#e.readContract({ address: a, abi: W, functionName: "balanceOf", args: [e, c] });
965
+ if (d === 0n) continue;
966
+ const [p, m] = await this.#e.readContract({ address: a, abi: W, functionName: "positions", args: [c] }), u = oe(p), h = r.get(u) ?? { key: p, bins: [] };
967
+ h.bins.push({ binId: m, shares: d }), r.set(u, h);
968
+ }
969
+ const l = [];
970
+ for (const [c, { key: d, bins: p }] of r) {
971
+ const m = await this.#a(d, "BIN", n);
972
+ if (m === null) continue;
973
+ const [u] = await this.#e.readContract({ address: d.poolManager, abi: X, functionName: "getSlot0", args: [c] });
974
+ let h = 0n, y = 0n, w = 0n;
975
+ const k = [...p].sort((g, M) => g.binId - M.binId);
976
+ for (const g of k) {
977
+ const [M, q, , D] = await this.#e.readContract({
978
+ address: d.poolManager,
979
+ abi: pe,
980
+ functionName: "getBin",
981
+ args: [c, g.binId]
982
+ }), x = re({ shares: g.shares, totalShares: D, reserveX: M, reserveY: q });
983
+ h += x.amount0, y += x.amount1, w += g.shares;
984
+ }
985
+ const T = k[0], B = k[k.length - 1];
986
+ l.push({
987
+ id: `bin:${c}`,
988
+ pool: m,
989
+ range: { type: "BIN", activeIdDesired: u, binIdLower: T.binId, binIdUpper: B.binId, idSlippage: 0 },
990
+ liquidity: w,
991
+ amount0: h,
992
+ amount1: y,
993
+ /* Bin fees compound into the bins' reserves; they are inside amount0/amount1, never a separate figure. */
994
+ feesOwed0: 0n,
995
+ feesOwed1: 0n,
996
+ binAmounts: k.map((g) => ({ binId: g.binId, amount: g.shares })),
997
+ inRange: k.some((g) => g.binId === u),
998
+ source: "live"
999
+ });
1000
+ }
1001
+ return l;
1002
+ }
1003
+ /**
1004
+ * The `PoolInfo` for a position's key: the configured one when the pool is
1005
+ * listed, else one built from the key with both tokens read off their
1006
+ * contracts. `null` when `only` names a different pool.
1007
+ */
1008
+ async #a(e, o, n) {
1009
+ const a = oe(e);
1010
+ if (n !== void 0) return n.id.toLowerCase() === a.toLowerCase() ? n : null;
1011
+ const i = this.#t.pools.find((c) => c.id.toLowerCase() === a.toLowerCase());
1012
+ if (i !== void 0) return i;
1013
+ const [s, r] = await Promise.all([this.getToken(e.currency0), this.getToken(e.currency1)]);
1014
+ if (s === null || r === null) return null;
1015
+ const l = o === "CL" ? { tickSpacing: Ne(e).tickSpacing } : { binStep: te(e).binStep };
1016
+ return { id: a, key: e, poolType: o, token0: s, token1: r, lpFeePips: e.fee, hooks: e.hooks, ...l };
1017
+ }
1018
+ /**
1019
+ * What withdrawing `percentBps` of a position returns as PRINCIPAL, rounded
1020
+ * down as the pool rounds a burn. A CL decrease also pays out the position's
1021
+ * uncollected fees (`feesOwed0/1` on the position); they are not in these
1022
+ * figures because the position manager's minimum-out check is on the
1023
+ * principal alone, and a floor that counted fees could revert an honest
1024
+ * withdrawal.
1025
+ */
1026
+ async quoteRemoveLiquidity(e, o) {
1027
+ const n = this.#n.quoteRemoveLiquidity;
1028
+ if (n !== void 0) return n(e, o);
1029
+ if (!Number.isInteger(o) || o <= 0 || o > 1e4)
1030
+ throw new RangeError(`[@latchprotocol/widgets] percentBps must be an integer in (0, 10000]: ${o}`);
1031
+ const { pool: a } = e;
1032
+ if (e.range.type === "CL") {
1033
+ const l = await this.getPoolState(a), c = e.liquidity * BigInt(o) / 10000n, d = U(l.sqrtPriceX96, e.range.tickLower, e.range.tickUpper, c, !1);
1034
+ return { position: e, percentBps: o, amount0: d.amount0, amount1: d.amount1, source: "live" };
1035
+ }
1036
+ const i = e.binAmounts ?? [];
1037
+ let s = 0n, r = 0n;
1038
+ for (const l of i) {
1039
+ const [c, d, , p] = await this.#e.readContract({
1040
+ address: a.key.poolManager,
1041
+ abi: pe,
1042
+ functionName: "getBin",
1043
+ args: [a.id, l.binId]
1044
+ }), m = re({ shares: l.amount * BigInt(o) / 10000n, totalShares: p, reserveX: c, reserveY: d });
1045
+ s += m.amount0, r += m.amount1;
1046
+ }
1047
+ return { position: e, percentBps: o, amount0: s, amount1: r, source: "live" };
1048
+ }
1049
+ async buildRemoveLiquidity(e) {
1050
+ const o = await this.getAccount();
1051
+ if (o === null) throw new E("remove liquidity");
1052
+ const { position: n } = e;
1053
+ if (n.range.type === "CL") {
1054
+ const r = L(
1055
+ this.chain,
1056
+ "clPositionManager",
1057
+ "decrease a concentrated-liquidity position"
1058
+ );
1059
+ if (n.tokenId === void 0)
1060
+ throw new f(
1061
+ "buildRemoveLiquidity",
1062
+ "a CL position must carry its ERC-721 tokenId"
1063
+ );
1064
+ const l = n.liquidity * BigInt(e.percentBps) / 10000n, c = vt({
1065
+ positionManager: r,
1066
+ poolKey: n.pool.key,
1067
+ tokenId: n.tokenId,
1068
+ liquidity: l,
1069
+ amount0Min: e.amount0Min,
1070
+ amount1Min: e.amount1Min,
1071
+ recipient: e.recipient,
1072
+ owner: o,
1073
+ deadline: e.deadline,
1074
+ ...e.hookData ? { hookData: e.hookData } : {}
1075
+ });
1076
+ return {
1077
+ to: c.to,
1078
+ data: c.data,
1079
+ value: c.value,
1080
+ summary: `Remove ${e.percentBps / 100}% of position #${n.tokenId}`,
1081
+ source: "live"
1082
+ };
1083
+ }
1084
+ const a = L(
1085
+ this.chain,
1086
+ "binPositionManager",
1087
+ "remove liquidity from a bin pool"
1088
+ ), i = n.binAmounts;
1089
+ if (i === void 0 || i.length === 0)
1090
+ throw new f(
1091
+ "buildRemoveLiquidity",
1092
+ "a bin burn needs the per-bin share amounts held by the position"
1093
+ );
1094
+ const s = It({
1095
+ positionManager: a,
1096
+ poolKey: n.pool.key,
1097
+ amount0Min: e.amount0Min,
1098
+ amount1Min: e.amount1Min,
1099
+ ids: i.map((r) => r.binId),
1100
+ amounts: i.map(
1101
+ (r) => r.amount * BigInt(e.percentBps) / 10000n
1102
+ ),
1103
+ from: o,
1104
+ recipient: e.recipient,
1105
+ deadline: e.deadline,
1106
+ ...e.hookData ? { hookData: e.hookData } : {}
1107
+ });
1108
+ return {
1109
+ to: s.to,
1110
+ data: s.data,
1111
+ value: s.value,
1112
+ summary: `Remove ${e.percentBps / 100}% of a bin position`,
1113
+ source: "live"
1114
+ };
1115
+ }
1116
+ /**
1117
+ * Requires at least one launch guard. A chain with neither is "no launchpad
1118
+ * here", signalled the way every missing contract is: `ChainConfigError`
1119
+ * naming `launchGuardHook`, which `isLaunchpadNotConfigured` recognises.
1120
+ */
1121
+ #s(e) {
1122
+ const { launchGuardHook: o, binLaunchGuardHook: n } = this.chain.contracts;
1123
+ o === void 0 && n === void 0 && L(this.chain, "launchGuardHook", e);
1124
+ }
1125
+ /**
1126
+ * Every configured pool whose key names one of the chain's launch guards:
1127
+ * CL pools naming `launchGuardHook`, Bin pools naming `binLaunchGuardHook`.
1128
+ *
1129
+ * There is no on-chain enumeration of launches any more than there is of
1130
+ * pools, so the candidate set is the pool list the host supplied. Throws
1131
+ * `ChainConfigError` when no guard address is configured, which is how a
1132
+ * caller distinguishes "no launchpad on this chain" from "no launches yet".
1133
+ */
1134
+ async listLaunches() {
1135
+ this.#s("read a launch schedule");
1136
+ const e = this.#t.pools.filter((n) => this.#o(n) !== null);
1137
+ return (await Promise.all(e.map((n) => this.#i(n)))).filter((n) => n !== null);
1138
+ }
1139
+ async getLaunch(e) {
1140
+ this.#s("read a launch schedule");
1141
+ const o = this.#t.pools.find((n) => n.id === e);
1142
+ if (o === void 0)
1143
+ throw new f(
1144
+ "getLaunch",
1145
+ `pool ${e} is not in the configured pool list. The singleton has no pool enumeration, so the widget can only read pools the host declared.`
1146
+ );
1147
+ return this.#o(o) === null ? null : this.#i(o);
1148
+ }
1149
+ /**
1150
+ * The pools a `LaunchpadKitV2` launch opened for `token`, read from the kit's
1151
+ * `legsOf(token)` and then from the guards, in leg order.
1152
+ *
1153
+ * Every leg's pool must be in the host's pool list — the kit knows the ids,
1154
+ * not the keys, and a pool the host has not declared cannot be quoted or
1155
+ * swapped through anyway. A missing one is an error naming the id, not a
1156
+ * shorter list.
1157
+ */
1158
+ async getLaunchesForToken(e) {
1159
+ const o = L(this.chain, "launchpadKitV2", "look a launch up by its token"), n = await this.#e.readContract({
1160
+ address: o,
1161
+ abi: Se,
1162
+ functionName: "legsOf",
1163
+ args: [e]
1164
+ });
1165
+ if (n.length === 0) return [];
1166
+ const a = n.filter((r) => this.#t.pools.every((l) => l.id !== r));
1167
+ if (a.length > 0)
1168
+ throw new f(
1169
+ "getLaunchesForToken",
1170
+ `the kit lists ${n.length} pool(s) for ${e} but ${a.length} of them (${a.join(", ")}) are not in the configured pool list. Declare them (the pool manager's Initialize log carries the key) so the widget can read and route through them.`
1171
+ );
1172
+ const i = n.filter((r) => {
1173
+ const l = this.#t.pools.find((c) => c.id === r);
1174
+ return this.#o(l) === null;
1175
+ });
1176
+ if (i.length > 0)
1177
+ throw new f(
1178
+ "getLaunchesForToken",
1179
+ `${i.length} of the kit's pools for ${e} (${i.join(", ")}) name a launch guard this chain config does not declare. Set \`contracts.launchGuardHook\` (CL) and \`contracts.binLaunchGuardHook\` (Bin) to the kit's guards; a launch cannot be shown with a leg missing.`
1180
+ );
1181
+ return await Promise.all(
1182
+ n.map(async (r) => {
1183
+ const l = this.#t.pools.find((d) => d.id === r), c = await this.#i(l);
1184
+ if (c === null)
1185
+ throw new f(
1186
+ "getLaunchesForToken",
1187
+ `the kit lists pool ${r} for ${e} but its guard has no launch record for it`
1188
+ );
1189
+ return c;
1190
+ })
1191
+ );
1192
+ }
1193
+ /**
1194
+ * Which generation a launch hook is, by configuration first, then the SDK
1195
+ * address book, then the hook's own `CLOCK_MODE()` (a revert means the
1196
+ * block-numbered build). A transport failure throws; it is never a revert.
1197
+ */
1198
+ async #r(e, o = "CL") {
1199
+ if (o === "CL") {
1200
+ const i = this.chain.contracts.launchGuardHookClock;
1201
+ if (i !== void 0) return i;
1202
+ }
1203
+ const n = $e(this.chain.chainId);
1204
+ if (o === "CL" && n?.launchGuardHook && b(n.launchGuardHook, e)) {
1205
+ const i = n.durationClocks.launchGuardHook;
1206
+ if (i !== null) return i;
1207
+ }
1208
+ const a = n?.launchpadV2;
1209
+ if (a !== void 0) {
1210
+ const i = o === "CL" ? a.clLaunchGuardHook : a.binLaunchGuardHook;
1211
+ if (i !== null && b(i, e)) return "timestamp";
1212
+ }
1213
+ try {
1214
+ const { data: i } = await this.#e.call({ to: e, data: Pe });
1215
+ if (i === void 0 || i === "0x") return "contract-block";
1216
+ const [s] = Le([{ type: "string" }], i);
1217
+ if (s === Be) return "timestamp";
1218
+ throw new f("getLaunch", `hook ${e} reports an unknown CLOCK_MODE "${s}"`);
1219
+ } catch (i) {
1220
+ if (i instanceof J && i.walk((s) => s instanceof Z) !== null)
1221
+ return "contract-block";
1222
+ throw i;
1223
+ }
1224
+ }
1225
+ async #i(e) {
1226
+ const o = this.#o(e);
1227
+ if (o === null) return null;
1228
+ const n = o.hook, a = await this.#r(n, o.poolType);
1229
+ if (o.poolType === "BIN" && a !== "timestamp")
1230
+ throw new f(
1231
+ "getLaunch",
1232
+ `BinLaunchGuardHook ${n} answers as a block-numbered build; no such build exists, so this is not a Bin launch guard.`
1233
+ );
1234
+ const i = o.poolType === "CL" ? ae(a) : ee, s = await this.#e.readContract({
1235
+ address: n,
1236
+ abi: i,
1237
+ functionName: "getLaunch",
1238
+ args: [e.id]
1239
+ }), r = Ke(s, a);
1240
+ if (!Xe(r)) return null;
1241
+ const [l, c] = await Promise.all([
1242
+ this.#e.readContract({
1243
+ address: n,
1244
+ abi: i,
1245
+ functionName: "currentFee",
1246
+ args: [e.id]
1247
+ }),
1248
+ /* "Now" on the HOOK's clock. The timestamp build compares with
1249
+ block.timestamp. The block-numbered build compares with the EVM's
1250
+ block.number, which on an Arbitrum chain (Robinhood, 4663) is
1251
+ Ethereum's block number while the RPC head is the L2 block; against
1252
+ the RPC head every unopened launch rendered as settled. */
1253
+ xe(this.#e, this.chain.chainId)
1254
+ ]), d = a === "timestamp" ? c.timestamp : c.contractBlockNumber, [p, m] = r.launchTokenIsCurrency0 ? [e.token0, e.token1] : [e.token1, e.token0];
1255
+ return {
1256
+ poolId: e.id,
1257
+ pool: e,
1258
+ hook: n,
1259
+ launchToken: p,
1260
+ quoteToken: m,
1261
+ guard: r,
1262
+ currentFeePips: Number(l),
1263
+ readAt: d,
1264
+ source: "live"
1265
+ };
1266
+ }
1267
+ async sendTransaction(e) {
1268
+ const o = this.#t.wallet;
1269
+ if (o === void 0) throw new E("send a transaction");
1270
+ return o.sendTransaction({
1271
+ to: e.to,
1272
+ data: e.data,
1273
+ value: e.value
1274
+ });
1275
+ }
1276
+ /**
1277
+ * The clock the next block will carry, as closely as the RPC can say: the
1278
+ * later of the PENDING block's timestamp (anvil and geth-style nodes compute
1279
+ * the next block's; an RPC without one refuses or echoes the latest) and the
1280
+ * latest block's. See `nextBlockClock` for why the pending read matters.
1281
+ */
1282
+ async getBlockTimestamp() {
1283
+ const [e, o] = await Promise.allSettled([
1284
+ this.#e.getBlock({ blockTag: "pending" }),
1285
+ this.#e.getBlock({ blockTag: "latest" })
1286
+ ]), n = Ye(
1287
+ e.status === "fulfilled" ? e.value.timestamp : null,
1288
+ o.status === "fulfilled" ? o.value.timestamp : null
1289
+ );
1290
+ if (n === null) throw o.status === "rejected" ? o.reason : new Error("no block timestamp could be read");
1291
+ return n;
1292
+ }
1293
+ async waitForTransaction(e) {
1294
+ const o = await this.#e.waitForTransactionReceipt({ hash: e });
1295
+ return {
1296
+ hash: e,
1297
+ status: o.status === "success" ? "success" : "reverted",
1298
+ blockNumber: o.blockNumber,
1299
+ source: "live"
1300
+ };
1301
+ }
1302
+ }
1303
+ function Rt(t) {
1304
+ return new Ct(t);
1305
+ }
1306
+ function Ft(t, e, o, n = {}) {
1307
+ const a = n.native ?? me, i = n.lp ?? {};
1308
+ return P(
1309
+ () => Ve(t, e, o, { native: a, lp: i }),
1310
+ [t, e, o, a.symbol, a.decimals, i.lpLocker, i.binLpLocker, i.poolType, i.lpLockerFromBlock, (i.lpLockerTokenIds ?? []).join(",")],
1311
+ { enabled: He(e, i), refetchIntervalMs: n.refetchIntervalMs ?? 6e4 }
1312
+ );
1313
+ }
1314
+ function Gt(t, e, o, n = {}) {
1315
+ const a = n.native ?? me, i = n.lp ?? {}, s = !!i.lpLocker || !!i.binLpLocker;
1316
+ return P(
1317
+ () => je(t, e, o, { native: a, lp: i }),
1318
+ [t, e, o, a.symbol, a.decimals, i.lpLocker, i.binLpLocker, i.lpLockerFromBlock, (i.lpLockerTokenIds ?? []).join(",")],
1319
+ { enabled: e !== null || s, refetchIntervalMs: n.refetchIntervalMs ?? 6e4 }
1320
+ );
1321
+ }
1322
+ function qt(t, e) {
1323
+ const [o, n] = he(() => Date.now());
1324
+ return Ze(() => {
1325
+ if (t === null) return;
1326
+ const a = setInterval(() => n(Date.now()), 1e3);
1327
+ return () => clearInterval(a);
1328
+ }, [t]), t === null || e === null ? null : We(t, e, o);
1329
+ }
1330
+ function I(t) {
1331
+ return t.status === "read" ? t.sources ?? [] : t.status === "error" && t.source ? [t.source] : [];
1332
+ }
1333
+ function v(t, e, o, n, a) {
1334
+ return { key: t, label: e, headline: o.headline, detail: o.detail, tone: o.tone, provenance: n.map((i) => ut(i, a.readAt)), sources: n };
1335
+ }
1336
+ const ge = {
1337
+ "launch-leg": "a Kit v2 launch leg",
1338
+ "lp-locker": "an LP-locker lock",
1339
+ "position-lock": "a LatchPositionLock time lock",
1340
+ given: "this page's pool list"
1341
+ };
1342
+ function ve(t) {
1343
+ return t.length <= 1 ? t[0] ?? "" : `${t.slice(0, -1).join(", ")} and ${t[t.length - 1]}`;
1344
+ }
1345
+ const Tt = (t, e) => t[e.toLowerCase()] ?? `${e.slice(0, 6)}…${e.slice(-4)}`;
1346
+ function Mt(t, e, o) {
1347
+ const n = [
1348
+ {
1349
+ ...v("liquidity", "Liquidity locks", at(t.liquidity, t.kind), I(t.liquidity), e),
1350
+ share: t.liquidity.status !== "read" || !t.liquidity.measurable ? null : t.kind === "Bin" ? ce([{ key: "permanent", label: "Locked permanently (LP locker)", bps: t.liquidity.lockedActiveBps }], "of the active bin") : ce(
1351
+ [
1352
+ { key: "permanent", label: "Locked permanently (LP locker)", bps: t.liquidity.permanentActiveBps },
1353
+ { key: "time", label: "Time-locked until a date", bps: t.liquidity.timeLockedActiveBps }
1354
+ ],
1355
+ "of active liquidity"
1356
+ )
1357
+ },
1358
+ v("lp-fee", "LP fee", st(t.lpFee), t.lpFee.kind === "error" ? [] : t.lpFee.source === null ? [] : [t.lpFee.source], e),
1359
+ v("protocol-fee", "Protocol fee", rt(t.protocolFee), I(t.protocolFee), e)
1360
+ ];
1361
+ return t.tax.status !== "not-a-launch-pool" && n.push(v("tax", "Creator tax", ye(t.tax, e.readAt.chainNow), I(t.tax), e)), n.push(v("registry", "Hook in LatchRegistry", ct(t.registry), t.registry.status === "no-hook" ? [] : I(t.registry), e)), {
1362
+ poolId: t.poolId,
1363
+ title: `${e.symbol} / ${Tt(o, t.pairedWith)} · ${t.kind} pool`,
1364
+ foundBy: `Found through ${ve(t.origins.map((a) => ge[a]))}.`,
1365
+ rows: n
1366
+ };
1367
+ }
1368
+ function Nt(t) {
1369
+ const e = t.launch;
1370
+ if (e.status === "not-configured")
1371
+ return v("tax", "Creator tax", { headline: "Coming soon", detail: "Latch launches are coming soon on this chain, so there is no creator tax to read.", tone: "missing" }, [], t);
1372
+ if (e.status === "error")
1373
+ return v("tax", "Creator tax", { headline: "Could not be read", detail: `The launch read failed: ${e.message}.`, tone: "error" }, I(e), t);
1374
+ if (e.launch === null)
1375
+ return v("tax", "Creator tax", { headline: "Not a Latch launch", detail: "LaunchpadKitV2 has no launch for this token, so no Latch launch guard takes a creator tax on it.", tone: "neutral" }, I(e), t);
1376
+ const o = t.pools.filter((s) => s.origins.includes("launch-leg") && s.tax.status !== "not-a-launch-pool");
1377
+ if (o.length === 0)
1378
+ return v("tax", "Creator tax", { headline: "Could not be read", detail: "No launch pool of this token could be described, so its tax was not read.", tone: "error" }, I(e), t);
1379
+ const n = o.map((s) => ye(s.tax, t.readAt.chainNow)), a = o.flatMap((s) => I(s.tax)).filter((s, r, l) => l.findIndex((c) => c.address.toLowerCase() === s.address.toLowerCase()) === r), i = n[0];
1380
+ return n.every((s) => s.headline === i.headline && s.detail === i.detail) ? v("tax", "Creator tax", o.length === 1 ? i : { ...i, detail: `${i.detail ?? ""} Same on all ${o.length} launch pools.`.trim() }, a, t) : v("tax", "Creator tax", { headline: "Differs by pool", detail: "Each launch pool below carries its own terms.", tone: n.some((s) => s.tone === "caution") ? "caution" : "neutral" }, a, t);
1381
+ }
1382
+ function Ut(t, e = {}) {
1383
+ const o = t.discovery.searched.map((i) => ge[i]), n = `Pools listed are those found through ${o.length === 0 ? "no source yet: these reads are coming soon on this chain" : ve(o)}${t.discovery.truncated ? ", and only the first of them were read" : ""}${t.discovery.positionLocksTruncated ? " (newest position locks only)" : ""}. A pool of this token that no Latch launch or lock knows about is not listed.`, a = t.readAt.fromBlock === t.readAt.toBlock ? `block ${t.readAt.fromBlock.toLocaleString("en-US")}` : `blocks ${t.readAt.fromBlock.toLocaleString("en-US")}–${t.readAt.toBlock.toLocaleString("en-US")}`;
1384
+ return {
1385
+ summary: it(t),
1386
+ launch: v("launch", "Latch launch", ot(t.launch, t.readAt), I(t.launch), t),
1387
+ tokenLocks: {
1388
+ ...v("token-locks", "Token locks & vesting", nt(t.tokenLocks, t.symbol, t.decimals), I(t.tokenLocks), t),
1389
+ share: t.tokenLocks.status === "read" && t.tokenLocks.lockCount > 0 ? Qe(t.tokenLocks) : null
1390
+ },
1391
+ creatorTax: Nt(t),
1392
+ pools: t.pools.map((i) => Mt(i, t, e)),
1393
+ failedPools: t.failedPools.map((i) => `${i.kind} pool ${i.poolId.slice(0, 10)}… could not be described: ${i.message}.`),
1394
+ discoveryNote: n,
1395
+ readAtNote: `Read from chain at ${a}; expiries judged against the chain's clock. Token units, never priced. A registry listing is what the registry records, not an audit.`
1396
+ };
1397
+ }
1398
+ async function St(t, e) {
1399
+ const o = await lt(t, {
1400
+ token: e.token,
1401
+ contracts: e.contracts,
1402
+ ...e.pools !== void 0 ? { pools: e.pools } : {},
1403
+ ...e.lpLockerTokenIds !== void 0 ? { lpLockerTokenIds: e.lpLockerTokenIds } : {},
1404
+ ...e.native !== void 0 ? { native: e.native } : {}
1405
+ }), n = [...new Set(o.pools.map((r) => r.pairedWith.toLowerCase()))], a = e.native?.symbol ?? "ETH", i = await Promise.all(n.map((r) => r === Ie ? Promise.resolve({ symbol: a }) : De(t, r).catch(() => null))), s = {};
1406
+ return n.forEach((r, l) => {
1407
+ const c = i[l];
1408
+ c && (s[r] = c.symbol);
1409
+ }), { trust: o, symbols: s };
1410
+ }
1411
+ function Kt(t, e, o = {}) {
1412
+ const n = e.contracts, a = n === null ? "none" : Object.entries(n).map(([i, s]) => `${i}:${String(s ?? "")}`).sort().join("|");
1413
+ return P(
1414
+ () => St(t, { ...e, contracts: n }),
1415
+ [
1416
+ t,
1417
+ e.token.toLowerCase(),
1418
+ a,
1419
+ (e.pools ?? []).map((i) => `${i.kind}${i.poolId}`).join(","),
1420
+ (e.lpLockerTokenIds ?? []).join(","),
1421
+ e.native?.symbol,
1422
+ e.native?.decimals
1423
+ ],
1424
+ { enabled: n !== null, refetchIntervalMs: o.refetchIntervalMs ?? 6e4 }
1425
+ );
1426
+ }
1427
+ function Xt(t, e) {
1428
+ const o = t.trim().replace(/_/g, "");
1429
+ if (!/^\d+(\.\d+)?$/.test(o) || (o.split(".")[1] ?? "").length > e) return null;
1430
+ try {
1431
+ return Ae(o, e);
1432
+ } catch {
1433
+ return null;
1434
+ }
1435
+ }
1436
+ function Yt(t) {
1437
+ const e = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/.exec(t.trim());
1438
+ if (e === null) return null;
1439
+ const o = Date.UTC(Number(e[1]), Number(e[2]) - 1, Number(e[3]), Number(e[4]), Number(e[5]));
1440
+ return Number.isFinite(o) ? BigInt(Math.floor(o / 1e3)) : null;
1441
+ }
1442
+ function Wt(t) {
1443
+ return new Date(Number(t) * 1e3).toISOString().slice(0, 16);
1444
+ }
1445
+ function Ht(t) {
1446
+ const e = t.trim();
1447
+ return /^\d+$/.test(e) ? BigInt(e) * 86400n : null;
1448
+ }
1449
+ function Vt(t, e) {
1450
+ return t === "timelock" ? e.unlockAt === null ? null : { start: e.unlockAt, cliff: e.unlockAt, end: e.unlockAt } : e.start === null || e.cliffDays === null || e.durationDays === null ? null : { start: e.start, cliff: e.start + e.cliffDays, end: e.start + e.durationDays };
1451
+ }
1452
+ function H(t, e) {
1453
+ if (t === 0n) return "0";
1454
+ const o = 10n ** BigInt(e), n = t / o, a = (t % o).toString().padStart(e, "0").replace(/0+$/, "");
1455
+ return a === "" ? n.toLocaleString("en-US") : `${n.toLocaleString("en-US")}.${a}`;
1456
+ }
1457
+ function jt(t, e) {
1458
+ const o = `${H(t.feeWei, e.decimals)} ${e.symbol} per lock`, n = t.pendingFee, a = n !== null && n.feeWei > t.feeWei, i = a ? n.feeWei : t.feeWei, s = n === null ? null : `${n.feeWei > t.feeWei ? "An increase" : "A change"} to ${H(n.feeWei, e.decimals)} ${e.symbol} applies from ${new Date(Number(n.effectiveAt) * 1e3).toISOString().replace("T", " ").slice(0, 16)} UTC.`;
1459
+ return {
1460
+ fee: o,
1461
+ sends: `${H(i, e.decimals)} ${e.symbol}`,
1462
+ pending: s,
1463
+ note: `Charged by the lock contract itself and paid only to its fee recipient ${t.recipient.slice(0, 6)}…${t.recipient.slice(-4)}.${a ? " The transaction sends the announced higher fee in case it applies before it mines; the contract refunds any surplus in the same call." : ""}`
1464
+ };
1465
+ }
1466
+ function Qt(t) {
1467
+ const e = [];
1468
+ return t.approved || e.push({ key: "approve", label: `Approve LatchPositionLock to move position #${t.tokenId} (this NFT only)` }), e.push({ key: "lock", label: `Lock position #${t.tokenId} until ${new Date(Number(t.unlockAt) * 1e3).toISOString().replace("T", " ").slice(0, 16)} UTC, paying the fee` }), e;
1469
+ }
1470
+ function zt(t) {
1471
+ const e = [];
1472
+ return !t.native && t.allowance < t.amount && e.push({ key: "approve", label: `Approve LatchTokenLock for exactly ${t.amountText} ${t.symbol}` }), e.push({ key: "lock", label: `Lock ${t.amountText} ${t.symbol}, paying the fee${t.native ? " (the amount is sent with it)" : ""}` }), e;
1473
+ }
1474
+ const R = (t, e) => t != null && e !== null && e !== void 0 && t.toLowerCase() === e.toLowerCase();
1475
+ function Jt(t, e, o) {
1476
+ if (t.withdrawn) return [];
1477
+ const n = ["collect"];
1478
+ return R(t.owner, e) && (n.push("extend"), o >= t.unlockAt && n.push("withdraw")), R(t.pendingOwner, e) && n.push("accept"), n;
1479
+ }
1480
+ function Zt(t, e) {
1481
+ const o = [];
1482
+ return R(t.beneficiary, e) && t.claimable > 0n && o.push("claim"), R(t.pendingBeneficiary, e) && o.push("accept"), o;
1483
+ }
1484
+ const en = {
1485
+ collect: "Collect fees",
1486
+ extend: "Extend",
1487
+ withdraw: "Withdraw",
1488
+ accept: "Accept lock"
1489
+ }, tn = {
1490
+ claim: "Claim vested",
1491
+ accept: "Accept lock"
1492
+ };
1493
+ function nn(t) {
1494
+ const e = Je();
1495
+ return tt(() => {
1496
+ if (t !== void 0) return t;
1497
+ const o = e?.adapter;
1498
+ return o === void 0 || o.isMock ? null : {
1499
+ getAccount: () => o.getAccount(),
1500
+ sendTransaction: (n) => o.sendTransaction({ ...n, summary: "Latch lock", source: "live" })
1501
+ };
1502
+ }, [t, e?.adapter]);
1503
+ }
1504
+ function on(t) {
1505
+ return P(() => t === null ? Promise.resolve(null) : t.getAccount(), [t], { refetchIntervalMs: 4e3 });
1506
+ }
1507
+ function an(t, e) {
1508
+ return P(
1509
+ async () => {
1510
+ const [o, n] = await Promise.all([
1511
+ e.positionLock === null ? Promise.resolve(null) : le(t, e.positionLock),
1512
+ e.tokenLock === null ? Promise.resolve(null) : le(t, e.tokenLock)
1513
+ ]);
1514
+ return { position: o, token: n };
1515
+ },
1516
+ [t, e.positionLock, e.tokenLock],
1517
+ { enabled: e.positionLock !== null || e.tokenLock !== null, refetchIntervalMs: 6e4 }
1518
+ );
1519
+ }
1520
+ function sn(t, e, o) {
1521
+ return P(
1522
+ async () => {
1523
+ const n = o, [a, i, s] = await Promise.all([
1524
+ dt(t),
1525
+ e.positionLock === null ? Promise.resolve([]) : pt(t, e.positionLock, n),
1526
+ e.tokenLock === null ? Promise.resolve({ locks: [] }) : mt(t, e.tokenLock, n)
1527
+ ]);
1528
+ return { positions: i, tokens: s.locks, now: a };
1529
+ },
1530
+ [t, e.positionLock, e.tokenLock, o],
1531
+ { enabled: o !== null && (e.positionLock !== null || e.tokenLock !== null), refetchIntervalMs: 6e4 }
1532
+ );
1533
+ }
1534
+ class V extends Error {
1535
+ hash;
1536
+ constructor(e) {
1537
+ super(`The transaction ${e.slice(0, 10)}… was mined and reverted.`), this.name = "TransactionRevertedError", this.hash = e;
1538
+ }
1539
+ }
1540
+ async function rn(t, e, o, n) {
1541
+ await t.call({ account: o, to: n.to, data: n.data, value: n.value });
1542
+ const a = await e.sendTransaction({ to: n.to, data: n.data, value: n.value });
1543
+ if ((await t.waitForTransactionReceipt({ hash: a })).status !== "success") throw new V(a);
1544
+ return a;
1545
+ }
1546
+ function cn(t, e, o, n) {
1547
+ const [a, i] = he({ k: "idle" }), s = et(!1), r = ue(
1548
+ async (c) => {
1549
+ if (s.current) return;
1550
+ const d = c.map((u) => u.label);
1551
+ if (e === null || o === null) {
1552
+ i({ k: "failed", labels: d, active: 0, message: "Connect a wallet first." });
1553
+ return;
1554
+ }
1555
+ s.current = !0;
1556
+ const p = [];
1557
+ let m = 0;
1558
+ try {
1559
+ for (; m < c.length; m++) {
1560
+ i({ k: "running", labels: d, active: m, phase: "simulating" });
1561
+ const u = await c[m].build();
1562
+ await t.call({ account: o, to: u.to, data: u.data, value: u.value }), i({ k: "running", labels: d, active: m, phase: "signing" });
1563
+ const h = await e.sendTransaction({ to: u.to, data: u.data, value: u.value });
1564
+ if (i({ k: "running", labels: d, active: m, phase: "confirming" }), (await t.waitForTransactionReceipt({ hash: h })).status !== "success") throw new V(h);
1565
+ p.push(h);
1566
+ }
1567
+ i({ k: "done", labels: d, hashes: p }), n?.();
1568
+ } catch (u) {
1569
+ i({ k: "failed", labels: d, active: m, message: u instanceof V ? u.message : ze(u, "transaction") });
1570
+ } finally {
1571
+ s.current = !1;
1572
+ }
1573
+ },
1574
+ [t, e, o, n]
1575
+ ), l = ue(() => i({ k: "idle" }), []);
1576
+ return { state: a, run: r, reset: l };
1577
+ }
1578
+ export {
1579
+ sn as A,
1580
+ Ft as B,
1581
+ Gt as C,
1582
+ Kt as D,
1583
+ Et as N,
1584
+ en as P,
1585
+ tn as T,
1586
+ V as a,
1587
+ Lt as b,
1588
+ It as c,
1589
+ vt as d,
1590
+ gt as e,
1591
+ ht as f,
1592
+ Rt as g,
1593
+ St as h,
1594
+ _t as i,
1595
+ jt as j,
1596
+ Xt as k,
1597
+ Vt as l,
1598
+ Yt as m,
1599
+ Qt as n,
1600
+ zt as o,
1601
+ Ht as p,
1602
+ Jt as q,
1603
+ Zt as r,
1604
+ rn as s,
1605
+ Wt as t,
1606
+ Ut as u,
1607
+ qt as v,
1608
+ on as w,
1609
+ an as x,
1610
+ cn as y,
1611
+ nn as z
1612
+ };
1613
+ //# sourceMappingURL=useLocker-D1c_NTk-.js.map