@aori/mega-swap-widget 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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +404 -0
  3. package/dist/AssetSelectionMenu-Y3EB32BT.cjs +13 -0
  4. package/dist/AssetSelectionMenu-Y3EB32BT.cjs.map +1 -0
  5. package/dist/AssetSelectionMenu-ZRG42UCZ.js +13 -0
  6. package/dist/AssetSelectionMenu-ZRG42UCZ.js.map +1 -0
  7. package/dist/ChainSelectionMenu-FBAPPFKI.cjs +11 -0
  8. package/dist/ChainSelectionMenu-FBAPPFKI.cjs.map +1 -0
  9. package/dist/ChainSelectionMenu-QO3H4TNR.js +11 -0
  10. package/dist/ChainSelectionMenu-QO3H4TNR.js.map +1 -0
  11. package/dist/SwapFormHorizontal-JDJUDFNX.js +573 -0
  12. package/dist/SwapFormHorizontal-JDJUDFNX.js.map +1 -0
  13. package/dist/SwapFormHorizontal-WG3Z3CFT.cjs +573 -0
  14. package/dist/SwapFormHorizontal-WG3Z3CFT.cjs.map +1 -0
  15. package/dist/SwapFormSplit-7CHTPLEQ.js +441 -0
  16. package/dist/SwapFormSplit-7CHTPLEQ.js.map +1 -0
  17. package/dist/SwapFormSplit-VDDIRQUQ.cjs +441 -0
  18. package/dist/SwapFormSplit-VDDIRQUQ.cjs.map +1 -0
  19. package/dist/WalletPlaceholderPanel-7YDQ4FT6.js +57 -0
  20. package/dist/WalletPlaceholderPanel-7YDQ4FT6.js.map +1 -0
  21. package/dist/WalletPlaceholderPanel-FZ6XIAMF.cjs +57 -0
  22. package/dist/WalletPlaceholderPanel-FZ6XIAMF.cjs.map +1 -0
  23. package/dist/WidgetWalletPanel-D7I5TAU3.js +789 -0
  24. package/dist/WidgetWalletPanel-D7I5TAU3.js.map +1 -0
  25. package/dist/WidgetWalletPanel-T7H6FGVN.cjs +789 -0
  26. package/dist/WidgetWalletPanel-T7H6FGVN.cjs.map +1 -0
  27. package/dist/chunk-3E6RNP2D.cjs +389 -0
  28. package/dist/chunk-3E6RNP2D.cjs.map +1 -0
  29. package/dist/chunk-5TH6MFQD.cjs +122 -0
  30. package/dist/chunk-5TH6MFQD.cjs.map +1 -0
  31. package/dist/chunk-5XSCUUOW.js +101 -0
  32. package/dist/chunk-5XSCUUOW.js.map +1 -0
  33. package/dist/chunk-6Q7MSCKS.js +2199 -0
  34. package/dist/chunk-6Q7MSCKS.js.map +1 -0
  35. package/dist/chunk-6XB5R4GF.cjs +368 -0
  36. package/dist/chunk-6XB5R4GF.cjs.map +1 -0
  37. package/dist/chunk-6YLNOZ7P.js +389 -0
  38. package/dist/chunk-6YLNOZ7P.js.map +1 -0
  39. package/dist/chunk-7AWG6OWF.js +27 -0
  40. package/dist/chunk-7AWG6OWF.js.map +1 -0
  41. package/dist/chunk-ARMW5POL.js +3082 -0
  42. package/dist/chunk-ARMW5POL.js.map +1 -0
  43. package/dist/chunk-B3ILUJ7G.cjs +101 -0
  44. package/dist/chunk-B3ILUJ7G.cjs.map +1 -0
  45. package/dist/chunk-GGM3MDFM.js +32 -0
  46. package/dist/chunk-GGM3MDFM.js.map +1 -0
  47. package/dist/chunk-GZUTUD5O.cjs +2199 -0
  48. package/dist/chunk-GZUTUD5O.cjs.map +1 -0
  49. package/dist/chunk-HXOGJSAI.cjs +3082 -0
  50. package/dist/chunk-HXOGJSAI.cjs.map +1 -0
  51. package/dist/chunk-LTA7IG3J.js +122 -0
  52. package/dist/chunk-LTA7IG3J.js.map +1 -0
  53. package/dist/chunk-NBJPKJBC.cjs +32 -0
  54. package/dist/chunk-NBJPKJBC.cjs.map +1 -0
  55. package/dist/chunk-PGYOJ5RB.cjs +27 -0
  56. package/dist/chunk-PGYOJ5RB.cjs.map +1 -0
  57. package/dist/chunk-QHW27RMH.js +199 -0
  58. package/dist/chunk-QHW27RMH.js.map +1 -0
  59. package/dist/chunk-TMC4SUEV.js +368 -0
  60. package/dist/chunk-TMC4SUEV.js.map +1 -0
  61. package/dist/chunk-XQINW7QP.cjs +199 -0
  62. package/dist/chunk-XQINW7QP.cjs.map +1 -0
  63. package/dist/index.cjs +1780 -0
  64. package/dist/index.cjs.map +1 -0
  65. package/dist/index.css +1424 -0
  66. package/dist/index.css.map +1 -0
  67. package/dist/index.d.cts +555 -0
  68. package/dist/index.d.ts +555 -0
  69. package/dist/index.js +1780 -0
  70. package/dist/index.js.map +1 -0
  71. package/package.json +82 -0
@@ -0,0 +1,3082 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
+
3
+
4
+ var _chunk5TH6MFQDcjs = require('./chunk-5TH6MFQD.cjs');
5
+
6
+
7
+
8
+ var _chunk6XB5R4GFcjs = require('./chunk-6XB5R4GF.cjs');
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+ var _chunkGZUTUD5Ocjs = require('./chunk-GZUTUD5O.cjs');
39
+
40
+
41
+ var _chunkPGYOJ5RBcjs = require('./chunk-PGYOJ5RB.cjs');
42
+
43
+
44
+ var _chunkNBJPKJBCcjs = require('./chunk-NBJPKJBC.cjs');
45
+
46
+ // src/hooks/useBalanceEventListener.ts
47
+ var _reactquery = require('@tanstack/react-query');
48
+ var _react = require('react');
49
+ function getRefetchDelay(chainIds) {
50
+ const MIN_DELAY = 1e3;
51
+ const MAX_DELAY = 5e3;
52
+ const BUFFER = 1e3;
53
+ if (chainIds.length === 0) return 5e3;
54
+ const maxBlockTime = Math.max(
55
+ ...chainIds.map((id) => _nullishCoalesce(_optionalChain([_chunkGZUTUD5Ocjs.getChainConfig.call(void 0, id), 'optionalAccess', _ => _.blockTimeMs]), () => ( 2e3)))
56
+ );
57
+ return Math.min(MAX_DELAY, Math.max(MIN_DELAY, maxBlockTime * 2 + BUFFER));
58
+ }
59
+ var useBalanceEventListener = () => {
60
+ const { address: userAddress } = _chunkPGYOJ5RBcjs.useWalletState.call(void 0, );
61
+ const availableChainIds = _chunkGZUTUD5Ocjs.useEnabledChainIds.call(void 0, );
62
+ const queryClient = _reactquery.useQueryClient.call(void 0, );
63
+ const pendingTimerRef = _react.useRef.call(void 0, null);
64
+ const mountedRef = _react.useRef.call(void 0, true);
65
+ const triggerBalanceUpdate = _react.useCallback.call(void 0,
66
+ (event) => {
67
+ if (!userAddress) return;
68
+ const chainIds = [...new Set(event.tokens.map((t) => t.asset.chainId))];
69
+ const delay = getRefetchDelay(chainIds);
70
+ if (pendingTimerRef.current) {
71
+ clearTimeout(pendingTimerRef.current);
72
+ pendingTimerRef.current = null;
73
+ }
74
+ pendingTimerRef.current = setTimeout(async () => {
75
+ pendingTimerRef.current = null;
76
+ if (!mountedRef.current) return;
77
+ try {
78
+ const tokens = event.tokens.map((t) => ({
79
+ chainId: t.asset.chainId,
80
+ tokenAddress: t.asset.address
81
+ }));
82
+ const swapResult = await _chunkGZUTUD5Ocjs.fetchSwapBalances.call(void 0, userAddress, tokens);
83
+ if (swapResult.balances.length === 0) return;
84
+ if (event.tokens.length >= 2) {
85
+ const base = event.tokens[0].asset;
86
+ const quote = event.tokens[1].asset;
87
+ const swapKey = _chunkGZUTUD5Ocjs.balanceKeys.swap(
88
+ userAddress,
89
+ base.chainId,
90
+ base.address,
91
+ quote.chainId,
92
+ quote.address
93
+ );
94
+ queryClient.setQueryData(swapKey, swapResult);
95
+ }
96
+ const bulkKey = _chunkGZUTUD5Ocjs.balanceKeys.bulk(userAddress, availableChainIds);
97
+ const existingBulk = queryClient.getQueryData(bulkKey);
98
+ if (existingBulk) {
99
+ const updatedBalances = existingBulk.balances.map((existing) => {
100
+ const updated = swapResult.balances.find(
101
+ (b) => b.chainId === existing.chainId && b.token.toLowerCase() === existing.token.toLowerCase()
102
+ );
103
+ return _nullishCoalesce(updated, () => ( existing));
104
+ });
105
+ for (const newBalance of swapResult.balances) {
106
+ if (!updatedBalances.some(
107
+ (b) => b.chainId === newBalance.chainId && b.token.toLowerCase() === newBalance.token.toLowerCase()
108
+ )) updatedBalances.push(newBalance);
109
+ }
110
+ for (const eventToken of event.tokens) {
111
+ const inResult = swapResult.balances.some(
112
+ (b) => b.chainId === eventToken.asset.chainId && b.token.toLowerCase() === eventToken.asset.address.toLowerCase()
113
+ );
114
+ if (!inResult) {
115
+ const idx = updatedBalances.findIndex(
116
+ (b) => b.chainId === eventToken.asset.chainId && b.token.toLowerCase() === eventToken.asset.address.toLowerCase()
117
+ );
118
+ if (idx !== -1) {
119
+ updatedBalances[idx] = { ...updatedBalances[idx], balance: "0", shiftedBalance: "0" };
120
+ }
121
+ }
122
+ }
123
+ queryClient.setQueryData(bulkKey, { balances: updatedBalances });
124
+ }
125
+ } catch (e2) {
126
+ }
127
+ }, delay);
128
+ },
129
+ [userAddress, availableChainIds, queryClient]
130
+ );
131
+ _react.useEffect.call(void 0, () => {
132
+ mountedRef.current = true;
133
+ return () => {
134
+ mountedRef.current = false;
135
+ if (pendingTimerRef.current) {
136
+ clearTimeout(pendingTimerRef.current);
137
+ pendingTimerRef.current = null;
138
+ }
139
+ };
140
+ }, []);
141
+ return { triggerBalanceUpdate };
142
+ };
143
+ var BalanceEventEmitter = class extends EventTarget {
144
+ emit(event) {
145
+ this.dispatchEvent(new CustomEvent("balance-update", { detail: event }));
146
+ }
147
+ };
148
+ var balanceEventEmitter = new BalanceEventEmitter();
149
+ var useEmitBalanceEvent = () => {
150
+ return (event) => balanceEventEmitter.emit(event);
151
+ };
152
+ var useBalanceEventSubscription = () => {
153
+ const { triggerBalanceUpdate } = useBalanceEventListener();
154
+ _react.useEffect.call(void 0, () => {
155
+ const handler = (event) => {
156
+ triggerBalanceUpdate(event.detail);
157
+ };
158
+ balanceEventEmitter.addEventListener("balance-update", handler);
159
+ return () => balanceEventEmitter.removeEventListener("balance-update", handler);
160
+ }, [triggerBalanceUpdate]);
161
+ };
162
+
163
+ // src/providers/RfqProvider.tsx
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+ var _viem = require('viem');
174
+ var _jsxruntime = require('react/jsx-runtime');
175
+ var RfqContext = _react.createContext.call(void 0, void 0);
176
+ var POLLING_INTERVAL_MS = 1e4;
177
+ var STALE_WINDOW_MS = 3e4;
178
+ var TYPING_SETTLE_DELAY_MS = 1e3;
179
+ var ROUTING_ERROR_THRESHOLD = 2;
180
+ function selectQuote(quotes) {
181
+ const aori = quotes.find((q) => _optionalChain([q, 'access', _2 => _2.routeSteps, 'optionalAccess', _3 => _3[0], 'optionalAccess', _4 => _4.type]) === "AORI_V1");
182
+ return _nullishCoalesce(aori, () => ( quotes[0]));
183
+ }
184
+ var RfqProvider = ({
185
+ children,
186
+ recipient: recipientProp
187
+ }) => {
188
+ const { address: userAddress } = _chunkPGYOJ5RBcjs.useWalletState.call(void 0, );
189
+ const recipient = recipientProp || userAddress;
190
+ const [status, setStatus] = _react.useState.call(void 0, "idle");
191
+ const [inputState, setInputState] = _react.useState.call(void 0, "idle");
192
+ const [rfqQuote, setRfqQuote] = _react.useState.call(void 0, null);
193
+ const [error, setError] = _react.useState.call(void 0, null);
194
+ const [liquidityError, setLiquidityError] = _react.useState.call(void 0, false);
195
+ const [routingError, setRoutingError] = _react.useState.call(void 0, false);
196
+ const [sizeCapError, setSizeCapError] = _react.useState.call(void 0, false);
197
+ const sessionIdRef = _react.useRef.call(void 0, null);
198
+ const lastParamsRef = _react.useRef.call(void 0, null);
199
+ const pollingIntervalRef = _react.useRef.call(void 0, null);
200
+ const staleTimerRef = _react.useRef.call(void 0, null);
201
+ const typingTimerRef = _react.useRef.call(void 0, null);
202
+ const latestRequestId = _react.useRef.call(void 0, 0);
203
+ const lastRequestAtRef = _react.useRef.call(void 0, 0);
204
+ const lastStartAtRef = _react.useRef.call(void 0, 0);
205
+ const hasQuoteRef = _react.useRef.call(void 0, false);
206
+ const routingErrorsRef = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
207
+ const clearTimers = _react.useCallback.call(void 0, () => {
208
+ if (pollingIntervalRef.current) clearTimeout(pollingIntervalRef.current);
209
+ if (staleTimerRef.current) clearTimeout(staleTimerRef.current);
210
+ if (typingTimerRef.current) clearTimeout(typingTimerRef.current);
211
+ pollingIntervalRef.current = null;
212
+ staleTimerRef.current = null;
213
+ typingTimerRef.current = null;
214
+ }, []);
215
+ const stop = _react.useCallback.call(void 0, () => {
216
+ clearTimers();
217
+ sessionIdRef.current = null;
218
+ latestRequestId.current = 0;
219
+ setStatus(() => hasQuoteRef.current ? "fresh" : "idle");
220
+ }, [clearTimers]);
221
+ const clear = _react.useCallback.call(void 0, () => {
222
+ stop();
223
+ lastParamsRef.current = null;
224
+ setRfqQuote(null);
225
+ setError(null);
226
+ setLiquidityError(false);
227
+ setRoutingError(false);
228
+ setSizeCapError(false);
229
+ routingErrorsRef.current.clear();
230
+ setStatus("idle");
231
+ setInputState("idle");
232
+ }, [stop]);
233
+ const scheduleStale = _react.useCallback.call(void 0, (receivedAt) => {
234
+ if (!receivedAt) return;
235
+ if (staleTimerRef.current) clearTimeout(staleTimerRef.current);
236
+ const delay = Math.max(0, receivedAt + STALE_WINDOW_MS - Date.now());
237
+ staleTimerRef.current = setTimeout(() => {
238
+ setStatus((prev) => prev === "idle" ? "idle" : "stale");
239
+ }, delay);
240
+ }, []);
241
+ const requestQuoteOnce = _react.useCallback.call(void 0,
242
+ async (params, sessionId) => {
243
+ const { inputToken, outputToken, inputAmount, setOutputAmount } = params;
244
+ if (!inputToken || !outputToken || !inputAmount || parseFloat(inputAmount) <= 0)
245
+ return;
246
+ const now = Date.now();
247
+ if (now - (lastRequestAtRef.current || 0) < POLLING_INTERVAL_MS - 10)
248
+ return;
249
+ const requestId = ++latestRequestId.current;
250
+ try {
251
+ if (!_optionalChain([inputToken, 'optionalAccess', _5 => _5.decimals]) || !_optionalChain([outputToken, 'optionalAccess', _6 => _6.decimals])) return;
252
+ const srcChainKey = _chunkGZUTUD5Ocjs.getKeyForChainId.call(void 0, inputToken.chainId) || _optionalChain([_chunkGZUTUD5Ocjs.getChainConfig.call(void 0, inputToken.chainId), 'optionalAccess', _7 => _7.key]) || "";
253
+ const dstChainKey = _chunkGZUTUD5Ocjs.getKeyForChainId.call(void 0, outputToken.chainId) || _optionalChain([_chunkGZUTUD5Ocjs.getChainConfig.call(void 0, outputToken.chainId), 'optionalAccess', _8 => _8.key]) || "";
254
+ if (!srcChainKey || !dstChainKey) throw new Error("Unknown chain");
255
+ const normalizedAmount = _viem.parseUnits.call(void 0,
256
+ inputAmount.toString(),
257
+ inputToken.decimals
258
+ ).toString();
259
+ const body = {
260
+ srcChainKey,
261
+ dstChainKey,
262
+ srcTokenAddress: _chunkGZUTUD5Ocjs.checkedAddress.call(void 0, inputToken.address),
263
+ dstTokenAddress: _chunkGZUTUD5Ocjs.checkedAddress.call(void 0, outputToken.address),
264
+ amount: normalizedAmount,
265
+ srcWalletAddress: userAddress || "0x0000000000000000000000000000000000000000",
266
+ dstWalletAddress: recipient || userAddress || "0x0000000000000000000000000000000000000000",
267
+ options: {
268
+ amountType: "EXACT_SRC_AMOUNT",
269
+ feeTolerance: { type: "PERCENT", amount: 2 }
270
+ }
271
+ };
272
+ lastRequestAtRef.current = Date.now();
273
+ const res = await fetch(`${_chunkGZUTUD5Ocjs.getVtApiUrl.call(void 0, )}/quotes`, {
274
+ method: "POST",
275
+ headers: _chunkGZUTUD5Ocjs.getVtHeaders.call(void 0, ),
276
+ body: JSON.stringify(body),
277
+ signal: AbortSignal.timeout(15e3)
278
+ });
279
+ if (!res.ok) {
280
+ const errBody = await res.json().catch(() => ({}));
281
+ const msg = _optionalChain([errBody, 'optionalAccess', _9 => _9.message]) || res.statusText;
282
+ throw Object.assign(new Error(msg), { status: res.status });
283
+ }
284
+ const data = await res.json();
285
+ if (requestId !== latestRequestId.current || sessionIdRef.current !== sessionId)
286
+ return;
287
+ const quotes = _nullishCoalesce(data.quotes, () => ( []));
288
+ const selected = selectQuote(quotes);
289
+ if (!selected) throw Object.assign(new Error("No quotes returned"), { emptyQuotes: true });
290
+ const formattedOutput = Number(
291
+ _viem.formatUnits.call(void 0, _chunkGZUTUD5Ocjs.toBigInt.call(void 0, selected.dstAmount), outputToken.decimals)
292
+ );
293
+ if (typeof setOutputAmount === "function") setOutputAmount(formattedOutput);
294
+ selected._receivedAt = Date.now();
295
+ setRfqQuote(selected);
296
+ setError(null);
297
+ setLiquidityError(false);
298
+ setStatus("fresh");
299
+ scheduleStale(selected._receivedAt);
300
+ if (sessionId) routingErrorsRef.current.delete(sessionId);
301
+ } catch (e) {
302
+ if (requestId !== latestRequestId.current || sessionIdRef.current !== sessionId)
303
+ return;
304
+ const statusCode = _optionalChain([e, 'optionalAccess', _10 => _10.status]);
305
+ const errorMessage = e instanceof Error ? e.message : "";
306
+ const isEmptyQuotes = !!_optionalChain([e, 'optionalAccess', _11 => _11.emptyQuotes]);
307
+ if ((statusCode === 400 || isEmptyQuotes || errorMessage.includes("Quote request failed")) && sessionId) {
308
+ const current = routingErrorsRef.current.get(sessionId) || 0;
309
+ const newCount = current + 1;
310
+ routingErrorsRef.current.set(sessionId, newCount);
311
+ if (newCount >= ROUTING_ERROR_THRESHOLD) {
312
+ setRoutingError(true);
313
+ clearTimers();
314
+ sessionIdRef.current = null;
315
+ return;
316
+ }
317
+ }
318
+ if (errorMessage.toLowerCase().includes("order cap exceeded")) {
319
+ setSizeCapError(true);
320
+ clearTimers();
321
+ sessionIdRef.current = null;
322
+ return;
323
+ }
324
+ if (errorMessage.toLowerCase().includes("insufficient executor balance")) {
325
+ setLiquidityError(true);
326
+ clearTimers();
327
+ sessionIdRef.current = null;
328
+ return;
329
+ }
330
+ setError(e instanceof Error ? e.message : "Unknown error");
331
+ }
332
+ },
333
+ [userAddress, recipient, scheduleStale, clearTimers]
334
+ );
335
+ const startPolling = _react.useCallback.call(void 0,
336
+ (params, sessionId) => {
337
+ clearTimers();
338
+ lastParamsRef.current = params;
339
+ lastRequestAtRef.current = 0;
340
+ routingErrorsRef.current.delete(sessionId);
341
+ setLiquidityError(false);
342
+ setRoutingError(false);
343
+ setSizeCapError(false);
344
+ setError(null);
345
+ setStatus("polling");
346
+ const poll = async () => {
347
+ if (sessionIdRef.current !== sessionId) return;
348
+ await requestQuoteOnce(params, sessionId);
349
+ if (sessionIdRef.current !== sessionId) return;
350
+ pollingIntervalRef.current = setTimeout(poll, POLLING_INTERVAL_MS);
351
+ };
352
+ poll();
353
+ },
354
+ [clearTimers, requestQuoteOnce]
355
+ );
356
+ const ensureForParams = _react.useCallback.call(void 0,
357
+ (params) => {
358
+ if (!_optionalChain([params, 'optionalAccess', _12 => _12.inputToken]) || !_optionalChain([params, 'optionalAccess', _13 => _13.outputToken]) || !_optionalChain([params, 'optionalAccess', _14 => _14.inputAmount]) || parseFloat(params.inputAmount) <= 0) {
359
+ stop();
360
+ return;
361
+ }
362
+ const prev = lastParamsRef.current;
363
+ const sameParams = prev && _optionalChain([prev, 'access', _15 => _15.inputToken, 'optionalAccess', _16 => _16.address]) === _optionalChain([params, 'access', _17 => _17.inputToken, 'optionalAccess', _18 => _18.address]) && _optionalChain([prev, 'access', _19 => _19.inputToken, 'optionalAccess', _20 => _20.chainId]) === _optionalChain([params, 'access', _21 => _21.inputToken, 'optionalAccess', _22 => _22.chainId]) && _optionalChain([prev, 'access', _23 => _23.outputToken, 'optionalAccess', _24 => _24.address]) === _optionalChain([params, 'access', _25 => _25.outputToken, 'optionalAccess', _26 => _26.address]) && _optionalChain([prev, 'access', _27 => _27.outputToken, 'optionalAccess', _28 => _28.chainId]) === _optionalChain([params, 'access', _29 => _29.outputToken, 'optionalAccess', _30 => _30.chainId]) && prev.inputAmount === params.inputAmount;
364
+ if (sameParams && sessionIdRef.current) return;
365
+ const now = Date.now();
366
+ if (now - lastStartAtRef.current < 100) return;
367
+ lastStartAtRef.current = now;
368
+ const newSessionId = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
369
+ sessionIdRef.current = newSessionId;
370
+ startPolling(params, newSessionId);
371
+ },
372
+ [startPolling, stop]
373
+ );
374
+ const handleInputChange = _react.useCallback.call(void 0,
375
+ ({ amount, inputToken, outputToken, setOutputAmount }) => {
376
+ setOutputAmount(null);
377
+ if (typingTimerRef.current) clearTimeout(typingTimerRef.current);
378
+ if (!amount || amount === 0) {
379
+ setInputState("idle");
380
+ stop();
381
+ setRfqQuote(null);
382
+ setError(null);
383
+ setLiquidityError(false);
384
+ setRoutingError(false);
385
+ setSizeCapError(false);
386
+ } else {
387
+ setInputState("typing");
388
+ stop();
389
+ setRfqQuote(null);
390
+ setLiquidityError(false);
391
+ setRoutingError(false);
392
+ setSizeCapError(false);
393
+ setError(null);
394
+ typingTimerRef.current = setTimeout(() => {
395
+ setInputState("settled");
396
+ if (inputToken && outputToken && amount > 0) {
397
+ ensureForParams({
398
+ inputToken,
399
+ outputToken,
400
+ inputAmount: amount.toString(),
401
+ setOutputAmount
402
+ });
403
+ }
404
+ }, TYPING_SETTLE_DELAY_MS);
405
+ }
406
+ },
407
+ [stop, ensureForParams]
408
+ );
409
+ const refresh = _react.useCallback.call(void 0, () => {
410
+ const params = lastParamsRef.current;
411
+ if (!params) return;
412
+ setRfqQuote(null);
413
+ const newSessionId = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
414
+ sessionIdRef.current = newSessionId;
415
+ setStatus("refreshing");
416
+ if (typeof params.setOutputAmount === "function")
417
+ params.setOutputAmount(null);
418
+ startPolling(params, newSessionId);
419
+ }, [startPolling]);
420
+ _react.useEffect.call(void 0, () => {
421
+ hasQuoteRef.current = !!rfqQuote;
422
+ }, [rfqQuote]);
423
+ _react.useEffect.call(void 0, () => () => clearTimers(), [clearTimers]);
424
+ const contextValue = _react.useMemo.call(void 0,
425
+ () => ({
426
+ status,
427
+ inputState,
428
+ rfqQuote,
429
+ error,
430
+ liquidityError,
431
+ routingError,
432
+ sizeCapError,
433
+ ensureForParams,
434
+ stop,
435
+ refresh,
436
+ clear,
437
+ handleInputChange
438
+ }),
439
+ [
440
+ status,
441
+ inputState,
442
+ rfqQuote,
443
+ error,
444
+ liquidityError,
445
+ routingError,
446
+ sizeCapError,
447
+ ensureForParams,
448
+ stop,
449
+ refresh,
450
+ clear,
451
+ handleInputChange
452
+ ]
453
+ );
454
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RfqContext.Provider, { value: contextValue, children });
455
+ };
456
+ var useRfq = () => {
457
+ const context = _react.useContext.call(void 0, RfqContext);
458
+ if (context === void 0)
459
+ throw new Error("useRfq must be used within an RfqProvider");
460
+ return context;
461
+ };
462
+
463
+ // src/wallet/WalletModalContext.tsx
464
+
465
+ var WalletModalContext = _react.createContext.call(void 0, {
466
+ openConnectModal: () => {
467
+ }
468
+ });
469
+ var useWalletModal = () => _react.useContext.call(void 0, WalletModalContext);
470
+
471
+ // src/components/AssetAmountInput.tsx
472
+
473
+
474
+ var MAX_INPUT_LENGTH = 20;
475
+ var AssetAmountInput = ({
476
+ side,
477
+ asset,
478
+ otherAsset,
479
+ isPlacingOrder,
480
+ isWrappingPair,
481
+ isUnwrappingPair
482
+ }) => {
483
+ const { baseAmount, quoteAmount, setBaseAmount, setQuoteAmount } = _chunk6XB5R4GFcjs.useSwapFormContext.call(void 0, );
484
+ const { amountInputVariant, hideAmountInputSymbol, widgetType } = _chunkGZUTUD5Ocjs.useWidgetConfig.call(void 0, );
485
+ const isCompactMode = widgetType === "compact";
486
+ const [setAssetAmount, setOtherAssetAmount] = side === "base" ? [setBaseAmount, setQuoteAmount] : [setQuoteAmount, setBaseAmount];
487
+ const disabled = !asset || side === "quote" || isPlacingOrder;
488
+ const maxFontSize = isCompactMode ? 32 : amountInputVariant === "default" ? 64 : 32;
489
+ const [fontSize, setFontSize] = _react.useState.call(void 0, maxFontSize);
490
+ const [inputValue, setInputValue] = _react.useState.call(void 0, "");
491
+ const containerRef = _react.useRef.call(void 0, null);
492
+ const measureRef = _react.useRef.call(void 0, null);
493
+ const symbolRef = _react.useRef.call(void 0, null);
494
+ const inputRef = _react.useRef.call(void 0, null);
495
+ const placeholderText = "USD";
496
+ const assetAmount = side === "base" ? baseAmount : quoteAmount;
497
+ const [isMounted, setIsMounted] = _react.useState.call(void 0, false);
498
+ const adjustFontSize = _react.useCallback.call(void 0, () => {
499
+ if (amountInputVariant !== "default") {
500
+ setFontSize(maxFontSize);
501
+ return;
502
+ }
503
+ if (!containerRef.current || !measureRef.current || !symbolRef.current)
504
+ return;
505
+ const containerWidth = containerRef.current.offsetWidth;
506
+ const padding = 20;
507
+ let newFontSize = maxFontSize;
508
+ while (newFontSize > 20) {
509
+ measureRef.current.style.fontSize = `${newFontSize}px`;
510
+ symbolRef.current.style.fontSize = `${newFontSize}px`;
511
+ const totalWidth = measureRef.current.offsetWidth + symbolRef.current.offsetWidth + padding;
512
+ if (totalWidth <= containerWidth) break;
513
+ newFontSize -= 1;
514
+ }
515
+ setFontSize(newFontSize);
516
+ }, [amountInputVariant, maxFontSize]);
517
+ const handleKeyDown = _react.useCallback.call(void 0,
518
+ (e) => {
519
+ if (e.key === "." && inputValue.includes(".")) e.preventDefault();
520
+ },
521
+ [inputValue]
522
+ );
523
+ const handleAmountChange = _react.useCallback.call(void 0,
524
+ (e) => {
525
+ let newValue = e.target.value;
526
+ if (newValue === ".") newValue = "0.";
527
+ if (!/^\d*\.?\d*$/.test(newValue)) return;
528
+ if ((newValue.match(/\./g) || []).length > 1) return;
529
+ if (newValue.length > 1 && newValue[0] === "0" && newValue[1] !== ".") {
530
+ newValue = newValue.replace(/^0+/, "") || "0";
531
+ }
532
+ if (_optionalChain([asset, 'optionalAccess', _31 => _31.decimals]) !== void 0 && newValue.includes(".")) {
533
+ const [, fracPart] = newValue.split(".");
534
+ if (fracPart && fracPart.length > asset.decimals) return;
535
+ }
536
+ if (newValue.length > MAX_INPUT_LENGTH) return;
537
+ setInputValue(newValue);
538
+ const newAmount = parseFloat(newValue);
539
+ if (newValue !== inputValue) {
540
+ if (newValue === "" || newValue === "0." || newValue.endsWith(".")) {
541
+ setAssetAmount(null);
542
+ if (side === "base") setOtherAssetAmount(null);
543
+ } else if (!Number.isNaN(newAmount) && newAmount >= 0) {
544
+ setAssetAmount(newAmount);
545
+ }
546
+ if (side === "base") setQuoteAmount(null);
547
+ if (isUnwrappingPair || isWrappingPair) setQuoteAmount(newAmount || 0);
548
+ }
549
+ },
550
+ [
551
+ inputValue,
552
+ setAssetAmount,
553
+ side,
554
+ setQuoteAmount,
555
+ _optionalChain([asset, 'optionalAccess', _32 => _32.decimals]),
556
+ setOtherAssetAmount,
557
+ isUnwrappingPair,
558
+ isWrappingPair
559
+ ]
560
+ );
561
+ _react.useEffect.call(void 0, () => {
562
+ const formatAmount = (amount) => {
563
+ if (amount === null) return "";
564
+ const decimals = _optionalChain([asset, 'optionalAccess', _33 => _33.decimals]);
565
+ if (decimals === void 0) return "";
566
+ let asString = amount.toString();
567
+ if (/e/i.test(asString)) {
568
+ asString = Number(amount).toLocaleString("en-US", {
569
+ useGrouping: false,
570
+ maximumFractionDigits: decimals
571
+ });
572
+ }
573
+ if (asString.includes(".")) {
574
+ const [intPart, fracPartRaw] = asString.split(".");
575
+ const fracPart = fracPartRaw.slice(0, decimals);
576
+ return fracPart ? `${intPart}.${fracPart}` : intPart;
577
+ }
578
+ return asString;
579
+ };
580
+ if (assetAmount === null) {
581
+ const isTypingDecimal = inputValue === "0." || inputValue !== "" && inputValue.endsWith(".");
582
+ if (!isTypingDecimal) setInputValue("");
583
+ return;
584
+ }
585
+ const isUserTyping = !disabled && (inputValue.endsWith(".") || inputValue.match(/\.\d*0$/) || inputValue === "0" || inputValue === "0.");
586
+ if (isUserTyping && inputValue !== "") return;
587
+ const currentNumericValue = parseFloat(inputValue) || 0;
588
+ if (inputValue === "" || Math.abs(currentNumericValue - assetAmount) > 1e-10) {
589
+ setInputValue(formatAmount(assetAmount));
590
+ }
591
+ }, [assetAmount, _optionalChain([asset, 'optionalAccess', _34 => _34.decimals]), inputValue, disabled]);
592
+ _react.useEffect.call(void 0, () => {
593
+ adjustFontSize();
594
+ }, [inputValue, adjustFontSize]);
595
+ _react.useEffect.call(void 0, () => {
596
+ setIsMounted(true);
597
+ }, []);
598
+ _react.useEffect.call(void 0, () => {
599
+ if (isMounted) adjustFontSize();
600
+ }, [isMounted, adjustFontSize]);
601
+ _react.useEffect.call(void 0, () => {
602
+ if (measureRef.current && inputRef.current) {
603
+ inputRef.current.style.width = `${measureRef.current.offsetWidth}px`;
604
+ }
605
+ }, [inputValue]);
606
+ _react.useEffect.call(void 0, () => {
607
+ if (!isMounted) return;
608
+ const resizeObserver = new ResizeObserver(() => {
609
+ if (isMounted) adjustFontSize();
610
+ });
611
+ if (containerRef.current) resizeObserver.observe(containerRef.current);
612
+ return () => resizeObserver.disconnect();
613
+ }, [isMounted, adjustFontSize]);
614
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
615
+ "div",
616
+ {
617
+ ref: containerRef,
618
+ style: {
619
+ fontSize: `${fontSize}px`,
620
+ transition: "font-size 0.05s ease-in-out"
621
+ },
622
+ className: `mt-2 box-border flex ${isCompactMode ? amountInputVariant === "normal" ? "h-12 my-1" : "h-10 my-0.5" : amountInputVariant === "normal" ? "h-12 my-1" : "h-20 my-1"} w-full flex-row items-center ${disabled ? "cursor-default" : "cursor-text"}`,
623
+ onClick: () => _optionalChain([inputRef, 'access', _35 => _35.current, 'optionalAccess', _36 => _36.focus, 'call', _37 => _37()]),
624
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex w-full items-center", children: [
625
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { htmlFor: `${side}Amount`, className: "sr-only", children: side === "base" ? "Input token amount" : "Output token amount" }),
626
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
627
+ "input",
628
+ {
629
+ ref: inputRef,
630
+ type: "text",
631
+ inputMode: "decimal",
632
+ placeholder: "0",
633
+ autoComplete: "off",
634
+ id: `${side}Amount`,
635
+ value: inputValue,
636
+ onWheel: (e) => e.target.blur(),
637
+ onKeyDown: handleKeyDown,
638
+ onChange: handleAmountChange,
639
+ style: {
640
+ transition: "width 0.15s ease-in-out",
641
+ color: disabled ? "var(--widget-foreground)" : "var(--widget-foreground)",
642
+ WebkitTextFillColor: disabled ? "var(--widget-foreground)" : "var(--widget-foreground)",
643
+ opacity: disabled ? 0.4 : 1
644
+ },
645
+ className: "flex min-w-[45px] whitespace-nowrap bg-transparent placeholder:opacity-50",
646
+ disabled
647
+ }
648
+ ),
649
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
650
+ "span",
651
+ {
652
+ style: { transition: "width 0.15s ease-in-out" },
653
+ ref: measureRef,
654
+ className: "pointer-events-none absolute flex whitespace-nowrap invisible",
655
+ children: inputValue || 0
656
+ }
657
+ ),
658
+ !hideAmountInputSymbol && amountInputVariant !== "normal" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
659
+ "span",
660
+ {
661
+ ref: symbolRef,
662
+ className: "ml-2 font-light uppercase",
663
+ style: {
664
+ color: "var(--widget-foreground)",
665
+ opacity: 0.5,
666
+ fontSize: `${fontSize}px`
667
+ },
668
+ children: _optionalChain([asset, 'optionalAccess', _38 => _38.symbol]) ? asset.symbol.length > 6 ? `${asset.symbol.slice(0, 6)}...` : asset.symbol : placeholderText
669
+ }
670
+ ),
671
+ (hideAmountInputSymbol || amountInputVariant === "normal") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { ref: symbolRef, className: "hidden" })
672
+ ] })
673
+ }
674
+ );
675
+ };
676
+ var AssetAmountInput_default = AssetAmountInput;
677
+
678
+ // src/components/AssetSelection.tsx
679
+
680
+ var AssetSelection = ({
681
+ toggle,
682
+ side,
683
+ asset,
684
+ isPlacingOrder
685
+ }) => {
686
+ const { baseBalance, quoteBalance } = _chunk6XB5R4GFcjs.useSwapFormContext.call(void 0, );
687
+ const { tokenDisplay, tokenBadgeOrientation, widgetType } = _chunkGZUTUD5Ocjs.useWidgetConfig.call(void 0, );
688
+ const isCompactMode = widgetType === "compact";
689
+ const cardHeight = isCompactMode ? "h-10" : "h-12";
690
+ const iconSize = isCompactMode ? "h-10 w-10" : "h-12 w-12";
691
+ const userBalance = side === "base" ? baseBalance.formatted ? (() => {
692
+ const value = parseFloat(baseBalance.formatted);
693
+ return value >= 1e8 ? _chunkGZUTUD5Ocjs.formatNumber.call(void 0, value) : value.toFixed(3);
694
+ })() : void 0 : quoteBalance.formatted ? (() => {
695
+ const value = parseFloat(quoteBalance.formatted);
696
+ return value >= 1e8 ? _chunkGZUTUD5Ocjs.formatNumber.call(void 0, value) : value.toFixed(3);
697
+ })() : void 0;
698
+ const sharedProps = {
699
+ role: "button",
700
+ tabIndex: isPlacingOrder ? -1 : 0,
701
+ "aria-disabled": isPlacingOrder,
702
+ "aria-label": `Select ${side === "base" ? "input" : "output"} token${asset ? `: ${asset.symbol}` : ""}`,
703
+ onClick: !isPlacingOrder ? toggle : void 0,
704
+ onKeyDown: !isPlacingOrder ? (e) => {
705
+ if (e.key === "Enter" || e.key === " ") {
706
+ e.preventDefault();
707
+ toggle();
708
+ }
709
+ } : void 0
710
+ };
711
+ if (tokenDisplay === "pill") {
712
+ const isRight = tokenBadgeOrientation === "right";
713
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
714
+ "div",
715
+ {
716
+ ...sharedProps,
717
+ className: `inline-flex items-center gap-1.5 h-7 px-2.5 rounded-full cursor-pointer transition-colors ${isRight ? "ml-auto" : ""}`,
718
+ style: {
719
+ border: "1px solid var(--widget-border)",
720
+ backgroundColor: "var(--widget-secondary)",
721
+ color: "var(--widget-secondary-foreground)"
722
+ },
723
+ children: asset ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
724
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.ChainIcon_default, { chain: asset.chainId, size: "xs" }),
725
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
726
+ _chunkGZUTUD5Ocjs.TokenImage_default,
727
+ {
728
+ className: "rounded-full",
729
+ asset,
730
+ size: "xxs",
731
+ noChain: true
732
+ }
733
+ ),
734
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs font-medium uppercase", children: asset.symbol }),
735
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
736
+ _chunkGZUTUD5Ocjs.DropdownIcon,
737
+ {
738
+ className: "w-1.5 opacity-60",
739
+ style: { color: "var(--widget-secondary-foreground)" }
740
+ }
741
+ )
742
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
743
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs opacity-70", children: "Select" }),
744
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
745
+ _chunkGZUTUD5Ocjs.DropdownIcon,
746
+ {
747
+ className: "w-1.5 opacity-60",
748
+ style: { color: "var(--widget-secondary-foreground)" }
749
+ }
750
+ )
751
+ ] })
752
+ }
753
+ );
754
+ }
755
+ if (tokenDisplay === "ghost") {
756
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
757
+ "div",
758
+ {
759
+ ...sharedProps,
760
+ className: "inline-flex items-center gap-1.5 cursor-pointer transition-opacity hover:opacity-70 py-1",
761
+ style: { color: "var(--widget-foreground)" },
762
+ children: [
763
+ asset ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
764
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.ChainIcon_default, { chain: asset.chainId, size: "xs" }),
765
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
766
+ _chunkGZUTUD5Ocjs.TokenImage_default,
767
+ {
768
+ className: "rounded-full",
769
+ asset,
770
+ size: "xxs",
771
+ noChain: true
772
+ }
773
+ ),
774
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium uppercase", children: asset.symbol })
775
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
776
+ "span",
777
+ {
778
+ className: "text-sm",
779
+ style: { color: "var(--widget-muted-foreground)" },
780
+ children: "Select token"
781
+ }
782
+ ),
783
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.DropdownIcon, { className: "w-1.5 opacity-50" })
784
+ ]
785
+ }
786
+ );
787
+ }
788
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
789
+ "div",
790
+ {
791
+ ...sharedProps,
792
+ className: `relative ${cardHeight} w-full cursor-pointer text-xl duration-100 ease-linear`,
793
+ style: {
794
+ border: "1px solid var(--widget-border)",
795
+ backgroundColor: "var(--widget-secondary)",
796
+ borderTopLeftRadius: "9999px",
797
+ borderBottomLeftRadius: "9999px",
798
+ borderTopRightRadius: "var(--widget-radius)",
799
+ borderBottomRightRadius: "var(--widget-radius)"
800
+ },
801
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex h-full w-full flex-row items-center", children: asset ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex h-full w-full flex-row items-center", children: [
802
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
803
+ "div",
804
+ {
805
+ className: `${iconSize} pl-px flex items-center justify-center`,
806
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.TokenImage_default, { className: "rounded-full", asset, size: "md" })
807
+ }
808
+ ),
809
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full w-full flex-row items-center justify-between pl-1.5 pr-7", children: [
810
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col justify-center", children: [
811
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
812
+ "p",
813
+ {
814
+ className: "text-sm font-medium uppercase",
815
+ style: { color: "var(--widget-secondary-foreground)" },
816
+ children: asset.symbol
817
+ }
818
+ ),
819
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
820
+ "span",
821
+ {
822
+ className: "text-2xs font-mono",
823
+ style: {
824
+ color: "var(--widget-secondary-foreground)",
825
+ opacity: 0.6
826
+ },
827
+ children: [
828
+ _optionalChain([asset, 'access', _39 => _39.address, 'optionalAccess', _40 => _40.slice, 'call', _41 => _41(0, 6)]),
829
+ "...",
830
+ _optionalChain([asset, 'access', _42 => _42.address, 'optionalAccess', _43 => _43.slice, 'call', _44 => _44(-4)])
831
+ ]
832
+ }
833
+ )
834
+ ] }),
835
+ userBalance !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col text-right", children: [
836
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
837
+ "p",
838
+ {
839
+ className: "text-2xs",
840
+ style: {
841
+ color: "var(--widget-secondary-foreground)",
842
+ opacity: 0.5
843
+ },
844
+ children: "Balance"
845
+ }
846
+ ),
847
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
848
+ "span",
849
+ {
850
+ className: "font-mono text-xs tabular-nums",
851
+ style: { color: "var(--widget-secondary-foreground)" },
852
+ children: userBalance
853
+ }
854
+ )
855
+ ] })
856
+ ] }),
857
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
858
+ _chunkGZUTUD5Ocjs.DropdownIcon,
859
+ {
860
+ className: "absolute right-3 top-1/2 w-1.5 translate-y-[-50%]",
861
+ style: {
862
+ color: "var(--widget-secondary-foreground)",
863
+ opacity: 0.6
864
+ }
865
+ }
866
+ )
867
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
868
+ "span",
869
+ {
870
+ className: "text-sm",
871
+ style: {
872
+ color: "var(--widget-secondary-foreground)",
873
+ opacity: 0.7
874
+ },
875
+ children: "Select token"
876
+ }
877
+ ) }) })
878
+ }
879
+ );
880
+ };
881
+ var AssetSelection_default = AssetSelection;
882
+
883
+ // src/components/RecipientForm.tsx
884
+ var import_ethereum_gradient_base64 = _chunkNBJPKJBCcjs.__toESM.call(void 0, _chunk5TH6MFQDcjs.require_main.call(void 0, ), 1);
885
+
886
+
887
+ var RecipientForm = () => {
888
+ const [recipient, setRecipient] = _react.useState.call(void 0, null);
889
+ const [inputValue, setInputValue] = _react.useState.call(void 0, "");
890
+ const debouncedValue = _chunkGZUTUD5Ocjs.useDebounce.call(void 0, inputValue, 1e3);
891
+ const [isError, setIsError] = _react.useState.call(void 0, false);
892
+ const [errorMessage, setErrorMessage] = _react.useState.call(void 0, "");
893
+ _react.useEffect.call(void 0, () => {
894
+ _chunk6XB5R4GFcjs.useWidgetSwapUIStore.getState().setRecipient(recipient);
895
+ }, [recipient]);
896
+ _react.useEffect.call(void 0, () => {
897
+ if (recipient) setInputValue(recipient);
898
+ else setInputValue("");
899
+ }, [recipient]);
900
+ const handleInputChange = (e) => {
901
+ const value = e.target.value;
902
+ if (isError) {
903
+ setIsError(false);
904
+ setErrorMessage("");
905
+ setRecipient(null);
906
+ }
907
+ setInputValue(value);
908
+ if (value === "") setRecipient(null);
909
+ };
910
+ _react.useEffect.call(void 0, () => {
911
+ if (debouncedValue === "" || !debouncedValue) {
912
+ setIsError(false);
913
+ setErrorMessage("");
914
+ setRecipient(null);
915
+ } else if (!_chunkGZUTUD5Ocjs.isAddress.call(void 0, debouncedValue)) {
916
+ setIsError(true);
917
+ setErrorMessage("Invalid wallet address...");
918
+ setRecipient(null);
919
+ setInputValue("");
920
+ } else {
921
+ setIsError(false);
922
+ setErrorMessage("");
923
+ setRecipient(debouncedValue);
924
+ }
925
+ }, [debouncedValue]);
926
+ _react.useEffect.call(void 0, () => {
927
+ if (isError) {
928
+ const timeout = setTimeout(() => {
929
+ setRecipient(null);
930
+ setInputValue("");
931
+ setIsError(false);
932
+ setErrorMessage("");
933
+ }, 2e3);
934
+ return () => clearTimeout(timeout);
935
+ }
936
+ }, [isError]);
937
+ const handleClear = () => {
938
+ setRecipient(null);
939
+ setInputValue("");
940
+ setIsError(false);
941
+ setErrorMessage("");
942
+ };
943
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex flex-row items-center", children: [
944
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
945
+ "input",
946
+ {
947
+ type: "password",
948
+ style: { display: "none" },
949
+ "aria-hidden": "true",
950
+ tabIndex: -1
951
+ }
952
+ ),
953
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { htmlFor: "recipient-address", className: "sr-only", children: "Recipient wallet address" }),
954
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
955
+ "div",
956
+ {
957
+ className: "absolute left-3 flex h-6 w-6 items-end justify-center overflow-hidden rounded-full",
958
+ style: { backgroundColor: "var(--widget-secondary)" },
959
+ children: recipient && !isError ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
960
+ "img",
961
+ {
962
+ className: "h-full w-full rounded-full object-cover",
963
+ src: (0, import_ethereum_gradient_base64.makeGradient)(recipient),
964
+ alt: "Recipient avatar"
965
+ }
966
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
967
+ _chunkGZUTUD5Ocjs.UserIcon,
968
+ {
969
+ className: "h-5 w-5",
970
+ style: {
971
+ color: isError ? "var(--widget-destructive)" : "var(--widget-muted-foreground)"
972
+ }
973
+ }
974
+ )
975
+ }
976
+ ),
977
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
978
+ "div",
979
+ {
980
+ className: "absolute left-12 top-1.5 -translate-y-1 text-xs font-medium opacity-60",
981
+ style: {
982
+ color: isError ? "var(--widget-destructive)" : "var(--widget-muted-foreground)"
983
+ },
984
+ "aria-hidden": "true",
985
+ children: "To:"
986
+ }
987
+ ),
988
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
989
+ "input",
990
+ {
991
+ id: "recipient-address",
992
+ className: "mono block h-10 w-full items-center pl-12 pt-4 pr-8 text-xs",
993
+ style: {
994
+ backgroundColor: isError ? `color-mix(in srgb, var(--widget-destructive) 10%, transparent)` : "transparent",
995
+ color: isError ? "var(--widget-destructive)" : "var(--widget-foreground)",
996
+ outline: "none",
997
+ opacity: isError ? 0.9 : 1
998
+ },
999
+ placeholder: isError ? errorMessage : "Enter recipient address...",
1000
+ value: inputValue,
1001
+ onChange: handleInputChange,
1002
+ spellCheck: false,
1003
+ "aria-invalid": isError,
1004
+ "aria-describedby": isError ? "recipient-error" : void 0
1005
+ }
1006
+ ),
1007
+ isError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: "recipient-error", className: "sr-only", children: errorMessage }),
1008
+ recipient && !isError && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1009
+ "button",
1010
+ {
1011
+ type: "button",
1012
+ className: "absolute right-2 top-1/2 -translate-y-1/2 cursor-pointer flex items-center justify-center h-4 w-4 rounded-full transition-colors hover:[color:var(--widget-destructive)]",
1013
+ style: { color: "var(--widget-muted-foreground)" },
1014
+ onClick: handleClear,
1015
+ "aria-label": "Clear recipient",
1016
+ children: [
1017
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "h-2.5 w-2.5", viewBox: "0 -0.5 21 21", fill: "none", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "g", { fill: "currentColor", fillRule: "evenodd", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1018
+ "polygon",
1019
+ {
1020
+ points: "375.0183 90 384 98.554 382.48065 100 373.5 91.446 364.5183 100 363 98.554 371.98065 90 363 81.446 364.5183 80 373.5 88.554 382.48065 80 384 81.446",
1021
+ transform: "translate(-363 -80)"
1022
+ }
1023
+ ) }) }),
1024
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Clear recipient" })
1025
+ ]
1026
+ }
1027
+ )
1028
+ ] }) });
1029
+ };
1030
+ var RecipientForm_default = RecipientForm;
1031
+
1032
+ // src/lib/pollOrderStatus.ts
1033
+ var TERMINAL_STATUSES = ["SUCCEEDED", "FAILED", "COMPLETED", "CANCELLED"];
1034
+ async function pollOrderStatus(quoteId, baseUrl, options = {}) {
1035
+ const {
1036
+ onStatusChange,
1037
+ onComplete,
1038
+ onError,
1039
+ interval = 4e3,
1040
+ timeout = 3e5,
1041
+ txHash,
1042
+ signal
1043
+ } = options;
1044
+ let lastStatus = null;
1045
+ const startTime = Date.now();
1046
+ let consecutiveErrorCount = 0;
1047
+ const MAX_CONSECUTIVE_ERRORS = 8;
1048
+ let timeoutId = null;
1049
+ const queryString = txHash ? `?txHash=${txHash}` : "";
1050
+ return new Promise((resolve, reject) => {
1051
+ const checkStatus = async () => {
1052
+ try {
1053
+ if (_optionalChain([signal, 'optionalAccess', _45 => _45.aborted])) {
1054
+ if (timeoutId) clearTimeout(timeoutId);
1055
+ reject(new DOMException("Polling aborted", "AbortError"));
1056
+ return;
1057
+ }
1058
+ if (Date.now() - startTime > timeout) {
1059
+ if (timeoutId) clearTimeout(timeoutId);
1060
+ const error = new Error("Order status polling timed out");
1061
+ _optionalChain([onError, 'optionalCall', _46 => _46(error)]);
1062
+ reject(error);
1063
+ return;
1064
+ }
1065
+ const response = await fetch(`${baseUrl}/status/${quoteId}${queryString}`, {
1066
+ headers: _chunkGZUTUD5Ocjs.getVtHeaders.call(void 0, ),
1067
+ signal
1068
+ });
1069
+ if (response.status === 404) {
1070
+ timeoutId = setTimeout(checkStatus, interval);
1071
+ return;
1072
+ }
1073
+ if (!response.ok) {
1074
+ throw new Error(`Failed to fetch order status: ${await response.text()}`);
1075
+ }
1076
+ const status = await response.json();
1077
+ if (!status || typeof status !== "object" || !status.status) {
1078
+ throw new Error(`Invalid status response format: ${JSON.stringify(status)}`);
1079
+ }
1080
+ consecutiveErrorCount = 0;
1081
+ const normalized = status.status.toUpperCase();
1082
+ if (normalized !== lastStatus) {
1083
+ lastStatus = normalized;
1084
+ _optionalChain([onStatusChange, 'optionalCall', _47 => _47(status)]);
1085
+ }
1086
+ if (TERMINAL_STATUSES.includes(normalized)) {
1087
+ if (timeoutId) clearTimeout(timeoutId);
1088
+ _optionalChain([onComplete, 'optionalCall', _48 => _48(status)]);
1089
+ resolve(status);
1090
+ return;
1091
+ }
1092
+ timeoutId = setTimeout(checkStatus, interval);
1093
+ } catch (error) {
1094
+ if (error instanceof Error && error.name === "AbortError") {
1095
+ if (timeoutId) clearTimeout(timeoutId);
1096
+ reject(error);
1097
+ return;
1098
+ }
1099
+ if (++consecutiveErrorCount >= MAX_CONSECUTIVE_ERRORS) {
1100
+ if (timeoutId) clearTimeout(timeoutId);
1101
+ const err = error instanceof Error ? error : new Error(String(error));
1102
+ _optionalChain([onError, 'optionalCall', _49 => _49(err)]);
1103
+ reject(err);
1104
+ return;
1105
+ }
1106
+ timeoutId = setTimeout(checkStatus, interval);
1107
+ }
1108
+ };
1109
+ checkStatus();
1110
+ });
1111
+ }
1112
+
1113
+ // src/hooks/useOrderStatusPolling.ts
1114
+
1115
+ function normalizeStatus(vtStatus) {
1116
+ const upper = vtStatus.toUpperCase();
1117
+ if (upper === "SUCCEEDED" || upper === "COMPLETED") return "completed";
1118
+ if (upper === "FAILED") return "failed";
1119
+ if (upper === "CANCELLED") return "cancelled";
1120
+ if (upper === "PROCESSING") return "received";
1121
+ return "pending";
1122
+ }
1123
+ var useOrderStatusPolling = (onStatusUpdate) => {
1124
+ const activePolls = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
1125
+ const orderMetadata = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
1126
+ const abortControllers = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
1127
+ const pollingLock = _react.useRef.call(void 0, 0);
1128
+ const incrementPollingLock = _react.useCallback.call(void 0, () => ++pollingLock.current, []);
1129
+ const { address: userAddress } = _chunkPGYOJ5RBcjs.useWalletState.call(void 0, );
1130
+ const emitBalanceEvent = useEmitBalanceEvent();
1131
+ const startPolling = _react.useCallback.call(void 0,
1132
+ (quoteId, metadata) => {
1133
+ if (activePolls.current.get(quoteId)) return;
1134
+ if (metadata) orderMetadata.current.set(quoteId, metadata);
1135
+ activePolls.current.set(quoteId, true);
1136
+ const currentLock = pollingLock.current;
1137
+ const abortController = new AbortController();
1138
+ abortControllers.current.set(quoteId, abortController);
1139
+ const isMainnet = _optionalChain([metadata, 'optionalAccess', _50 => _50.baseToken, 'optionalAccess', _51 => _51.chainId]) === 1;
1140
+ pollOrderStatus(
1141
+ quoteId,
1142
+ _chunkGZUTUD5Ocjs.getVtApiUrl.call(void 0, ),
1143
+ {
1144
+ interval: isMainnet ? 1e3 : 500,
1145
+ timeout: 3e5,
1146
+ signal: abortController.signal,
1147
+ onStatusChange: (status) => {
1148
+ if (!_optionalChain([status, 'optionalAccess', _52 => _52.status])) return;
1149
+ const statusValue = normalizeStatus(status.status);
1150
+ _optionalChain([onStatusUpdate, 'optionalCall', _53 => _53(quoteId, statusValue)]);
1151
+ if (statusValue === "completed" && userAddress) {
1152
+ const meta = orderMetadata.current.get(quoteId);
1153
+ if (meta && (meta.baseToken || meta.quoteToken)) {
1154
+ const tokens = [];
1155
+ if (meta.baseToken) tokens.push({ asset: meta.baseToken, userAddress });
1156
+ if (meta.quoteToken) tokens.push({ asset: meta.quoteToken, userAddress });
1157
+ emitBalanceEvent({ type: "swap", tokens });
1158
+ }
1159
+ }
1160
+ if (["completed", "failed", "cancelled"].includes(statusValue)) {
1161
+ activePolls.current.delete(quoteId);
1162
+ orderMetadata.current.delete(quoteId);
1163
+ }
1164
+ if (currentLock !== pollingLock.current) {
1165
+ activePolls.current.delete(quoteId);
1166
+ orderMetadata.current.delete(quoteId);
1167
+ }
1168
+ },
1169
+ onComplete: (status) => {
1170
+ if (_optionalChain([status, 'optionalAccess', _54 => _54.status])) {
1171
+ _optionalChain([onStatusUpdate, 'optionalCall', _55 => _55(quoteId, normalizeStatus(status.status))]);
1172
+ }
1173
+ activePolls.current.delete(quoteId);
1174
+ orderMetadata.current.delete(quoteId);
1175
+ },
1176
+ onError: () => {
1177
+ activePolls.current.delete(quoteId);
1178
+ orderMetadata.current.delete(quoteId);
1179
+ }
1180
+ }
1181
+ ).catch((error) => {
1182
+ if (error instanceof Error && error.name === "AbortError") return;
1183
+ activePolls.current.delete(quoteId);
1184
+ orderMetadata.current.delete(quoteId);
1185
+ abortControllers.current.delete(quoteId);
1186
+ });
1187
+ },
1188
+ [userAddress, emitBalanceEvent, onStatusUpdate]
1189
+ );
1190
+ const stopPolling = _react.useCallback.call(void 0,
1191
+ (quoteId) => {
1192
+ const controller = abortControllers.current.get(quoteId);
1193
+ if (controller) {
1194
+ controller.abort();
1195
+ abortControllers.current.delete(quoteId);
1196
+ }
1197
+ incrementPollingLock();
1198
+ activePolls.current.delete(quoteId);
1199
+ orderMetadata.current.delete(quoteId);
1200
+ },
1201
+ [incrementPollingLock]
1202
+ );
1203
+ const stopAllPolling = _react.useCallback.call(void 0, () => {
1204
+ for (const controller of abortControllers.current.values()) controller.abort();
1205
+ abortControllers.current.clear();
1206
+ incrementPollingLock();
1207
+ activePolls.current.clear();
1208
+ orderMetadata.current.clear();
1209
+ }, [incrementPollingLock]);
1210
+ _react.useEffect.call(void 0, () => {
1211
+ return () => stopAllPolling();
1212
+ }, [stopAllPolling]);
1213
+ return {
1214
+ startPolling,
1215
+ stopPolling,
1216
+ stopAllPolling,
1217
+ isPolling: (quoteId) => activePolls.current.has(quoteId)
1218
+ };
1219
+ };
1220
+
1221
+ // src/wallet/TransactionRegistryContext.tsx
1222
+
1223
+ var TransactionRegistryContext = _react.createContext.call(void 0, {
1224
+ registerTransaction: () => {
1225
+ },
1226
+ enabled: false
1227
+ });
1228
+ var useTransactionRegistry = () => _react.useContext.call(void 0, TransactionRegistryContext);
1229
+
1230
+ // src/lib/signSwap.ts
1231
+ var _actions = require('viem/actions');
1232
+ function isUserRejection(error) {
1233
+ if (!(error instanceof Error)) return false;
1234
+ return error.name === "UserRejectedRequestError" || error.message.includes("User rejected") || error.message.includes("rejected") || error.message.includes("denied") || error.message.includes("cancelled") || error.message.includes("canceled");
1235
+ }
1236
+ async function resolveChainId(walletClient) {
1237
+ if (_optionalChain([walletClient, 'access', _56 => _56.chain, 'optionalAccess', _57 => _57.id])) return walletClient.chain.id;
1238
+ const result = _optionalChain([walletClient, 'access', _58 => _58.getChainId, 'optionalCall', _59 => _59()]);
1239
+ if (result != null) return await result;
1240
+ return null;
1241
+ }
1242
+ var ChainSwitch = async (walletClient, requiredChainId) => {
1243
+ try {
1244
+ const currentChainId = await resolveChainId(walletClient);
1245
+ if (currentChainId === requiredChainId) return true;
1246
+ if (walletClient.request) {
1247
+ await walletClient.request({
1248
+ method: "wallet_switchEthereumChain",
1249
+ params: [{ chainId: `0x${requiredChainId.toString(16)}` }]
1250
+ });
1251
+ } else if (walletClient.switchChain) {
1252
+ await walletClient.switchChain({ id: requiredChainId });
1253
+ } else if (walletClient.send) {
1254
+ await walletClient.send("wallet_switchEthereumChain", [
1255
+ { chainId: `0x${requiredChainId.toString(16)}` }
1256
+ ]);
1257
+ } else {
1258
+ throw new Error("Wallet doesn't support chain switching");
1259
+ }
1260
+ const newChainId = await resolveChainId(walletClient);
1261
+ return newChainId === requiredChainId;
1262
+ } catch (error) {
1263
+ if (isUserRejection(error)) {
1264
+ throw new Error("User rejected the chain switch request");
1265
+ }
1266
+ throw new Error(
1267
+ `Please switch your wallet to the required network (Chain ID: ${requiredChainId})`
1268
+ );
1269
+ }
1270
+ };
1271
+ var SignSwap = async (params) => {
1272
+ const { quote, signatureStep, userAddress, walletClient } = params;
1273
+ if (!walletClient) throw new Error("Wallet client not available");
1274
+ if (signatureStep.type !== "SIGNATURE" || !_optionalChain([signatureStep, 'access', _60 => _60.signature, 'optionalAccess', _61 => _61.typedData]))
1275
+ throw new Error("Invalid signature step");
1276
+ try {
1277
+ const typed = signatureStep.signature.typedData;
1278
+ const normalizedMessage = { ...typed.message };
1279
+ for (const key of ["inputAmount", "outputAmount", "startTime", "endTime"]) {
1280
+ if (normalizedMessage[key] != null) {
1281
+ normalizedMessage[key] = BigInt(normalizedMessage[key]);
1282
+ }
1283
+ }
1284
+ const domain = typed.domain;
1285
+ if (domain.chainId != null) {
1286
+ const chainId = Number(domain.chainId);
1287
+ await ChainSwitch(walletClient, chainId);
1288
+ }
1289
+ const signature = await _actions.signTypedData.call(void 0, walletClient, {
1290
+ account: userAddress,
1291
+ domain,
1292
+ types: typed.types,
1293
+ primaryType: typed.primaryType,
1294
+ message: normalizedMessage
1295
+ });
1296
+ const submitRes = await fetch(`${_chunkGZUTUD5Ocjs.getVtApiUrl.call(void 0, )}/submit-signature`, {
1297
+ method: "POST",
1298
+ headers: _chunkGZUTUD5Ocjs.getVtHeaders.call(void 0, ),
1299
+ body: JSON.stringify({
1300
+ quoteId: quote.id,
1301
+ signatures: [signature]
1302
+ })
1303
+ });
1304
+ if (!submitRes.ok) {
1305
+ const errBody = await submitRes.json().catch(() => ({}));
1306
+ throw new Error(_optionalChain([errBody, 'optionalAccess', _62 => _62.message]) || `Submit failed: ${submitRes.status}`);
1307
+ }
1308
+ return { quoteId: quote.id, signature };
1309
+ } catch (error) {
1310
+ if (isUserRejection(error)) {
1311
+ throw new Error("User rejected the signing request");
1312
+ }
1313
+ if (error instanceof Error && error.message.includes("chain")) {
1314
+ throw new Error("Chain switching failed. Please manually switch to the correct network.");
1315
+ }
1316
+ throw error;
1317
+ }
1318
+ };
1319
+
1320
+ // src/lib/submitTracker.ts
1321
+ var STORAGE_KEY = "vt_submitted_quotes";
1322
+ var QUOTE_EXPIRATION_MS = 30 * 1e3;
1323
+ var getSubmittedQuotes = () => {
1324
+ try {
1325
+ const stored = localStorage.getItem(STORAGE_KEY);
1326
+ return stored ? JSON.parse(stored) : [];
1327
+ } catch (e3) {
1328
+ return [];
1329
+ }
1330
+ };
1331
+ var saveSubmittedQuotes = (quotes) => {
1332
+ try {
1333
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(quotes));
1334
+ } catch (e4) {
1335
+ }
1336
+ };
1337
+ var isQuoteFresh = (createdAt) => {
1338
+ const now = Date.now();
1339
+ const createdMs = typeof createdAt === "string" ? new Date(createdAt).getTime() : createdAt > 9999999999 ? createdAt : createdAt * 1e3;
1340
+ return now < createdMs + QUOTE_EXPIRATION_MS;
1341
+ };
1342
+ var isOrderAlreadySubmitted = (quoteId) => {
1343
+ return getSubmittedQuotes().some((q) => q.quoteId === quoteId);
1344
+ };
1345
+ var canSubmitOrder = (quoteId, createdAt) => {
1346
+ if (isOrderAlreadySubmitted(quoteId)) {
1347
+ return { canSubmit: false, reason: "Order already submitted" };
1348
+ }
1349
+ if (!isQuoteFresh(createdAt)) {
1350
+ return { canSubmit: false, reason: "Quote has expired" };
1351
+ }
1352
+ return { canSubmit: true };
1353
+ };
1354
+ var markOrderAsSubmitted = (quoteId, createdAt) => {
1355
+ const createdMs = typeof createdAt === "string" ? new Date(createdAt).getTime() : createdAt;
1356
+ const submitted = getSubmittedQuotes();
1357
+ submitted.push({ quoteId, submittedAt: Date.now(), createdAt: createdMs });
1358
+ saveSubmittedQuotes(submitted);
1359
+ };
1360
+ var cleanupOldSubmissions = () => {
1361
+ const submitted = getSubmittedQuotes();
1362
+ const now = Date.now();
1363
+ const CLEANUP_THRESHOLD = 5 * 60 * 1e3;
1364
+ const cleaned = submitted.filter((q) => now - q.submittedAt < CLEANUP_THRESHOLD);
1365
+ if (cleaned.length !== submitted.length) saveSubmittedQuotes(cleaned);
1366
+ };
1367
+
1368
+ // src/queries/useUnwrapToken.ts
1369
+
1370
+ var _core = require('@wagmi/core');
1371
+ var _abis = require('abitype/abis');
1372
+ var _wagmi = require('wagmi');
1373
+ function useUnwrapToken() {
1374
+ const wagmiConfig = _wagmi.useConfig.call(void 0, );
1375
+ return _reactquery.useMutation.call(void 0, {
1376
+ mutationFn: async ({ chainId, accountAddress, amountRaw, writeContractAsync }) => {
1377
+ const chainConfig = _chunkGZUTUD5Ocjs.getChainConfig.call(void 0, chainId);
1378
+ if (!chainConfig) throw new Error(`No wrapping contract for chain ${chainId}`);
1379
+ const wNativeAddress = chainConfig.wrappedAsset.address;
1380
+ const hash = await writeContractAsync({
1381
+ abi: _abis.wethAbi,
1382
+ functionName: "withdraw",
1383
+ address: wNativeAddress,
1384
+ account: accountAddress,
1385
+ args: [amountRaw],
1386
+ chainId
1387
+ });
1388
+ const receipt = await _core.waitForTransactionReceipt.call(void 0, wagmiConfig, {
1389
+ hash,
1390
+ chainId,
1391
+ confirmations: 1,
1392
+ pollingInterval: 4e3
1393
+ });
1394
+ if (receipt.status !== "success") {
1395
+ throw new Error("Unwrap transaction did not get successful receipt");
1396
+ }
1397
+ return { success: true, hash };
1398
+ }
1399
+ });
1400
+ }
1401
+
1402
+ // src/queries/useWrapToken.ts
1403
+
1404
+
1405
+
1406
+
1407
+ function useWrapToken() {
1408
+ const wagmiConfig = _wagmi.useConfig.call(void 0, );
1409
+ return _reactquery.useMutation.call(void 0, {
1410
+ mutationFn: async ({ chainId, accountAddress, amountRaw, writeContractAsync }) => {
1411
+ const chainConfig = _chunkGZUTUD5Ocjs.getChainConfig.call(void 0, chainId);
1412
+ if (!chainConfig) throw new Error(`No wrapping contract for chain ${chainId}`);
1413
+ const wNativeAddress = chainConfig.wrappedAsset.address;
1414
+ const hash = await writeContractAsync({
1415
+ abi: _abis.wethAbi,
1416
+ functionName: "deposit",
1417
+ address: wNativeAddress,
1418
+ account: accountAddress,
1419
+ value: amountRaw,
1420
+ chainId
1421
+ });
1422
+ const receipt = await _core.waitForTransactionReceipt.call(void 0, wagmiConfig, {
1423
+ hash,
1424
+ chainId,
1425
+ confirmations: 1,
1426
+ pollingInterval: 4e3
1427
+ });
1428
+ if (receipt.status !== "success") {
1429
+ throw new Error("Wrap transaction did not get successful receipt");
1430
+ }
1431
+ return { success: true, hash };
1432
+ }
1433
+ });
1434
+ }
1435
+
1436
+ // src/components/states/SwapButton.tsx
1437
+
1438
+
1439
+
1440
+ // src/wallet/useTransactionTracker.ts
1441
+
1442
+ function useTransactionTracker() {
1443
+ const { registerTransaction, enabled } = useTransactionRegistry();
1444
+ const registeredRef = _react.useRef.call(void 0, /* @__PURE__ */ new Set());
1445
+ const trackOrderTransaction = _react.useCallback.call(void 0,
1446
+ (quoteId, description) => {
1447
+ if (!enabled || registeredRef.current.has(quoteId)) return;
1448
+ registeredRef.current.add(quoteId);
1449
+ registerTransaction(quoteId, description);
1450
+ },
1451
+ [enabled, registerTransaction]
1452
+ );
1453
+ const trackNativeTransaction = _react.useCallback.call(void 0,
1454
+ (txHash, description) => {
1455
+ if (!enabled || registeredRef.current.has(txHash)) return;
1456
+ registeredRef.current.add(txHash);
1457
+ registerTransaction(txHash, description);
1458
+ },
1459
+ [enabled, registerTransaction]
1460
+ );
1461
+ return { trackOrderTransaction, trackNativeTransaction, txTrackingEnabled: enabled };
1462
+ }
1463
+
1464
+ // src/components/states/ReviewActionChainSwitchRow.tsx
1465
+
1466
+
1467
+
1468
+ var WALLET_TIMEOUT_MS = 15e3;
1469
+ var ComponentStep = "chain";
1470
+ var ReviewActionChainSwitchRow = ({
1471
+ needsChainSwitch,
1472
+ requiredChain,
1473
+ reviewState,
1474
+ goToNextStep,
1475
+ cancel
1476
+ }) => {
1477
+ const hasSucceeded = _chunkGZUTUD5Ocjs.isReviewStepPast.call(void 0, ComponentStep, reviewState);
1478
+ const [chainState, setChainState] = _react.useState.call(void 0, "pending");
1479
+ const isSwitching = _react.useRef.call(void 0, false);
1480
+ const switchAttempted = _react.useRef.call(void 0, false);
1481
+ const timeoutRef = _react.useRef.call(void 0, null);
1482
+ const currentChainId = _wagmi.useChainId.call(void 0, );
1483
+ const { switchChainAsync } = _wagmi.useSwitchChain.call(void 0, );
1484
+ const { status: wagmiStatus, isReconnecting } = _wagmi.useAccount.call(void 0, );
1485
+ const clearPendingTimeout = _react.useCallback.call(void 0, () => {
1486
+ if (timeoutRef.current) {
1487
+ clearTimeout(timeoutRef.current);
1488
+ timeoutRef.current = null;
1489
+ }
1490
+ }, []);
1491
+ const handleChainSwitch = _react.useCallback.call(void 0, async () => {
1492
+ if (isSwitching.current || switchAttempted.current || wagmiStatus !== "connected" || isReconnecting) return;
1493
+ isSwitching.current = true;
1494
+ switchAttempted.current = true;
1495
+ setChainState("pending");
1496
+ timeoutRef.current = setTimeout(() => {
1497
+ if (isSwitching.current) {
1498
+ setChainState("error");
1499
+ isSwitching.current = false;
1500
+ }
1501
+ }, WALLET_TIMEOUT_MS);
1502
+ try {
1503
+ await switchChainAsync({ chainId: requiredChain.chainId });
1504
+ clearPendingTimeout();
1505
+ setChainState("success");
1506
+ goToNextStep(ComponentStep, reviewState);
1507
+ } catch (e5) {
1508
+ clearPendingTimeout();
1509
+ setChainState("error");
1510
+ } finally {
1511
+ isSwitching.current = false;
1512
+ }
1513
+ }, [switchChainAsync, wagmiStatus, isReconnecting, requiredChain.chainId, goToNextStep, reviewState, clearPendingTimeout]);
1514
+ _react.useEffect.call(void 0, () => {
1515
+ if (isSwitching.current || switchAttempted.current) return;
1516
+ if (reviewState === ComponentStep && chainState === "pending" && wagmiStatus === "connected" && !isReconnecting) {
1517
+ if (needsChainSwitch && currentChainId !== requiredChain.chainId) handleChainSwitch();
1518
+ else {
1519
+ setChainState("success");
1520
+ goToNextStep(ComponentStep, reviewState);
1521
+ }
1522
+ }
1523
+ }, [reviewState, chainState, needsChainSwitch, currentChainId, requiredChain.chainId, wagmiStatus, isReconnecting, handleChainSwitch, goToNextStep]);
1524
+ _react.useEffect.call(void 0, () => () => clearPendingTimeout(), [clearPendingTimeout]);
1525
+ const handleRetry = () => {
1526
+ if (chainState === "error") {
1527
+ switchAttempted.current = false;
1528
+ setChainState("pending");
1529
+ }
1530
+ };
1531
+ const isError = !hasSucceeded && chainState === "error";
1532
+ const showCancel = !hasSucceeded && (chainState === "pending" || chainState === "error");
1533
+ const statusVar = isError ? "var(--widget-status-failed)" : "var(--widget-status-pending)";
1534
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between space-x-3", children: [
1535
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1536
+ "button",
1537
+ {
1538
+ type: "button",
1539
+ className: `inline-flex h-12 w-full items-center justify-center text-sm font-medium transition duration-150 ${isError ? "cursor-pointer" : "cursor-not-allowed"}`,
1540
+ style: {
1541
+ backgroundColor: `color-mix(in srgb, ${statusVar} 12%, transparent)`,
1542
+ border: `1px solid color-mix(in srgb, ${statusVar} 20%, transparent)`,
1543
+ color: statusVar,
1544
+ borderRadius: "var(--widget-radius)"
1545
+ },
1546
+ onClick: isError ? handleRetry : void 0,
1547
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 w-full flex-row items-center space-x-3 px-4", children: [
1548
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.ChainIcon_default, { chain: requiredChain.chainId, size: "xs" }),
1549
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-nowrap", children: isError ? "Retry Switch" : `Switch to ${requiredChain.name}` }),
1550
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-1 border-t", style: { borderColor: "var(--widget-border)" } }),
1551
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-6 w-3 items-center justify-center rounded-full", children: [
1552
+ !hasSucceeded && chainState === "pending" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
1553
+ (hasSucceeded || chainState === "success") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, { className: "h-8 w-8" }),
1554
+ isError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.RedoIcon, { className: "h-[12px] w-[12px]" })
1555
+ ] })
1556
+ ] })
1557
+ }
1558
+ ),
1559
+ showCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1560
+ "button",
1561
+ {
1562
+ type: "button",
1563
+ className: "inline-flex h-12 items-center justify-center px-8 text-sm font-medium transition duration-150 cursor-pointer",
1564
+ style: {
1565
+ backgroundColor: "color-mix(in srgb, var(--widget-status-failed) 12%, transparent)",
1566
+ border: "1px solid color-mix(in srgb, var(--widget-status-failed) 20%, transparent)",
1567
+ color: "var(--widget-status-failed)",
1568
+ borderRadius: "var(--widget-radius)"
1569
+ },
1570
+ onClick: cancel,
1571
+ children: "Cancel"
1572
+ }
1573
+ )
1574
+ ] });
1575
+ };
1576
+ var ReviewActionChainSwitchRow_default = ReviewActionChainSwitchRow;
1577
+
1578
+ // src/components/states/ReviewActionSignAndSubmitOrderRow.tsx
1579
+
1580
+
1581
+
1582
+
1583
+ // src/components/CountDown.tsx
1584
+
1585
+
1586
+ var CountDown = ({ startTime, onExpired }) => {
1587
+ const [timeLeft, setTimeLeft] = _react.useState.call(void 0, 30);
1588
+ const [isExpired, setIsExpired] = _react.useState.call(void 0, false);
1589
+ const firedRef = _react.useRef.call(void 0, false);
1590
+ const onExpiredRef = _react.useRef.call(void 0, onExpired);
1591
+ onExpiredRef.current = onExpired;
1592
+ _react.useEffect.call(void 0, () => {
1593
+ firedRef.current = false;
1594
+ }, [startTime]);
1595
+ _react.useEffect.call(void 0, () => {
1596
+ const calculateTimeLeft = () => {
1597
+ const now = Date.now();
1598
+ const startTimeMs = startTime > 9999999999 ? startTime : startTime * 1e3;
1599
+ const expirationTime = startTimeMs + 30 * 1e3;
1600
+ const remaining = Math.max(0, expirationTime - now);
1601
+ const remainingSeconds = Math.floor(remaining / 1e3);
1602
+ if (remainingSeconds <= 0) {
1603
+ setTimeLeft(0);
1604
+ if (!firedRef.current) {
1605
+ firedRef.current = true;
1606
+ setIsExpired(true);
1607
+ onExpiredRef.current();
1608
+ }
1609
+ return;
1610
+ }
1611
+ setTimeLeft(remainingSeconds);
1612
+ setIsExpired(false);
1613
+ };
1614
+ if (isExpired) return;
1615
+ calculateTimeLeft();
1616
+ const interval = setInterval(calculateTimeLeft, 1e3);
1617
+ return () => clearInterval(interval);
1618
+ }, [startTime, isExpired]);
1619
+ const formatTime = (seconds) => {
1620
+ const mins = Math.floor(seconds / 60);
1621
+ const secs = seconds % 60;
1622
+ return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
1623
+ };
1624
+ if (isExpired) return null;
1625
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs font-mono", children: formatTime(timeLeft) });
1626
+ };
1627
+ var CountDown_default = CountDown;
1628
+
1629
+ // src/components/states/ReviewActionSignAndSubmitOrderRow.tsx
1630
+
1631
+ function isUserRejectionError(error) {
1632
+ return error.name === "UserRejectedRequestError" || error.message.includes("User rejected") || error.message.includes("rejected") || error.message.includes("denied") || error.message.includes("cancelled") || error.message.includes("canceled");
1633
+ }
1634
+ var ComponentStep2 = "signingOrder";
1635
+ async function executeTransactionStep(step, userAddress, sendTransactionAsync, wagmiConfig, fallbackChainKey) {
1636
+ const encoded = _optionalChain([step, 'access', _63 => _63.transaction, 'optionalAccess', _64 => _64.encoded]);
1637
+ const to = _nullishCoalesce(_optionalChain([encoded, 'optionalAccess', _65 => _65.to]), () => ( step.to));
1638
+ const data = _nullishCoalesce(_optionalChain([encoded, 'optionalAccess', _66 => _66.data]), () => ( step.data));
1639
+ const value = _nullishCoalesce(_optionalChain([encoded, 'optionalAccess', _67 => _67.value]), () => ( step.value));
1640
+ if (!to) throw new Error('Transaction step missing "to" address');
1641
+ const encodedChainId = _optionalChain([encoded, 'optionalAccess', _68 => _68.chainId]);
1642
+ const resolvedChainKey = step.chainKey || fallbackChainKey;
1643
+ const chainId = encodedChainId || (resolvedChainKey ? _chunkGZUTUD5Ocjs.getChainIdForKey.call(void 0, resolvedChainKey) : void 0);
1644
+ if (!chainId) throw new Error(`Unknown chain: ${resolvedChainKey}`);
1645
+ const viemChain = _chunkGZUTUD5Ocjs.getViemChainById.call(void 0, )[chainId];
1646
+ const hash = await sendTransactionAsync({
1647
+ account: userAddress,
1648
+ chain: viemChain,
1649
+ to,
1650
+ data: data || "0x",
1651
+ value: BigInt(value || "0")
1652
+ });
1653
+ await _core.waitForTransactionReceipt.call(void 0, wagmiConfig, { hash, chainId });
1654
+ return hash;
1655
+ }
1656
+ var ReviewActionSignAndSubmitOrderRow = ({
1657
+ base,
1658
+ baseAmount,
1659
+ quote,
1660
+ quoteAmount,
1661
+ userAddress,
1662
+ reviewState,
1663
+ goToNextStep,
1664
+ cancel,
1665
+ isWrappingPair,
1666
+ isUnwrappingPair,
1667
+ restartSigningFlow,
1668
+ onSwapInitiated,
1669
+ onOrderSubmitted,
1670
+ onSwapComplete,
1671
+ startPolling,
1672
+ trackNativeTransaction
1673
+ }) => {
1674
+ const hasSucceeded = _chunkGZUTUD5Ocjs.isReviewStepPast.call(void 0, ComponentStep2, reviewState);
1675
+ const [signState, setSignState] = _react.useState.call(void 0, "idle");
1676
+ const isProcessing = _react.useRef.call(void 0, false);
1677
+ const hasAutoStartedRef = _react.useRef.call(void 0, null);
1678
+ const wagmiConfig = _wagmi.useConfig.call(void 0, );
1679
+ const { isReconnecting } = _wagmi.useAccount.call(void 0, );
1680
+ const { rfqQuote, stop: stopRfq, refresh } = useRfq();
1681
+ const { data: walletClient } = _wagmi.useWalletClient.call(void 0, { chainId: base.chainId });
1682
+ const { switchChain } = _wagmi.useSwitchChain.call(void 0, );
1683
+ const { sendTransactionAsync } = _wagmi.useSendTransaction.call(void 0, );
1684
+ const quoteReceivedAtMs = _nullishCoalesce(_optionalChain([rfqQuote, 'optionalAccess', _69 => _69._receivedAt]), () => ( 0));
1685
+ const isQuoteStale = _react.useCallback.call(void 0, () => {
1686
+ if (!quoteReceivedAtMs) return false;
1687
+ return Date.now() >= quoteReceivedAtMs + 30 * 1e3;
1688
+ }, [quoteReceivedAtMs]);
1689
+ const handleSignAndSubmit = _react.useCallback.call(void 0, async () => {
1690
+ if (isProcessing.current || !["idle", "error"].includes(signState)) return;
1691
+ if (!_optionalChain([rfqQuote, 'optionalAccess', _70 => _70.id]) || !_optionalChain([rfqQuote, 'optionalAccess', _71 => _71._receivedAt])) {
1692
+ setSignState("error");
1693
+ return;
1694
+ }
1695
+ const validation = canSubmitOrder(rfqQuote.id, rfqQuote._receivedAt);
1696
+ if (!validation.canSubmit) {
1697
+ setSignState("stale");
1698
+ return;
1699
+ }
1700
+ isProcessing.current = true;
1701
+ try {
1702
+ if (!walletClient) throw new Error("Wallet client not available");
1703
+ cleanupOldSubmissions();
1704
+ const steps = _nullishCoalesce(rfqQuote.userSteps, () => ( []));
1705
+ let lastTxHash;
1706
+ for (const step of steps) {
1707
+ if (step.type === "TRANSACTION") {
1708
+ setSignState("submitting");
1709
+ const resolvedKey = step.chainKey || rfqQuote.srcChainKey;
1710
+ const chainId = resolvedKey ? _chunkGZUTUD5Ocjs.getChainIdForKey.call(void 0, resolvedKey) : void 0;
1711
+ if (chainId && _optionalChain([walletClient, 'access', _72 => _72.chain, 'optionalAccess', _73 => _73.id]) !== chainId) {
1712
+ await switchChain({ chainId });
1713
+ await new Promise((r) => setTimeout(r, 800));
1714
+ }
1715
+ lastTxHash = await executeTransactionStep(step, userAddress, sendTransactionAsync, wagmiConfig, rfqQuote.srcChainKey);
1716
+ trackNativeTransaction(lastTxHash, step.description || `Tx on ${resolvedKey}`);
1717
+ } else if (step.type === "SIGNATURE") {
1718
+ setSignState("signing");
1719
+ await SignSwap({
1720
+ quote: rfqQuote,
1721
+ signatureStep: step,
1722
+ userAddress,
1723
+ walletClient
1724
+ });
1725
+ }
1726
+ }
1727
+ markOrderAsSubmitted(rfqQuote.id, rfqQuote._receivedAt);
1728
+ _optionalChain([onOrderSubmitted, 'optionalCall', _74 => _74(rfqQuote.id)]);
1729
+ startPolling(rfqQuote.id, { baseToken: base, quoteToken: quote });
1730
+ _optionalChain([onSwapInitiated, 'optionalCall', _75 => _75()]);
1731
+ stopRfq();
1732
+ setSignState("success");
1733
+ goToNextStep(ComponentStep2, reviewState);
1734
+ _optionalChain([onSwapComplete, 'optionalCall', _76 => _76(rfqQuote.id)]);
1735
+ } catch (error) {
1736
+ if (error instanceof Error && isUserRejectionError(error)) {
1737
+ hasAutoStartedRef.current = null;
1738
+ setSignState("idle");
1739
+ } else {
1740
+ setSignState("error");
1741
+ }
1742
+ } finally {
1743
+ isProcessing.current = false;
1744
+ }
1745
+ }, [signState, rfqQuote, walletClient, base, quote, userAddress, stopRfq, startPolling, goToNextStep, reviewState, onSwapComplete, switchChain, sendTransactionAsync, onSwapInitiated, onOrderSubmitted, trackNativeTransaction, wagmiConfig]);
1746
+ _react.useEffect.call(void 0, () => {
1747
+ if (reviewState === ComponentStep2) stopRfq();
1748
+ if (hasSucceeded && signState !== "success") {
1749
+ setSignState("success");
1750
+ goToNextStep(ComponentStep2, reviewState);
1751
+ return;
1752
+ }
1753
+ if (signState === "success") {
1754
+ goToNextStep(ComponentStep2, reviewState);
1755
+ return;
1756
+ }
1757
+ if (reviewState === ComponentStep2 && signState === "idle" && !_optionalChain([rfqQuote, 'optionalAccess', _77 => _77.id])) {
1758
+ setSignState("refreshingQuote");
1759
+ refresh();
1760
+ return;
1761
+ }
1762
+ if (reviewState === ComponentStep2 && signState === "idle" && walletClient && !isProcessing.current && !isReconnecting) {
1763
+ const currentId = _optionalChain([rfqQuote, 'optionalAccess', _78 => _78.id]) || null;
1764
+ if (currentId && hasAutoStartedRef.current !== currentId) {
1765
+ hasAutoStartedRef.current = currentId;
1766
+ handleSignAndSubmit();
1767
+ }
1768
+ }
1769
+ }, [hasSucceeded, reviewState, signState, walletClient, isReconnecting, handleSignAndSubmit, goToNextStep, _optionalChain([rfqQuote, 'optionalAccess', _79 => _79.id]), refresh, stopRfq]);
1770
+ _react.useEffect.call(void 0, () => {
1771
+ if (signState === "refreshingQuote" && _optionalChain([rfqQuote, 'optionalAccess', _80 => _80.id])) {
1772
+ setSignState("idle");
1773
+ }
1774
+ }, [signState, _optionalChain([rfqQuote, 'optionalAccess', _81 => _81.id])]);
1775
+ _react.useEffect.call(void 0, () => {
1776
+ if (reviewState !== ComponentStep2) hasAutoStartedRef.current = null;
1777
+ }, [reviewState]);
1778
+ _react.useEffect.call(void 0, () => {
1779
+ const interval = setInterval(() => {
1780
+ if (isQuoteStale() && !isProcessing.current && signState !== "submitting" && signState !== "success") {
1781
+ setSignState("stale");
1782
+ }
1783
+ }, 1e3);
1784
+ return () => clearInterval(interval);
1785
+ }, [isQuoteStale, signState]);
1786
+ const handleRetry = () => {
1787
+ if (signState === "error" && !isProcessing.current) {
1788
+ hasAutoStartedRef.current = null;
1789
+ setSignState("idle");
1790
+ }
1791
+ };
1792
+ const handleRefreshFromStale = _react.useCallback.call(void 0, () => {
1793
+ hasAutoStartedRef.current = null;
1794
+ setSignState("refreshingQuote");
1795
+ refresh();
1796
+ }, [refresh]);
1797
+ const handleCloseWalletAndRestart = _react.useCallback.call(void 0, () => {
1798
+ if (restartSigningFlow) {
1799
+ restartSigningFlow(true);
1800
+ } else {
1801
+ cancel();
1802
+ }
1803
+ }, [restartSigningFlow, cancel]);
1804
+ const buttonText = () => {
1805
+ if (signState === "error") return "Retry swap";
1806
+ if (signState === "signing") return "Sign Swap Order";
1807
+ if (signState === "submitting") return "Submitting...";
1808
+ if (signState === "refreshingQuote") return "Refreshing Quote...";
1809
+ if (signState === "stale") return "Quote Stale";
1810
+ return "Sign & Submit";
1811
+ };
1812
+ const isErrorOrStale = !hasSucceeded && (signState === "error" || signState === "stale");
1813
+ const statusVar = isErrorOrStale ? "var(--widget-status-failed)" : "var(--widget-status-pending)";
1814
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between space-x-3", children: [
1815
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1816
+ "button",
1817
+ {
1818
+ type: "button",
1819
+ className: `inline-flex h-12 w-full items-center justify-center text-sm font-medium transition duration-150 ${isErrorOrStale ? "cursor-pointer" : "cursor-not-allowed"}`,
1820
+ style: {
1821
+ backgroundColor: `color-mix(in srgb, ${statusVar} 12%, transparent)`,
1822
+ border: `1px solid color-mix(in srgb, ${statusVar} 20%, transparent)`,
1823
+ color: statusVar,
1824
+ borderRadius: "var(--widget-radius)"
1825
+ },
1826
+ onClick: !hasSucceeded && signState === "error" ? handleRetry : signState === "stale" ? handleCloseWalletAndRestart : void 0,
1827
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 w-full flex-row items-center space-x-3 px-4", children: [
1828
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.TokenImage_default, { asset: base, size: "xs", noChain: true }),
1829
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-nowrap", children: buttonText() }),
1830
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-1 border-t", style: { borderColor: "var(--widget-border)" } }),
1831
+ quoteReceivedAtMs > 0 && signState !== "success" && signState !== "error" && signState !== "stale" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CountDown_default, { startTime: quoteReceivedAtMs, onExpired: () => setSignState("stale") }),
1832
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-6 w-3 items-center justify-center rounded-full", children: [
1833
+ !hasSucceeded && (signState === "idle" || signState === "signing" || signState === "submitting" || signState === "refreshingQuote") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
1834
+ (hasSucceeded || signState === "success") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, { className: "h-8 w-8" }),
1835
+ !hasSucceeded && (signState === "error" || signState === "stale") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.RedoIcon, { className: "h-[12px] w-[12px]" })
1836
+ ] })
1837
+ ] })
1838
+ }
1839
+ ),
1840
+ !hasSucceeded && signState === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1841
+ "button",
1842
+ {
1843
+ type: "button",
1844
+ className: "inline-flex h-12 items-center justify-center px-8 text-sm font-medium transition duration-150 cursor-pointer",
1845
+ style: {
1846
+ backgroundColor: "color-mix(in srgb, var(--widget-status-failed) 12%, transparent)",
1847
+ border: "1px solid color-mix(in srgb, var(--widget-status-failed) 20%, transparent)",
1848
+ color: "var(--widget-status-failed)",
1849
+ borderRadius: "var(--widget-radius)"
1850
+ },
1851
+ onClick: cancel,
1852
+ children: "Cancel"
1853
+ }
1854
+ )
1855
+ ] });
1856
+ };
1857
+ var ReviewActionSignAndSubmitOrderRow_default = ReviewActionSignAndSubmitOrderRow;
1858
+
1859
+ // src/components/states/ReviewActionTxRow.tsx
1860
+
1861
+
1862
+ var ComponentStep3 = "trackingTx";
1863
+ var statusConfig = {
1864
+ pending: {
1865
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
1866
+ buttonText: "Trade Pending",
1867
+ showNewSwap: false,
1868
+ statusVar: "var(--widget-status-pending)",
1869
+ clickable: false
1870
+ },
1871
+ received: {
1872
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
1873
+ buttonText: "Trade Received",
1874
+ showNewSwap: false,
1875
+ statusVar: "var(--widget-status-received)",
1876
+ clickable: false
1877
+ },
1878
+ completed: {
1879
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, {}),
1880
+ buttonText: "Continue Swapping",
1881
+ showNewSwap: true,
1882
+ statusVar: "var(--widget-status-completed)",
1883
+ clickable: true
1884
+ },
1885
+ failed: {
1886
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.XAnimation, {}),
1887
+ buttonText: "Retry Swap",
1888
+ showNewSwap: true,
1889
+ statusVar: "var(--widget-status-failed)",
1890
+ clickable: true
1891
+ },
1892
+ cancelled: {
1893
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.XAnimation, {}),
1894
+ buttonText: "Continue Swapping",
1895
+ showNewSwap: true,
1896
+ statusVar: "var(--widget-status-failed)",
1897
+ clickable: true
1898
+ }
1899
+ };
1900
+ var ReviewActionTxRow = ({
1901
+ orderHash,
1902
+ base,
1903
+ quote,
1904
+ baseAmount,
1905
+ quoteAmount,
1906
+ reviewState,
1907
+ onNewSwap,
1908
+ onRetry,
1909
+ status
1910
+ }) => {
1911
+ const hasSucceeded = _chunkGZUTUD5Ocjs.isReviewStepPast.call(void 0, ComponentStep3, reviewState);
1912
+ const config = statusConfig[status] || statusConfig.pending;
1913
+ _react.useEffect.call(void 0, () => {
1914
+ if (status === "completed") {
1915
+ const timer = setTimeout(onNewSwap, 5e3);
1916
+ return () => clearTimeout(timer);
1917
+ }
1918
+ }, [status, onNewSwap]);
1919
+ const handleClick = () => {
1920
+ if (status === "failed") onRetry();
1921
+ else if (config.showNewSwap) onNewSwap();
1922
+ };
1923
+ const sv = config.statusVar;
1924
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-row justify-between space-x-3 w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1925
+ "button",
1926
+ {
1927
+ type: "button",
1928
+ className: `inline-flex h-12 w-full items-center justify-center text-sm font-medium transition duration-150 ${config.clickable ? "cursor-pointer" : "cursor-not-allowed"}`,
1929
+ style: {
1930
+ backgroundColor: `color-mix(in srgb, ${sv} 12%, transparent)`,
1931
+ border: `1px solid color-mix(in srgb, ${sv} 20%, transparent)`,
1932
+ color: sv,
1933
+ borderRadius: "var(--widget-radius)"
1934
+ },
1935
+ onClick: config.showNewSwap ? handleClick : void 0,
1936
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 w-full flex-row items-center space-x-3 px-4", children: [
1937
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-6 w-6 items-center justify-center rounded-full", children: config.icon }),
1938
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-nowrap", children: config.buttonText }),
1939
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-1 border-t", style: { borderColor: "var(--widget-border)" } }),
1940
+ config.showNewSwap && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-6 w-6 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.RedoAnimation, {}) })
1941
+ ] })
1942
+ }
1943
+ ) });
1944
+ };
1945
+ var ReviewActionTxRow_default = ReviewActionTxRow;
1946
+
1947
+ // src/components/states/ReviewActionUnwrapGasToken.tsx
1948
+
1949
+
1950
+
1951
+
1952
+ var WALLET_TIMEOUT_MS2 = 15e3;
1953
+ var ComponentStep4 = "unwrapping";
1954
+ var ReviewActionUnwrapGasToken = ({
1955
+ needsToUnwrap,
1956
+ amount,
1957
+ chainId,
1958
+ token,
1959
+ reviewState,
1960
+ setReviewState,
1961
+ goToNextStep,
1962
+ cancel,
1963
+ delayedClose
1964
+ }) => {
1965
+ const hasSucceeded = _chunkGZUTUD5Ocjs.isReviewStepPast.call(void 0, ComponentStep4, reviewState);
1966
+ const [unwrappingState, setUnwrappingState] = _react.useState.call(void 0, "idle");
1967
+ const unwrapMutation = useUnwrapToken();
1968
+ const { writeContractAsync } = _wagmi.useWriteContract.call(void 0, );
1969
+ const { address } = _chunkPGYOJ5RBcjs.useWalletState.call(void 0, );
1970
+ const emitBalanceEvent = useEmitBalanceEvent();
1971
+ const isUnwrapping = _react.useRef.call(void 0, false);
1972
+ const unwrapAttempted = _react.useRef.call(void 0, false);
1973
+ const timeoutRef = _react.useRef.call(void 0, null);
1974
+ const { status: wagmiStatus } = _wagmi.useAccount.call(void 0, );
1975
+ const clearPendingTimeout = _react.useCallback.call(void 0, () => {
1976
+ if (timeoutRef.current) {
1977
+ clearTimeout(timeoutRef.current);
1978
+ timeoutRef.current = null;
1979
+ }
1980
+ }, []);
1981
+ const handleUnwrap = _react.useCallback.call(void 0, async () => {
1982
+ if (isUnwrapping.current || unwrapAttempted.current || !address || wagmiStatus !== "connected") return;
1983
+ isUnwrapping.current = true;
1984
+ unwrapAttempted.current = true;
1985
+ setUnwrappingState("pending");
1986
+ timeoutRef.current = setTimeout(() => {
1987
+ if (isUnwrapping.current) {
1988
+ setUnwrappingState("error");
1989
+ isUnwrapping.current = false;
1990
+ }
1991
+ }, WALLET_TIMEOUT_MS2);
1992
+ try {
1993
+ const chainConfig = _chunkGZUTUD5Ocjs.getChainConfig.call(void 0, chainId);
1994
+ if (!chainConfig) throw new Error(`No config for chain ${chainId}`);
1995
+ const wrappedDecimals = _nullishCoalesce(chainConfig.wrappedAsset.decimals, () => ( chainConfig.nativeAsset.decimals));
1996
+ const amountRaw = _viem.parseUnits.call(void 0, amount.toString(), wrappedDecimals);
1997
+ await unwrapMutation.mutateAsync({
1998
+ chainId,
1999
+ accountAddress: address,
2000
+ amountRaw,
2001
+ writeContractAsync
2002
+ });
2003
+ const nativeAsset = {
2004
+ symbol: chainConfig.nativeAsset.symbol,
2005
+ name: chainConfig.nativeAsset.name,
2006
+ address: _chunkGZUTUD5Ocjs.NATIVE_ASSET_ADDRESS,
2007
+ decimals: chainConfig.nativeAsset.decimals,
2008
+ chainId
2009
+ };
2010
+ const wrappedAsset = {
2011
+ symbol: chainConfig.wrappedAsset.symbol,
2012
+ name: chainConfig.wrappedAsset.name,
2013
+ address: chainConfig.wrappedAsset.address,
2014
+ decimals: chainConfig.wrappedAsset.decimals,
2015
+ chainId
2016
+ };
2017
+ emitBalanceEvent({
2018
+ type: "unwrap",
2019
+ tokens: [
2020
+ { asset: nativeAsset, userAddress: address },
2021
+ { asset: wrappedAsset, userAddress: address }
2022
+ ]
2023
+ });
2024
+ clearPendingTimeout();
2025
+ setUnwrappingState("success");
2026
+ goToNextStep(ComponentStep4, reviewState);
2027
+ await delayedClose();
2028
+ } catch (e6) {
2029
+ clearPendingTimeout();
2030
+ setUnwrappingState("error");
2031
+ } finally {
2032
+ isUnwrapping.current = false;
2033
+ }
2034
+ }, [address, wagmiStatus, chainId, amount, unwrapMutation, writeContractAsync, emitBalanceEvent, goToNextStep, reviewState, delayedClose, clearPendingTimeout]);
2035
+ _react.useEffect.call(void 0, () => {
2036
+ if (isUnwrapping.current || unwrapAttempted.current) return;
2037
+ if (reviewState === ComponentStep4 && unwrappingState === "idle" && wagmiStatus === "connected") {
2038
+ if (needsToUnwrap) handleUnwrap();
2039
+ else {
2040
+ setUnwrappingState("success");
2041
+ goToNextStep(ComponentStep4, reviewState);
2042
+ }
2043
+ }
2044
+ }, [reviewState, unwrappingState, needsToUnwrap, wagmiStatus, handleUnwrap, goToNextStep]);
2045
+ _react.useEffect.call(void 0, () => () => clearPendingTimeout(), [clearPendingTimeout]);
2046
+ const handleRetry = () => {
2047
+ if (unwrappingState === "error") {
2048
+ unwrapAttempted.current = false;
2049
+ setUnwrappingState("idle");
2050
+ }
2051
+ };
2052
+ const isError = !hasSucceeded && unwrappingState === "error";
2053
+ const showCancel = !hasSucceeded && (unwrappingState === "pending" || unwrappingState === "idle" || unwrappingState === "error");
2054
+ const statusVar = isError ? "var(--widget-status-failed)" : "var(--widget-status-pending)";
2055
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between space-x-3", children: [
2056
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2057
+ "button",
2058
+ {
2059
+ type: "button",
2060
+ className: `inline-flex h-12 w-full items-center justify-center text-sm font-medium transition duration-150 ${isError ? "cursor-pointer" : "cursor-not-allowed"}`,
2061
+ style: {
2062
+ backgroundColor: `color-mix(in srgb, ${statusVar} 12%, transparent)`,
2063
+ border: `1px solid color-mix(in srgb, ${statusVar} 20%, transparent)`,
2064
+ color: statusVar,
2065
+ borderRadius: "var(--widget-radius)"
2066
+ },
2067
+ onClick: isError ? handleRetry : void 0,
2068
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 w-full flex-row items-center space-x-3 px-4", children: [
2069
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-nowrap", children: isError ? "Retry Unwrap" : token ? `Unwrap ${token.symbol}` : "Unwrap Native Token" }),
2070
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-1 border-t", style: { borderColor: "var(--widget-border)" } }),
2071
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-6 w-3 items-center justify-center rounded-full", children: [
2072
+ !hasSucceeded && (unwrappingState === "pending" || unwrappingState === "idle") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
2073
+ (hasSucceeded || unwrappingState === "success") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, { className: "h-8 w-8" }),
2074
+ isError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.RedoIcon, { className: "h-[12px] w-[12px]" })
2075
+ ] })
2076
+ ] })
2077
+ }
2078
+ ),
2079
+ showCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2080
+ "button",
2081
+ {
2082
+ type: "button",
2083
+ className: "inline-flex h-12 items-center justify-center px-8 text-sm font-medium transition duration-150 cursor-pointer",
2084
+ style: {
2085
+ backgroundColor: "color-mix(in srgb, var(--widget-status-failed) 12%, transparent)",
2086
+ border: "1px solid color-mix(in srgb, var(--widget-status-failed) 20%, transparent)",
2087
+ color: "var(--widget-status-failed)",
2088
+ borderRadius: "var(--widget-radius)"
2089
+ },
2090
+ onClick: cancel,
2091
+ children: "Cancel"
2092
+ }
2093
+ )
2094
+ ] });
2095
+ };
2096
+ var ReviewActionUnwrapGasToken_default = ReviewActionUnwrapGasToken;
2097
+
2098
+ // src/components/states/ReviewActionWrapGasToken.tsx
2099
+
2100
+
2101
+
2102
+
2103
+ var WALLET_TIMEOUT_MS3 = 15e3;
2104
+ var ComponentStep5 = "wrapping";
2105
+ var ReviewActionWrapGasToken = ({
2106
+ needsToWrap,
2107
+ amount,
2108
+ chainId,
2109
+ token,
2110
+ reviewState,
2111
+ setReviewState,
2112
+ goToNextStep,
2113
+ cancel,
2114
+ delayedClose,
2115
+ isWrappingPair
2116
+ }) => {
2117
+ const hasSucceeded = _chunkGZUTUD5Ocjs.isReviewStepPast.call(void 0, ComponentStep5, reviewState);
2118
+ const [wrappingState, setWrappingState] = _react.useState.call(void 0, "idle");
2119
+ const wrapMutation = useWrapToken();
2120
+ const { writeContractAsync } = _wagmi.useWriteContract.call(void 0, );
2121
+ const { address } = _chunkPGYOJ5RBcjs.useWalletState.call(void 0, );
2122
+ const emitBalanceEvent = useEmitBalanceEvent();
2123
+ const isWrapping = _react.useRef.call(void 0, false);
2124
+ const wrapAttempted = _react.useRef.call(void 0, false);
2125
+ const timeoutRef = _react.useRef.call(void 0, null);
2126
+ const { status: wagmiStatus } = _wagmi.useAccount.call(void 0, );
2127
+ const clearPendingTimeout = _react.useCallback.call(void 0, () => {
2128
+ if (timeoutRef.current) {
2129
+ clearTimeout(timeoutRef.current);
2130
+ timeoutRef.current = null;
2131
+ }
2132
+ }, []);
2133
+ const handleWrap = _react.useCallback.call(void 0, async () => {
2134
+ if (isWrapping.current || wrapAttempted.current || !address || wagmiStatus !== "connected") return;
2135
+ isWrapping.current = true;
2136
+ wrapAttempted.current = true;
2137
+ setWrappingState("pending");
2138
+ timeoutRef.current = setTimeout(() => {
2139
+ if (isWrapping.current) {
2140
+ setWrappingState("error");
2141
+ isWrapping.current = false;
2142
+ }
2143
+ }, WALLET_TIMEOUT_MS3);
2144
+ try {
2145
+ const chainConfig = _chunkGZUTUD5Ocjs.getChainConfig.call(void 0, chainId);
2146
+ if (!chainConfig) throw new Error(`No config for chain ${chainId}`);
2147
+ const amountRaw = _viem.parseUnits.call(void 0, amount.toString(), chainConfig.nativeAsset.decimals);
2148
+ await wrapMutation.mutateAsync({
2149
+ chainId,
2150
+ accountAddress: address,
2151
+ amountRaw,
2152
+ writeContractAsync
2153
+ });
2154
+ const nativeAsset = {
2155
+ symbol: chainConfig.nativeAsset.symbol,
2156
+ name: chainConfig.nativeAsset.name,
2157
+ address: _chunkGZUTUD5Ocjs.NATIVE_ASSET_ADDRESS,
2158
+ decimals: chainConfig.nativeAsset.decimals,
2159
+ chainId
2160
+ };
2161
+ const wrappedAsset = {
2162
+ symbol: chainConfig.wrappedAsset.symbol,
2163
+ name: chainConfig.wrappedAsset.name,
2164
+ address: chainConfig.wrappedAsset.address,
2165
+ decimals: chainConfig.wrappedAsset.decimals,
2166
+ chainId
2167
+ };
2168
+ emitBalanceEvent({
2169
+ type: "wrap",
2170
+ tokens: [
2171
+ { asset: nativeAsset, userAddress: address },
2172
+ { asset: wrappedAsset, userAddress: address }
2173
+ ]
2174
+ });
2175
+ clearPendingTimeout();
2176
+ setWrappingState("success");
2177
+ goToNextStep(ComponentStep5, reviewState);
2178
+ if (isWrappingPair) await delayedClose();
2179
+ } catch (e7) {
2180
+ clearPendingTimeout();
2181
+ setWrappingState("error");
2182
+ } finally {
2183
+ isWrapping.current = false;
2184
+ }
2185
+ }, [address, wagmiStatus, chainId, amount, wrapMutation, writeContractAsync, emitBalanceEvent, goToNextStep, reviewState, delayedClose, isWrappingPair, clearPendingTimeout]);
2186
+ _react.useEffect.call(void 0, () => {
2187
+ if (isWrapping.current || wrapAttempted.current) return;
2188
+ if (reviewState === ComponentStep5 && wrappingState === "idle" && wagmiStatus === "connected") {
2189
+ if (needsToWrap) handleWrap();
2190
+ else {
2191
+ setWrappingState("success");
2192
+ goToNextStep(ComponentStep5, reviewState);
2193
+ }
2194
+ }
2195
+ }, [reviewState, wrappingState, needsToWrap, wagmiStatus, handleWrap, goToNextStep]);
2196
+ _react.useEffect.call(void 0, () => () => clearPendingTimeout(), [clearPendingTimeout]);
2197
+ const handleRetry = () => {
2198
+ if (wrappingState === "error") {
2199
+ wrapAttempted.current = false;
2200
+ setWrappingState("idle");
2201
+ }
2202
+ };
2203
+ const isError = !hasSucceeded && wrappingState === "error";
2204
+ const showCancel = !hasSucceeded && (wrappingState === "pending" || wrappingState === "idle" || wrappingState === "error");
2205
+ const statusVar = isError ? "var(--widget-status-failed)" : "var(--widget-status-pending)";
2206
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between space-x-3", children: [
2207
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2208
+ "button",
2209
+ {
2210
+ type: "button",
2211
+ className: `inline-flex h-12 w-full items-center justify-center text-sm font-medium transition duration-150 ${isError ? "cursor-pointer" : "cursor-not-allowed"}`,
2212
+ style: {
2213
+ backgroundColor: `color-mix(in srgb, ${statusVar} 12%, transparent)`,
2214
+ border: `1px solid color-mix(in srgb, ${statusVar} 20%, transparent)`,
2215
+ color: statusVar,
2216
+ borderRadius: "var(--widget-radius)"
2217
+ },
2218
+ onClick: isError ? handleRetry : void 0,
2219
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 w-full flex-row items-center space-x-3 px-4", children: [
2220
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-nowrap", children: isError ? "Retry Wrap" : token ? `Wrap ${token.symbol}` : "Wrap Native Token" }),
2221
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-1 border-t", style: { borderColor: "var(--widget-border)" } }),
2222
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-6 w-3 items-center justify-center rounded-full", children: [
2223
+ !hasSucceeded && (wrappingState === "pending" || wrappingState === "idle") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "5" }),
2224
+ (hasSucceeded || wrappingState === "success") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, { className: "h-8 w-8" }),
2225
+ isError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.RedoIcon, { className: "h-[12px] w-[12px]" })
2226
+ ] })
2227
+ ] })
2228
+ }
2229
+ ),
2230
+ showCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2231
+ "button",
2232
+ {
2233
+ type: "button",
2234
+ className: "inline-flex h-12 items-center justify-center px-8 text-sm font-medium transition duration-150 cursor-pointer",
2235
+ style: {
2236
+ backgroundColor: "color-mix(in srgb, var(--widget-status-failed) 12%, transparent)",
2237
+ border: "1px solid color-mix(in srgb, var(--widget-status-failed) 20%, transparent)",
2238
+ color: "var(--widget-status-failed)",
2239
+ borderRadius: "var(--widget-radius)"
2240
+ },
2241
+ onClick: cancel,
2242
+ children: "Cancel"
2243
+ }
2244
+ )
2245
+ ] });
2246
+ };
2247
+ var ReviewActionWrapGasToken_default = ReviewActionWrapGasToken;
2248
+
2249
+ // src/components/states/SwapButton.tsx
2250
+
2251
+ var SwapButton = ({
2252
+ base,
2253
+ baseAmount,
2254
+ quote,
2255
+ quoteAmount,
2256
+ userAddress,
2257
+ isWrappingPair,
2258
+ isUnwrappingPair,
2259
+ isBaseGasToken,
2260
+ isQuoteGasToken,
2261
+ reviewActionProps,
2262
+ reviewState,
2263
+ setReviewState,
2264
+ trackedOrderHash,
2265
+ setTrackedOrderHash,
2266
+ txStatus,
2267
+ onSwapComplete,
2268
+ onSwapInitiated,
2269
+ onOrderSubmitted,
2270
+ onStaleQuoteRestart,
2271
+ setExitHandler,
2272
+ setRetryHandler
2273
+ }) => {
2274
+ const {
2275
+ rfqQuote,
2276
+ status: rfqStatus,
2277
+ liquidityError,
2278
+ routingError,
2279
+ sizeCapError,
2280
+ stop,
2281
+ clear
2282
+ } = useRfq();
2283
+ const { clearForm } = _chunk6XB5R4GFcjs.useSwapFormContext.call(void 0, );
2284
+ const currentChainId = _wagmi.useChainId.call(void 0, );
2285
+ const { swapButtonVariant, widgetType } = _chunkGZUTUD5Ocjs.useWidgetConfig.call(void 0, );
2286
+ const isCompact = widgetType === "compact";
2287
+ const { trackOrderTransaction, trackNativeTransaction } = useTransactionTracker();
2288
+ const { startPolling } = useOrderStatusPolling((orderHash, status) => {
2289
+ _chunk6XB5R4GFcjs.useWidgetSwapUIStore.getState().setTxStatus(status);
2290
+ if (status === "completed") {
2291
+ trackOrderTransaction(orderHash, `Swap ${base.symbol} \u2192 ${quote.symbol}`);
2292
+ }
2293
+ });
2294
+ const [isRestarting, setIsRestarting] = _react.useState.call(void 0, false);
2295
+ const awaitingAutoResumeRef = _react.useRef.call(void 0, false);
2296
+ const restartTimerRef = _react.useRef.call(void 0, null);
2297
+ const needsToWrap = isWrappingPair;
2298
+ const needsToUnwrap = isUnwrappingPair;
2299
+ const needsSignature = !isWrappingPair && !isUnwrappingPair;
2300
+ const needsChainSwitch = currentChainId !== _optionalChain([base, 'optionalAccess', _82 => _82.chainId]) && (needsToWrap || needsToUnwrap || needsSignature);
2301
+ const chainConfig = _chunkGZUTUD5Ocjs.getChainConfig.call(void 0, base.chainId);
2302
+ const requiredChain = {
2303
+ chainId: base.chainId,
2304
+ name: _nullishCoalesce(_optionalChain([chainConfig, 'optionalAccess', _83 => _83.displayName]), () => ( `Chain ${base.chainId}`))
2305
+ };
2306
+ const goToNextStep = _react.useCallback.call(void 0,
2307
+ (componentStep, currentStep) => {
2308
+ if (currentStep !== componentStep) return;
2309
+ if (componentStep === "chain") {
2310
+ if (needsToWrap) {
2311
+ setReviewState("wrapping");
2312
+ return;
2313
+ }
2314
+ if (needsToUnwrap) {
2315
+ setReviewState("unwrapping");
2316
+ return;
2317
+ }
2318
+ setReviewState("signingOrder");
2319
+ return;
2320
+ }
2321
+ if (componentStep === "signingOrder") {
2322
+ setReviewState("trackingTx");
2323
+ return;
2324
+ }
2325
+ if (componentStep === "wrapping") {
2326
+ if (!isWrappingPair) {
2327
+ setReviewState("signingOrder");
2328
+ return;
2329
+ }
2330
+ setReviewState("wrapSuccess");
2331
+ return;
2332
+ }
2333
+ if (componentStep === "unwrapping") {
2334
+ setReviewState("wrapSuccess");
2335
+ return;
2336
+ }
2337
+ const nextStep = _chunkGZUTUD5Ocjs.getNextReviewStep.call(void 0, componentStep);
2338
+ if (nextStep) setReviewState(nextStep);
2339
+ },
2340
+ [
2341
+ setReviewState,
2342
+ isWrappingPair,
2343
+ needsToWrap,
2344
+ needsToUnwrap,
2345
+ needsSignature
2346
+ ]
2347
+ );
2348
+ const determineInitialStep = _react.useCallback.call(void 0, () => {
2349
+ if (needsChainSwitch) return "chain";
2350
+ if (needsToWrap) return "wrapping";
2351
+ if (needsToUnwrap) return "unwrapping";
2352
+ if (needsSignature) return "signingOrder";
2353
+ return null;
2354
+ }, [
2355
+ needsChainSwitch,
2356
+ needsToWrap,
2357
+ needsToUnwrap,
2358
+ needsSignature
2359
+ ]);
2360
+ const resetState = _react.useCallback.call(void 0, () => {
2361
+ setReviewState(null);
2362
+ clearForm();
2363
+ }, [clearForm, setReviewState]);
2364
+ const delayedClose = _react.useCallback.call(void 0, async () => {
2365
+ setReviewState("wrapSuccess");
2366
+ for (let i = 0; i < 3; i++) {
2367
+ await _chunkGZUTUD5Ocjs.sleep.call(void 0, 700);
2368
+ }
2369
+ resetState();
2370
+ }, [resetState, setReviewState]);
2371
+ const cancel = _react.useCallback.call(void 0, async () => {
2372
+ clear();
2373
+ setReviewState("cancelled");
2374
+ for (let i = 0; i < 3; i++) {
2375
+ await _chunkGZUTUD5Ocjs.sleep.call(void 0, 500);
2376
+ }
2377
+ resetState();
2378
+ }, [clear, resetState, setReviewState]);
2379
+ const handleNewSwap = _react.useCallback.call(void 0, () => {
2380
+ if (!trackedOrderHash) return;
2381
+ _chunk6XB5R4GFcjs.useWidgetSwapUIStore.getState().stopTracking();
2382
+ setReviewState(null);
2383
+ setTrackedOrderHash(null);
2384
+ clearForm();
2385
+ }, [trackedOrderHash, setReviewState, setTrackedOrderHash, clearForm]);
2386
+ const handleRetrySwap = _react.useCallback.call(void 0, () => {
2387
+ setReviewState(null);
2388
+ setTrackedOrderHash(null);
2389
+ awaitingAutoResumeRef.current = true;
2390
+ _optionalChain([onStaleQuoteRestart, 'optionalCall', _84 => _84()]);
2391
+ }, [setReviewState, setTrackedOrderHash, onStaleQuoteRestart]);
2392
+ const handleReview = _react.useCallback.call(void 0, () => {
2393
+ if (reviewActionProps) {
2394
+ setReviewState(determineInitialStep());
2395
+ }
2396
+ }, [determineInitialStep, reviewActionProps, setReviewState]);
2397
+ const restartSigningFlow = _react.useCallback.call(void 0,
2398
+ (isFromStaleState = false) => {
2399
+ if (isFromStaleState) {
2400
+ awaitingAutoResumeRef.current = true;
2401
+ setReviewState(null);
2402
+ _optionalChain([onStaleQuoteRestart, 'optionalCall', _85 => _85()]);
2403
+ } else {
2404
+ setReviewState(null);
2405
+ restartTimerRef.current = setTimeout(() => {
2406
+ if (reviewActionProps) {
2407
+ setReviewState(determineInitialStep());
2408
+ setIsRestarting(false);
2409
+ }
2410
+ }, 100);
2411
+ }
2412
+ },
2413
+ [
2414
+ setReviewState,
2415
+ reviewActionProps,
2416
+ determineInitialStep,
2417
+ onStaleQuoteRestart
2418
+ ]
2419
+ );
2420
+ _react.useEffect.call(void 0, () => {
2421
+ if (reviewState !== null) stop();
2422
+ }, [reviewState, stop]);
2423
+ _react.useEffect.call(void 0, () => {
2424
+ if (reviewState !== null && isRestarting) setIsRestarting(false);
2425
+ }, [reviewState, isRestarting]);
2426
+ _react.useEffect.call(void 0, () => {
2427
+ _optionalChain([setExitHandler, 'optionalCall', _86 => _86(handleNewSwap)]);
2428
+ }, [setExitHandler, handleNewSwap]);
2429
+ _react.useEffect.call(void 0, () => {
2430
+ _optionalChain([setRetryHandler, 'optionalCall', _87 => _87(handleRetrySwap)]);
2431
+ }, [setRetryHandler, handleRetrySwap]);
2432
+ _react.useEffect.call(void 0, () => {
2433
+ return () => {
2434
+ if (restartTimerRef.current) clearTimeout(restartTimerRef.current);
2435
+ };
2436
+ }, []);
2437
+ _react.useEffect.call(void 0, () => {
2438
+ if (awaitingAutoResumeRef.current && rfqStatus === "fresh" && _optionalChain([rfqQuote, 'optionalAccess', _88 => _88.id])) {
2439
+ awaitingAutoResumeRef.current = false;
2440
+ setReviewState("signingOrder");
2441
+ }
2442
+ }, [rfqStatus, _optionalChain([rfqQuote, 'optionalAccess', _89 => _89.id]), setReviewState]);
2443
+ const getIdleButtonStyle = (active) => {
2444
+ if (!active) {
2445
+ return {
2446
+ backgroundColor: swapButtonVariant === "default" ? "var(--widget-muted)" : "transparent",
2447
+ color: "var(--widget-muted-foreground)",
2448
+ border: swapButtonVariant !== "default" ? "1px solid var(--widget-border)" : "none",
2449
+ borderRadius: "var(--widget-radius)"
2450
+ };
2451
+ }
2452
+ switch (swapButtonVariant) {
2453
+ case "outline":
2454
+ return {
2455
+ backgroundColor: "transparent",
2456
+ color: "var(--widget-primary)",
2457
+ border: "1px solid var(--widget-primary)",
2458
+ borderRadius: "var(--widget-radius)"
2459
+ };
2460
+ case "ghost":
2461
+ return {
2462
+ backgroundColor: "transparent",
2463
+ color: "var(--widget-primary)",
2464
+ border: "none",
2465
+ borderRadius: "var(--widget-radius)"
2466
+ };
2467
+ default:
2468
+ return {
2469
+ backgroundColor: "var(--widget-primary)",
2470
+ color: "var(--widget-primary-foreground)",
2471
+ borderRadius: "var(--widget-radius)"
2472
+ };
2473
+ }
2474
+ };
2475
+ const idleButtonClass = `w-full ${isCompact ? "py-2" : "py-3"} text-sm font-medium transition-colors cursor-pointer mt-1`;
2476
+ if (reviewState === null && !isWrappingPair && !isUnwrappingPair) {
2477
+ if (isRestarting) {
2478
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2479
+ "button",
2480
+ {
2481
+ className: idleButtonClass,
2482
+ disabled: true,
2483
+ style: {
2484
+ ...getIdleButtonStyle(false),
2485
+ opacity: 0.6,
2486
+ cursor: "not-allowed"
2487
+ },
2488
+ children: "Getting fresh quote..."
2489
+ }
2490
+ );
2491
+ }
2492
+ const getIdleText = () => {
2493
+ if (liquidityError) return "Insufficient Liquidity";
2494
+ if (routingError) return "Route Not Available";
2495
+ if (sizeCapError) return "Size Cap Exceeded";
2496
+ if (!rfqQuote && rfqStatus === "polling") return "Getting Quote...";
2497
+ if (!rfqQuote) return "Enter Amount";
2498
+ return "Swap";
2499
+ };
2500
+ const isActive = !!reviewActionProps;
2501
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2502
+ "button",
2503
+ {
2504
+ onClick: isActive ? handleReview : void 0,
2505
+ disabled: !isActive,
2506
+ className: `${idleButtonClass} disabled:opacity-40 disabled:cursor-not-allowed`,
2507
+ style: getIdleButtonStyle(isActive),
2508
+ children: getIdleText()
2509
+ }
2510
+ );
2511
+ }
2512
+ if (reviewState === null && isUnwrappingPair) {
2513
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2514
+ "button",
2515
+ {
2516
+ onClick: reviewActionProps ? handleReview : void 0,
2517
+ disabled: !reviewActionProps,
2518
+ className: `${idleButtonClass} disabled:opacity-40 disabled:cursor-not-allowed`,
2519
+ style: getIdleButtonStyle(!!reviewActionProps),
2520
+ children: "Unwrap"
2521
+ }
2522
+ );
2523
+ }
2524
+ if (reviewState === null && isWrappingPair) {
2525
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2526
+ "button",
2527
+ {
2528
+ onClick: reviewActionProps ? handleReview : void 0,
2529
+ disabled: !reviewActionProps,
2530
+ className: `${idleButtonClass} disabled:opacity-40 disabled:cursor-not-allowed`,
2531
+ style: getIdleButtonStyle(!!reviewActionProps),
2532
+ children: "Wrap"
2533
+ }
2534
+ );
2535
+ }
2536
+ if (reviewState === "success") {
2537
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2 w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2538
+ "button",
2539
+ {
2540
+ className: `w-full ${isCompact ? "py-2" : "py-3"} text-sm font-medium cursor-default`,
2541
+ style: {
2542
+ backgroundColor: "color-mix(in srgb, var(--widget-status-completed) 15%, transparent)",
2543
+ color: "var(--widget-status-completed)",
2544
+ border: "1px solid color-mix(in srgb, var(--widget-status-completed) 20%, transparent)",
2545
+ borderRadius: "var(--widget-radius)"
2546
+ },
2547
+ children: "Order Placed"
2548
+ }
2549
+ ) });
2550
+ }
2551
+ if (reviewState === "wrapSuccess") {
2552
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2 w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2553
+ "button",
2554
+ {
2555
+ className: `w-full ${isCompact ? "py-2" : "py-3"} text-sm font-medium cursor-default`,
2556
+ style: {
2557
+ backgroundColor: "color-mix(in srgb, var(--widget-status-completed) 15%, transparent)",
2558
+ color: "var(--widget-status-completed)",
2559
+ border: "1px solid color-mix(in srgb, var(--widget-status-completed) 20%, transparent)",
2560
+ borderRadius: "var(--widget-radius)"
2561
+ },
2562
+ children: isWrappingPair ? "Wrapped Successfully" : "Unwrapped Successfully"
2563
+ }
2564
+ ) });
2565
+ }
2566
+ if (reviewState === "cancelled") {
2567
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2 w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2568
+ "button",
2569
+ {
2570
+ onClick: resetState,
2571
+ className: `w-full ${isCompact ? "py-2" : "py-3"} text-sm font-medium cursor-pointer`,
2572
+ style: {
2573
+ backgroundColor: "color-mix(in srgb, var(--widget-status-failed) 15%, transparent)",
2574
+ color: "var(--widget-status-failed)",
2575
+ border: "1px solid color-mix(in srgb, var(--widget-status-failed) 20%, transparent)",
2576
+ borderRadius: "var(--widget-radius)"
2577
+ },
2578
+ children: "Order Cancelled"
2579
+ }
2580
+ ) });
2581
+ }
2582
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full", children: [
2583
+ reviewState === "chain" && needsChainSwitch && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2584
+ ReviewActionChainSwitchRow_default,
2585
+ {
2586
+ requiredChain,
2587
+ needsChainSwitch: needsChainSwitch && currentChainId !== base.chainId,
2588
+ reviewState,
2589
+ goToNextStep,
2590
+ cancel
2591
+ }
2592
+ ),
2593
+ reviewState === "wrapping" && needsToWrap && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2594
+ ReviewActionWrapGasToken_default,
2595
+ {
2596
+ needsToWrap,
2597
+ amount: baseAmount,
2598
+ chainId: base.chainId,
2599
+ token: base,
2600
+ reviewState,
2601
+ setReviewState,
2602
+ goToNextStep,
2603
+ cancel,
2604
+ delayedClose,
2605
+ isWrappingPair
2606
+ }
2607
+ ),
2608
+ reviewState === "unwrapping" && needsToUnwrap && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2609
+ ReviewActionUnwrapGasToken_default,
2610
+ {
2611
+ needsToUnwrap,
2612
+ amount: baseAmount,
2613
+ chainId: base.chainId,
2614
+ token: base,
2615
+ reviewState,
2616
+ setReviewState,
2617
+ goToNextStep,
2618
+ cancel,
2619
+ delayedClose
2620
+ }
2621
+ ),
2622
+ reviewState === "signingOrder" && needsSignature && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2623
+ ReviewActionSignAndSubmitOrderRow_default,
2624
+ {
2625
+ base,
2626
+ baseAmount,
2627
+ quote,
2628
+ quoteAmount,
2629
+ userAddress,
2630
+ reviewState,
2631
+ goToNextStep,
2632
+ cancel,
2633
+ restartSigningFlow,
2634
+ onSwapInitiated,
2635
+ onOrderSubmitted,
2636
+ isWrappingPair,
2637
+ isUnwrappingPair,
2638
+ onSwapComplete,
2639
+ startPolling,
2640
+ trackNativeTransaction
2641
+ }
2642
+ ),
2643
+ reviewState === "trackingTx" && trackedOrderHash && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2644
+ ReviewActionTxRow_default,
2645
+ {
2646
+ orderHash: trackedOrderHash,
2647
+ base,
2648
+ quote,
2649
+ baseAmount,
2650
+ quoteAmount,
2651
+ reviewState,
2652
+ status: txStatus,
2653
+ onNewSwap: handleNewSwap,
2654
+ onRetry: handleRetrySwap
2655
+ }
2656
+ ),
2657
+ reviewState && ![
2658
+ "chain",
2659
+ "wrapping",
2660
+ "unwrapping",
2661
+ "approval",
2662
+ "signingOrder",
2663
+ "trackingTx",
2664
+ "success",
2665
+ "wrapSuccess",
2666
+ "cancelled"
2667
+ ].includes(reviewState) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2668
+ "button",
2669
+ {
2670
+ disabled: true,
2671
+ className: `w-full ${isCompact ? "py-2" : "py-3"} text-sm font-medium`,
2672
+ style: {
2673
+ backgroundColor: "var(--widget-muted)",
2674
+ color: "var(--widget-muted-foreground)",
2675
+ borderRadius: "var(--widget-radius)"
2676
+ },
2677
+ children: "Processing..."
2678
+ }
2679
+ )
2680
+ ] });
2681
+ };
2682
+
2683
+ // src/components/states/TxStatusDisplay.tsx
2684
+
2685
+ var _shallow = require('zustand/react/shallow');
2686
+
2687
+ var statusVarMap = {
2688
+ pending: "var(--widget-status-pending)",
2689
+ received: "var(--widget-status-received)",
2690
+ completed: "var(--widget-status-completed)",
2691
+ failed: "var(--widget-status-failed)",
2692
+ cancelled: "var(--widget-status-failed)"
2693
+ };
2694
+ var statusLabels = {
2695
+ pending: { title: "Trade Pending", subtitle: "Submitting to network" },
2696
+ received: { title: "Trade Received", subtitle: "Processing settlement" },
2697
+ completed: { title: "Trade Filled", subtitle: "Settlement complete" },
2698
+ failed: { title: "Trade Failed", subtitle: "Settlement unsuccessful" },
2699
+ cancelled: { title: "Trade Cancelled", subtitle: "Order was cancelled" }
2700
+ };
2701
+ function getStatusStyles(status) {
2702
+ const v = _nullishCoalesce(statusVarMap[status], () => ( statusVarMap.pending));
2703
+ return {
2704
+ textColor: v,
2705
+ bgColor: `color-mix(in srgb, ${v} 15%, transparent)`,
2706
+ borderColor: `color-mix(in srgb, ${v} 20%, transparent)`,
2707
+ cardBgColor: `color-mix(in srgb, ${v} 8%, transparent)`,
2708
+ cardBorderColor: `color-mix(in srgb, ${v} 15%, transparent)`,
2709
+ iconBgColor: `color-mix(in srgb, ${v} 12%, transparent)`,
2710
+ iconBorderColor: `color-mix(in srgb, ${v} 15%, transparent)`
2711
+ };
2712
+ }
2713
+ var StatusIcon = ({ status }) => {
2714
+ switch (status) {
2715
+ case "completed":
2716
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.Checkmark, {});
2717
+ case "failed":
2718
+ case "cancelled":
2719
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.XAnimation, {});
2720
+ default:
2721
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.LoadingSpinner_default, { size: "10" });
2722
+ }
2723
+ };
2724
+ var TxStatusDisplay = ({
2725
+ orderHash,
2726
+ base,
2727
+ quote,
2728
+ baseAmount,
2729
+ quoteAmount,
2730
+ status
2731
+ }) => {
2732
+ const [copied, setCopied] = _react.useState.call(void 0, false);
2733
+ const receivedTimeRef = _react.useRef.call(void 0, null);
2734
+ const submissionTimeRef = _react.useRef.call(void 0, Date.now());
2735
+ const [transactionSpeed, setTransactionSpeed] = _react.useState.call(void 0, null);
2736
+ const copyTimerRef = _react.useRef.call(void 0, null);
2737
+ const { isRecipientInputOpen, recipient } = _chunk6XB5R4GFcjs.useWidgetSwapUIStore.call(void 0,
2738
+ _shallow.useShallow.call(void 0, (state) => ({
2739
+ isRecipientInputOpen: state.isRecipientInputOpen,
2740
+ recipient: state.recipient
2741
+ }))
2742
+ );
2743
+ _react.useEffect.call(void 0, () => {
2744
+ if (status === "received") receivedTimeRef.current = Date.now();
2745
+ }, [status]);
2746
+ _react.useEffect.call(void 0, () => {
2747
+ if (status === "completed" && !transactionSpeed) {
2748
+ const startTime = receivedTimeRef.current || submissionTimeRef.current;
2749
+ setTransactionSpeed((Date.now() - startTime) / 1e3);
2750
+ }
2751
+ }, [status, transactionSpeed]);
2752
+ _react.useEffect.call(void 0, () => {
2753
+ return () => {
2754
+ if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
2755
+ };
2756
+ }, []);
2757
+ const handleCopyHash = _react.useCallback.call(void 0, () => {
2758
+ if (!_optionalChain([navigator, 'access', _90 => _90.clipboard, 'optionalAccess', _91 => _91.writeText])) return;
2759
+ navigator.clipboard.writeText(orderHash).then(() => {
2760
+ setCopied(true);
2761
+ if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
2762
+ copyTimerRef.current = setTimeout(() => setCopied(false), 2e3);
2763
+ }).catch(() => {
2764
+ });
2765
+ }, [orderHash]);
2766
+ const labels = _nullishCoalesce(statusLabels[status], () => ( statusLabels.pending));
2767
+ const config = getStatusStyles(status);
2768
+ const formattedBaseAmount = _chunkGZUTUD5Ocjs.formatNumber.call(void 0, baseAmount);
2769
+ const formattedQuoteAmount = _chunkGZUTUD5Ocjs.formatNumber.call(void 0, quoteAmount);
2770
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2771
+ "div",
2772
+ {
2773
+ className: "relative w-full h-full overflow-hidden flex flex-col",
2774
+ style: {
2775
+ backgroundColor: config.bgColor,
2776
+ border: `1px var(--widget-border-style) ${config.borderColor}`,
2777
+ backdropFilter: "blur(8px)"
2778
+ },
2779
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative z-10 px-3 pt-5 pb-3 flex-1 flex flex-col", children: [
2780
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center mb-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-1 text-center", children: [
2781
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2782
+ "div",
2783
+ {
2784
+ className: "flex h-10 w-10 items-center justify-center rounded-full border",
2785
+ style: {
2786
+ backgroundColor: config.iconBgColor,
2787
+ borderColor: config.iconBorderColor
2788
+ },
2789
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-7 w-7 flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusIcon, { status }) })
2790
+ }
2791
+ ),
2792
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2793
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2794
+ "h3",
2795
+ {
2796
+ className: "text-xl font-bold",
2797
+ style: { color: config.textColor },
2798
+ children: labels.title
2799
+ }
2800
+ ),
2801
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2802
+ "p",
2803
+ {
2804
+ className: "text-2xs uppercase tracking-wider",
2805
+ style: { color: config.textColor, opacity: 0.6 },
2806
+ children: labels.subtitle
2807
+ }
2808
+ )
2809
+ ] })
2810
+ ] }) }),
2811
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 flex flex-col justify-center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-1.5", children: [
2812
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2813
+ "div",
2814
+ {
2815
+ className: "flex items-center justify-between backdrop-blur-sm p-2.5 border transition-all duration-300",
2816
+ style: {
2817
+ backgroundColor: config.cardBgColor,
2818
+ borderColor: config.cardBorderColor
2819
+ },
2820
+ children: [
2821
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2.5", children: [
2822
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.TokenImage_default, { asset: base, size: "sm" }),
2823
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2824
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2825
+ "div",
2826
+ {
2827
+ className: "text-sm font-bold",
2828
+ style: { color: config.textColor },
2829
+ children: base.symbol
2830
+ }
2831
+ ),
2832
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2833
+ "div",
2834
+ {
2835
+ className: "text-2xs",
2836
+ style: { color: config.textColor, opacity: 0.5 },
2837
+ children: base.name
2838
+ }
2839
+ )
2840
+ ] })
2841
+ ] }),
2842
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-right", children: [
2843
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2844
+ "div",
2845
+ {
2846
+ className: "text-lg font-bold mono",
2847
+ style: { color: config.textColor },
2848
+ children: formattedBaseAmount
2849
+ }
2850
+ ),
2851
+ base.price && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2852
+ "div",
2853
+ {
2854
+ className: "text-2xs mono",
2855
+ style: { color: config.textColor, opacity: 0.5 },
2856
+ children: [
2857
+ "$",
2858
+ (base.price * baseAmount).toFixed(2)
2859
+ ]
2860
+ }
2861
+ )
2862
+ ] })
2863
+ ]
2864
+ }
2865
+ ),
2866
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center pb-0.5 pt-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2867
+ "div",
2868
+ {
2869
+ className: "flex h-6 w-6 items-center justify-center rounded-full border",
2870
+ style: {
2871
+ backgroundColor: config.cardBgColor,
2872
+ borderColor: config.cardBorderColor
2873
+ },
2874
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-base", style: { color: config.textColor }, children: "\u2193" })
2875
+ }
2876
+ ) }),
2877
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2878
+ "div",
2879
+ {
2880
+ className: "flex items-center justify-between backdrop-blur-sm p-2.5 border transition-all duration-300",
2881
+ style: {
2882
+ backgroundColor: config.cardBgColor,
2883
+ borderColor: config.cardBorderColor
2884
+ },
2885
+ children: [
2886
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2.5", children: [
2887
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGZUTUD5Ocjs.TokenImage_default, { asset: quote, size: "sm" }),
2888
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2889
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2890
+ "div",
2891
+ {
2892
+ className: "text-sm font-bold",
2893
+ style: { color: config.textColor },
2894
+ children: quote.symbol
2895
+ }
2896
+ ),
2897
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2898
+ "div",
2899
+ {
2900
+ className: "text-2xs",
2901
+ style: { color: config.textColor, opacity: 0.5 },
2902
+ children: quote.name
2903
+ }
2904
+ )
2905
+ ] })
2906
+ ] }),
2907
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-right", children: [
2908
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2909
+ "div",
2910
+ {
2911
+ className: "text-lg font-bold mono",
2912
+ style: { color: config.textColor },
2913
+ children: formattedQuoteAmount
2914
+ }
2915
+ ),
2916
+ quote.price && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2917
+ "div",
2918
+ {
2919
+ className: "text-2xs mono",
2920
+ style: { color: config.textColor, opacity: 0.5 },
2921
+ children: [
2922
+ "$",
2923
+ (quote.price * quoteAmount).toFixed(2)
2924
+ ]
2925
+ }
2926
+ )
2927
+ ] })
2928
+ ]
2929
+ }
2930
+ ),
2931
+ isRecipientInputOpen && recipient && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-1.5", children: [
2932
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2933
+ "div",
2934
+ {
2935
+ className: "text-2xs mb-0.5 uppercase tracking-wider font-medium",
2936
+ style: { color: config.textColor, opacity: 0.5 },
2937
+ children: "Recipient"
2938
+ }
2939
+ ),
2940
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2941
+ "div",
2942
+ {
2943
+ className: "flex items-center backdrop-blur-sm p-2 border transition-all duration-300",
2944
+ style: {
2945
+ backgroundColor: config.cardBgColor,
2946
+ borderColor: config.cardBorderColor
2947
+ },
2948
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
2949
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2950
+ "div",
2951
+ {
2952
+ className: "flex h-5 w-5 items-center justify-center overflow-hidden rounded-full",
2953
+ style: { backgroundColor: config.iconBgColor },
2954
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-2xs", children: "\u{1F464}" })
2955
+ }
2956
+ ),
2957
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
2958
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2959
+ "div",
2960
+ {
2961
+ className: "text-2xs",
2962
+ style: { color: config.textColor, opacity: 0.5 },
2963
+ children: "To:"
2964
+ }
2965
+ ),
2966
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2967
+ "div",
2968
+ {
2969
+ className: "text-xs mono",
2970
+ style: { color: config.textColor },
2971
+ children: [
2972
+ recipient.slice(0, 6),
2973
+ "...",
2974
+ recipient.slice(-4)
2975
+ ]
2976
+ }
2977
+ )
2978
+ ] })
2979
+ ] })
2980
+ }
2981
+ )
2982
+ ] })
2983
+ ] }) }),
2984
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2985
+ "div",
2986
+ {
2987
+ className: "mt-3 pt-2.5 space-y-1.5",
2988
+ style: { borderTop: `1px solid ${config.cardBorderColor}` },
2989
+ children: [
2990
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2991
+ "div",
2992
+ {
2993
+ role: "button",
2994
+ tabIndex: 0,
2995
+ onClick: handleCopyHash,
2996
+ onKeyDown: (e) => {
2997
+ if (e.key === "Enter" || e.key === " ") {
2998
+ e.preventDefault();
2999
+ handleCopyHash();
3000
+ }
3001
+ },
3002
+ className: "flex items-center justify-between cursor-pointer group hover:opacity-80 transition-opacity",
3003
+ children: [
3004
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3005
+ "div",
3006
+ {
3007
+ className: "text-xs uppercase tracking-wider font-medium",
3008
+ style: { color: config.textColor, opacity: 0.5 },
3009
+ children: copied ? "Copied!" : status === "completed" || status === "failed" || status === "cancelled" ? "Order Hash" : status === "received" ? "Received" : "Pending"
3010
+ }
3011
+ ),
3012
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3013
+ "div",
3014
+ {
3015
+ className: "text-xs mono transition-colors",
3016
+ style: { color: config.textColor },
3017
+ children: [
3018
+ orderHash.slice(0, 6),
3019
+ "...",
3020
+ orderHash.slice(-4)
3021
+ ]
3022
+ }
3023
+ )
3024
+ ]
3025
+ }
3026
+ ),
3027
+ status === "completed" && transactionSpeed ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between", children: [
3028
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3029
+ "div",
3030
+ {
3031
+ className: "text-xs uppercase tracking-wider font-medium",
3032
+ style: { color: config.textColor, opacity: 0.5 },
3033
+ children: "Speed"
3034
+ }
3035
+ ),
3036
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3037
+ "div",
3038
+ {
3039
+ className: "text-base font-bold mono",
3040
+ style: { color: config.textColor },
3041
+ children: [
3042
+ transactionSpeed.toFixed(2),
3043
+ "s"
3044
+ ]
3045
+ }
3046
+ )
3047
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-5" })
3048
+ ]
3049
+ }
3050
+ )
3051
+ ] })
3052
+ }
3053
+ );
3054
+ };
3055
+ var TxStatusDisplay_default = TxStatusDisplay;
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+
3080
+
3081
+ exports.useBalanceEventListener = useBalanceEventListener; exports.useEmitBalanceEvent = useEmitBalanceEvent; exports.useBalanceEventSubscription = useBalanceEventSubscription; exports.RfqProvider = RfqProvider; exports.useRfq = useRfq; exports.WalletModalContext = WalletModalContext; exports.useWalletModal = useWalletModal; exports.AssetAmountInput_default = AssetAmountInput_default; exports.AssetSelection_default = AssetSelection_default; exports.RecipientForm_default = RecipientForm_default; exports.pollOrderStatus = pollOrderStatus; exports.useOrderStatusPolling = useOrderStatusPolling; exports.useTransactionRegistry = useTransactionRegistry; exports.ChainSwitch = ChainSwitch; exports.SignSwap = SignSwap; exports.isQuoteFresh = isQuoteFresh; exports.canSubmitOrder = canSubmitOrder; exports.markOrderAsSubmitted = markOrderAsSubmitted; exports.cleanupOldSubmissions = cleanupOldSubmissions; exports.useUnwrapToken = useUnwrapToken; exports.useWrapToken = useWrapToken; exports.SwapButton = SwapButton; exports.TxStatusDisplay_default = TxStatusDisplay_default;
3082
+ //# sourceMappingURL=chunk-HXOGJSAI.cjs.map