@unifold/ui-react 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2847 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Button: () => Button,
34
+ BuyWithCard: () => BuyWithCard,
35
+ CurrencyListItem: () => CurrencyListItem,
36
+ CurrencyListSection: () => CurrencyListSection,
37
+ CurrencyModal: () => CurrencyModal,
38
+ DepositExecutionItem: () => DepositExecutionItem,
39
+ DepositHeader: () => DepositHeader,
40
+ DepositModal: () => DepositModal,
41
+ DepositSuccessToast: () => DepositSuccessToast,
42
+ DepositTrackerButton: () => DepositTrackerButton,
43
+ DepositWithCardButton: () => DepositWithCardButton,
44
+ DepositsModal: () => DepositsModal,
45
+ Dialog: () => Dialog,
46
+ DialogClose: () => DialogClose,
47
+ DialogContent: () => DialogContent,
48
+ DialogDescription: () => DialogDescription,
49
+ DialogFooter: () => DialogFooter,
50
+ DialogHeader: () => DialogHeader,
51
+ DialogOverlay: () => DialogOverlay,
52
+ DialogPortal: () => DialogPortal,
53
+ DialogTitle: () => DialogTitle,
54
+ DialogTrigger: () => DialogTrigger,
55
+ ExecutionStatus: () => ExecutionStatus,
56
+ SOLANA_USDC_ADDRESS: () => SOLANA_USDC_ADDRESS,
57
+ Select: () => Select,
58
+ SelectContent: () => SelectContent,
59
+ SelectGroup: () => SelectGroup,
60
+ SelectItem: () => SelectItem,
61
+ SelectLabel: () => SelectLabel,
62
+ SelectScrollDownButton: () => SelectScrollDownButton,
63
+ SelectScrollUpButton: () => SelectScrollUpButton,
64
+ SelectSeparator: () => SelectSeparator,
65
+ SelectTrigger: () => SelectTrigger,
66
+ SelectValue: () => SelectValue,
67
+ StyledQRCode: () => StyledQRCode,
68
+ ThemeProvider: () => ThemeProvider,
69
+ Tooltip: () => Tooltip,
70
+ TooltipContent: () => TooltipContent,
71
+ TooltipProvider: () => TooltipProvider,
72
+ TooltipTrigger: () => TooltipTrigger,
73
+ TransferCrypto: () => TransferCrypto,
74
+ TransferCrypto2: () => TransferCrypto2,
75
+ TransferCryptoBase: () => TransferCryptoBase,
76
+ TransferCryptoButton: () => TransferCryptoButton,
77
+ buttonVariants: () => buttonVariants,
78
+ cn: () => cn,
79
+ createEOA: () => createEOA,
80
+ createMeldSession: () => createMeldSession,
81
+ getApiBaseUrl: () => getApiBaseUrl,
82
+ getFiatCurrencies: () => getFiatCurrencies,
83
+ getIconUrl: () => getIconUrl,
84
+ getMeldQuotes: () => getMeldQuotes,
85
+ getSupportedDepositTokens: () => getSupportedDepositTokens,
86
+ getWalletByChainType: () => getWalletByChainType,
87
+ i18n: () => i18n,
88
+ queryExecutions: () => queryExecutions,
89
+ setApiConfig: () => setApiConfig,
90
+ useTheme: () => useTheme,
91
+ useUserIp: () => useUserIp
92
+ });
93
+ module.exports = __toCommonJS(index_exports);
94
+
95
+ // src/components/deposits/DepositModal.tsx
96
+ var import_react6 = require("react");
97
+
98
+ // src/components/shared/dialog.tsx
99
+ var React2 = __toESM(require("react"));
100
+ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
101
+ var import_lucide_react = require("lucide-react");
102
+
103
+ // src/lib/utils.ts
104
+ var import_clsx = require("clsx");
105
+ var import_tailwind_merge = require("tailwind-merge");
106
+ function cn(...inputs) {
107
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
108
+ }
109
+
110
+ // src/context/ThemeContext.tsx
111
+ var React = __toESM(require("react"));
112
+ var import_jsx_runtime = require("react/jsx-runtime");
113
+ var ThemeContext = React.createContext({ themeClass: "" });
114
+ function ThemeProvider({
115
+ children,
116
+ themeClass
117
+ }) {
118
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: { themeClass }, children });
119
+ }
120
+ function useTheme() {
121
+ return React.useContext(ThemeContext);
122
+ }
123
+
124
+ // src/components/shared/dialog.tsx
125
+ var import_jsx_runtime2 = require("react/jsx-runtime");
126
+ var Dialog = DialogPrimitive.Root;
127
+ var DialogTrigger = DialogPrimitive.Trigger;
128
+ var DialogPortal = DialogPrimitive.Portal;
129
+ var DialogClose = DialogPrimitive.Close;
130
+ var DialogOverlay = React2.forwardRef(({ className, ...props }, ref) => {
131
+ const { themeClass } = useTheme();
132
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
133
+ DialogPrimitive.Overlay,
134
+ {
135
+ ref,
136
+ className: cn(
137
+ themeClass,
138
+ "uf-fixed uf-inset-0 uf-z-50 uf-bg-black/40 data-[state=open]:uf-animate-in data-[state=closed]:uf-animate-out data-[state=closed]:uf-fade-out-0 data-[state=open]:uf-fade-in-0",
139
+ className
140
+ ),
141
+ ...props
142
+ }
143
+ );
144
+ });
145
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
146
+ var DialogContent = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(DialogPortal, { children: [
147
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DialogOverlay, {}),
148
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
149
+ DialogPrimitive.Content,
150
+ {
151
+ ref,
152
+ className: cn(
153
+ // Mobile: bottom-aligned, full-width
154
+ "uf-fixed uf-bottom-0 uf-left-0 uf-right-0 uf-z-50 uf-grid uf-w-full uf-max-w-full",
155
+ // Mobile: rounded top corners only
156
+ "uf-rounded-t-3xl",
157
+ // Desktop: centered modal (no default max-width, let parent specify)
158
+ "sm:uf-left-[50%] sm:uf-top-[50%] sm:uf-bottom-auto sm:uf-right-auto sm:uf-translate-x-[-50%] sm:uf-translate-y-[-50%]",
159
+ // Desktop: rounded all corners
160
+ "sm:uf-rounded-3xl",
161
+ // Common styles
162
+ "uf-gap-4 uf-border uf-bg-background uf-p-6 uf-shadow-lg uf-duration-200",
163
+ // Animations - mobile slides from bottom
164
+ "data-[state=open]:uf-animate-in data-[state=closed]:uf-animate-out",
165
+ "data-[state=closed]:uf-fade-out-0 data-[state=open]:uf-fade-in-0",
166
+ "data-[state=closed]:uf-slide-out-to-bottom data-[state=open]:uf-slide-in-from-bottom",
167
+ // Desktop animations - center zoom
168
+ "sm:data-[state=closed]:uf-zoom-out-95 sm:data-[state=open]:uf-zoom-in-95",
169
+ "sm:data-[state=closed]:uf-slide-out-to-left-1/2 sm:data-[state=closed]:uf-slide-out-to-top-[48%]",
170
+ "sm:data-[state=open]:uf-slide-in-from-left-1/2 sm:data-[state=open]:uf-slide-in-from-top-[48%]",
171
+ className
172
+ ),
173
+ ...props,
174
+ children: [
175
+ children,
176
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(DialogPrimitive.Close, { className: "uf-absolute uf-right-6 uf-top-6 uf-rounded-sm uf-opacity-70 uf-ring-offset-background uf-transition-opacity hover:uf-opacity-100 focus:uf-outline-none focus:uf-ring-2 focus:uf-ring-ring focus:uf-ring-offset-2 disabled:uf-pointer-events-none data-[state=open]:uf-bg-accent data-[state=open]:uf-text-muted-foreground", children: [
177
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.X, { className: "uf-h-6 uf-w-6" }),
178
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "uf-sr-only", children: "Close" })
179
+ ] })
180
+ ]
181
+ }
182
+ )
183
+ ] }));
184
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
185
+ var DialogHeader = ({
186
+ className,
187
+ ...props
188
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
189
+ "div",
190
+ {
191
+ className: cn(
192
+ "uf-flex uf-flex-col uf-space-y-1.5 uf-text-center sm:uf-text-left",
193
+ className
194
+ ),
195
+ ...props
196
+ }
197
+ );
198
+ DialogHeader.displayName = "DialogHeader";
199
+ var DialogFooter = ({
200
+ className,
201
+ ...props
202
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
203
+ "div",
204
+ {
205
+ className: cn(
206
+ "uf-flex uf-flex-col-reverse sm:uf-flex-row sm:uf-justify-end sm:uf-space-x-2",
207
+ className
208
+ ),
209
+ ...props
210
+ }
211
+ );
212
+ DialogFooter.displayName = "DialogFooter";
213
+ var DialogTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
214
+ DialogPrimitive.Title,
215
+ {
216
+ ref,
217
+ className: cn(
218
+ "uf-text-lg uf-font-semibold uf-leading-none uf-tracking-tight",
219
+ className
220
+ ),
221
+ ...props
222
+ }
223
+ ));
224
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
225
+ var DialogDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
226
+ DialogPrimitive.Description,
227
+ {
228
+ ref,
229
+ className: cn("uf-text-sm uf-text-muted-foreground", className),
230
+ ...props
231
+ }
232
+ ));
233
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
234
+
235
+ // src/components/deposits/TransferCryptoBase.tsx
236
+ var import_react3 = require("react");
237
+ var import_lucide_react5 = require("lucide-react");
238
+
239
+ // src/components/deposits/StyledQRCode.tsx
240
+ var import_react = require("react");
241
+ var import_qr_code_styling = __toESM(require("qr-code-styling"));
242
+ var import_jsx_runtime3 = require("react/jsx-runtime");
243
+ function StyledQRCode({
244
+ value,
245
+ size = 200,
246
+ imageUrl,
247
+ imageSize = 50,
248
+ darkMode = false
249
+ }) {
250
+ const ref = (0, import_react.useRef)(null);
251
+ const qrCodeRef = (0, import_react.useRef)(null);
252
+ (0, import_react.useEffect)(() => {
253
+ if (!ref.current) return;
254
+ if (!qrCodeRef.current) {
255
+ qrCodeRef.current = new import_qr_code_styling.default({
256
+ type: "svg",
257
+ width: size,
258
+ height: size,
259
+ data: value,
260
+ margin: 0,
261
+ qrOptions: {
262
+ typeNumber: 0,
263
+ mode: "Byte",
264
+ errorCorrectionLevel: "H"
265
+ },
266
+ imageOptions: {
267
+ hideBackgroundDots: true,
268
+ imageSize: imageSize / size,
269
+ margin: 4,
270
+ crossOrigin: "anonymous"
271
+ },
272
+ dotsOptions: {
273
+ type: "dots",
274
+ color: darkMode ? "#ffffff" : "#000000"
275
+ },
276
+ backgroundOptions: {
277
+ color: darkMode ? "#1a1a1a" : "#ffffff"
278
+ },
279
+ image: imageUrl,
280
+ cornersSquareOptions: {
281
+ type: "extra-rounded",
282
+ color: darkMode ? "#ffffff" : "#000000"
283
+ },
284
+ cornersDotOptions: {
285
+ type: "dot",
286
+ color: darkMode ? "#ffffff" : "#000000"
287
+ }
288
+ });
289
+ qrCodeRef.current.append(ref.current);
290
+ }
291
+ }, []);
292
+ (0, import_react.useEffect)(() => {
293
+ if (qrCodeRef.current) {
294
+ qrCodeRef.current.update({
295
+ data: value,
296
+ image: imageUrl,
297
+ width: size,
298
+ height: size,
299
+ dotsOptions: {
300
+ type: "dots",
301
+ color: darkMode ? "#ffffff" : "#000000"
302
+ },
303
+ backgroundOptions: {
304
+ color: darkMode ? "#1a1a1a" : "#ffffff"
305
+ },
306
+ cornersSquareOptions: {
307
+ type: "extra-rounded",
308
+ color: darkMode ? "#ffffff" : "#000000"
309
+ },
310
+ cornersDotOptions: {
311
+ type: "dot",
312
+ color: darkMode ? "#ffffff" : "#000000"
313
+ }
314
+ });
315
+ }
316
+ }, [value, size, imageUrl, imageSize, darkMode]);
317
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
318
+ "div",
319
+ {
320
+ ref,
321
+ style: {
322
+ width: size,
323
+ height: size,
324
+ display: "flex",
325
+ alignItems: "center",
326
+ justifyContent: "center"
327
+ }
328
+ }
329
+ );
330
+ }
331
+
332
+ // src/components/deposits/DepositsModal.tsx
333
+ var import_react2 = require("react");
334
+
335
+ // src/components/deposits/DepositHeader.tsx
336
+ var import_lucide_react2 = require("lucide-react");
337
+ var import_jsx_runtime4 = require("react/jsx-runtime");
338
+ function DepositHeader({
339
+ title,
340
+ showBack = false,
341
+ showClose = true,
342
+ onBack,
343
+ onClose,
344
+ badge
345
+ }) {
346
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-2", children: [
347
+ showBack ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
348
+ "button",
349
+ {
350
+ onClick: onBack,
351
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
352
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ArrowLeft, { className: "uf-w-5 uf-h-5" })
353
+ }
354
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
355
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
356
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DialogTitle, { className: "uf-text-center uf-text-base uf-font-light uf-text-foreground", children: title }),
357
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-bg-secondary uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px] uf-text-muted-foreground", children: badge.count })
358
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DialogTitle, { className: "uf-text-center uf-text-base uf-font-light uf-text-foreground", children: title }),
359
+ showClose ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
360
+ "button",
361
+ {
362
+ onClick: onClose,
363
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
364
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.X, { className: "uf-w-5 uf-h-5" })
365
+ }
366
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
367
+ ] });
368
+ }
369
+
370
+ // src/components/deposits/DepositExecutionItem.tsx
371
+ var import_lucide_react3 = require("lucide-react");
372
+
373
+ // src/lib/api.ts
374
+ var API_BASE_URL = "http://localhost:3002";
375
+ var DEFAULT_PUBLISHABLE_KEY = "pk_test_123";
376
+ var DEFAULT_CONFIG = {};
377
+ function setApiConfig(config) {
378
+ if (config.baseUrl) {
379
+ API_BASE_URL = config.baseUrl;
380
+ }
381
+ if (config.publishableKey) {
382
+ DEFAULT_PUBLISHABLE_KEY = config.publishableKey;
383
+ }
384
+ if (config.defaultConfig) {
385
+ DEFAULT_CONFIG = config.defaultConfig;
386
+ }
387
+ }
388
+ function getApiBaseUrl() {
389
+ return API_BASE_URL;
390
+ }
391
+ function getIconUrl(iconPath) {
392
+ const normalizedPath = iconPath.startsWith("/") ? iconPath : `/${iconPath}`;
393
+ return `${API_BASE_URL}/api/public${normalizedPath}`;
394
+ }
395
+ async function createEOA(overrides, publishableKey) {
396
+ if (!overrides?.user_id) {
397
+ throw new Error("user_id is required");
398
+ }
399
+ const payload = {
400
+ user_id: overrides.user_id,
401
+ destination_chain_type: overrides?.destination_chain_type || "ethereum",
402
+ destination_chain_id: overrides?.destination_chain_id || DEFAULT_CONFIG.destinationChainId || "8453",
403
+ destination_token_address: overrides?.destination_token_address || DEFAULT_CONFIG.destinationTokenAddress || "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
404
+ recipient_address: overrides?.recipient_address || DEFAULT_CONFIG.recipientAddress || "0x309a4154a2CD4153Da886E780890C9cb5161553C",
405
+ client_metadata: overrides?.client_metadata || {}
406
+ };
407
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
408
+ const response = await fetch(`${API_BASE_URL}/v1/public/deposit_addresses`, {
409
+ method: "POST",
410
+ headers: {
411
+ accept: "application/json",
412
+ "x-publishable-key": pk,
413
+ "Content-Type": "application/json"
414
+ },
415
+ body: JSON.stringify(payload)
416
+ });
417
+ if (!response.ok) {
418
+ throw new Error(`Failed to create EOA: ${response.statusText}`);
419
+ }
420
+ return response.json();
421
+ }
422
+ function getWalletByChainType(wallets, chainType) {
423
+ return wallets.find((wallet) => wallet.chain_type === chainType);
424
+ }
425
+ var ExecutionStatus = /* @__PURE__ */ ((ExecutionStatus2) => {
426
+ ExecutionStatus2["DELAYED"] = "delayed";
427
+ ExecutionStatus2["FAILED"] = "failed";
428
+ ExecutionStatus2["PENDING"] = "pending";
429
+ ExecutionStatus2["REFUNDED"] = "refunded";
430
+ ExecutionStatus2["SUCCEEDED"] = "succeeded";
431
+ ExecutionStatus2["WAITING"] = "waiting";
432
+ return ExecutionStatus2;
433
+ })(ExecutionStatus || {});
434
+ var SOLANA_USDC_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
435
+ async function queryExecutions(externalUserId, publishableKey) {
436
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
437
+ const response = await fetch(
438
+ `${API_BASE_URL}/v1/public/direct_executions/query`,
439
+ {
440
+ method: "POST",
441
+ headers: {
442
+ accept: "application/json",
443
+ "x-publishable-key": pk,
444
+ "Content-Type": "application/json"
445
+ },
446
+ body: JSON.stringify({
447
+ external_user_id: externalUserId
448
+ })
449
+ }
450
+ );
451
+ if (!response.ok) {
452
+ throw new Error(`Failed to query executions: ${response.statusText}`);
453
+ }
454
+ return response.json();
455
+ }
456
+ async function getSupportedDepositTokens(publishableKey) {
457
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
458
+ const response = await fetch(
459
+ `${API_BASE_URL}/v1/public/tokens/supported_deposit_tokens`,
460
+ {
461
+ method: "GET",
462
+ headers: {
463
+ accept: "application/json",
464
+ "x-publishable-key": pk
465
+ }
466
+ }
467
+ );
468
+ if (!response.ok) {
469
+ throw new Error(
470
+ `Failed to fetch supported deposit tokens: ${response.statusText}`
471
+ );
472
+ }
473
+ return response.json();
474
+ }
475
+ async function getMeldQuotes(request, publishableKey) {
476
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
477
+ const response = await fetch(
478
+ `${API_BASE_URL}/v1/public/onramps/meld/quotes`,
479
+ {
480
+ method: "POST",
481
+ headers: {
482
+ accept: "application/json",
483
+ "x-publishable-key": pk,
484
+ "Content-Type": "application/json"
485
+ },
486
+ body: JSON.stringify(request)
487
+ }
488
+ );
489
+ if (!response.ok) {
490
+ throw new Error(`Failed to fetch Meld quotes: ${response.statusText}`);
491
+ }
492
+ return response.json();
493
+ }
494
+ async function createMeldSession(request, publishableKey) {
495
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
496
+ const response = await fetch(
497
+ `${API_BASE_URL}/v1/public/onramps/meld/sessions`,
498
+ {
499
+ method: "POST",
500
+ headers: {
501
+ accept: "application/json",
502
+ "x-publishable-key": pk,
503
+ "Content-Type": "application/json"
504
+ },
505
+ body: JSON.stringify(request)
506
+ }
507
+ );
508
+ if (!response.ok) {
509
+ throw new Error(`Failed to create Meld session: ${response.statusText}`);
510
+ }
511
+ return response.json();
512
+ }
513
+ async function getFiatCurrencies(publishableKey) {
514
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
515
+ const response = await fetch(
516
+ `${API_BASE_URL}/v1/public/onramps/fiat_currencies`,
517
+ {
518
+ method: "GET",
519
+ headers: {
520
+ accept: "application/json",
521
+ "x-publishable-key": pk
522
+ }
523
+ }
524
+ );
525
+ if (!response.ok) {
526
+ throw new Error(`Failed to fetch fiat currencies: ${response.statusText}`);
527
+ }
528
+ return response.json();
529
+ }
530
+
531
+ // src/components/deposits/DepositExecutionItem.tsx
532
+ var import_jsx_runtime5 = require("react/jsx-runtime");
533
+ function DepositExecutionItem({
534
+ execution,
535
+ showCloseButton = false,
536
+ onClose
537
+ }) {
538
+ const isPending = execution.status === "pending" /* PENDING */ || execution.status === "waiting" /* WAITING */ || execution.status === "delayed" /* DELAYED */;
539
+ const formatTxHash = (hash) => {
540
+ if (hash.length <= 12) return hash;
541
+ return `${hash.slice(0, 16)}...${hash.slice(-8)}`;
542
+ };
543
+ const formatDateTime = (timestamp) => {
544
+ try {
545
+ const date = new Date(timestamp);
546
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric" }) + " \xB7 " + date.toLocaleTimeString("en-US", {
547
+ hour: "numeric",
548
+ minute: "2-digit",
549
+ second: "2-digit",
550
+ hour12: false
551
+ });
552
+ } catch {
553
+ return timestamp;
554
+ }
555
+ };
556
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-bg-card uf-border uf-border-border uf-rounded-xl uf-overflow-hidden uf-p-3", children: [
557
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-flex uf-items-start uf-justify-between", children: [
558
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2.5 uf-flex-1", children: [
559
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-relative uf-flex-shrink-0", children: [
560
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
561
+ "img",
562
+ {
563
+ src: execution.source_token_metadata?.icon_url || getIconUrl("/icons/tokens/usdc.svg"),
564
+ alt: "Token",
565
+ width: 32,
566
+ height: 32,
567
+ className: "uf-rounded-full"
568
+ }
569
+ ),
570
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "uf-absolute uf--bottom-0.5 uf--right-0.5 uf-bg-yellow-500 uf-rounded-full uf-p-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
571
+ "svg",
572
+ {
573
+ width: "10",
574
+ height: "10",
575
+ viewBox: "0 0 12 12",
576
+ fill: "none",
577
+ className: "uf-animate-spin",
578
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
579
+ "path",
580
+ {
581
+ d: "M6 1V3M6 9V11M1 6H3M9 6H11M2.5 2.5L4 4M8 8L9.5 9.5M2.5 9.5L4 8M8 4L9.5 2.5",
582
+ stroke: "white",
583
+ strokeWidth: "2",
584
+ strokeLinecap: "round"
585
+ }
586
+ )
587
+ }
588
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "uf-absolute uf--bottom-0.5 uf--right-0.5 uf-bg-green-500 uf-rounded-full uf-p-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
589
+ "path",
590
+ {
591
+ d: "M10 3L4.5 8.5L2 6",
592
+ stroke: "white",
593
+ strokeWidth: "2",
594
+ strokeLinecap: "round",
595
+ strokeLinejoin: "round"
596
+ }
597
+ ) }) })
598
+ ] }),
599
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-flex-1 uf-min-w-0", children: [
600
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-mb-0.5", children: [
601
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "uf-text-foreground uf-font-medium uf-text-sm", children: isPending ? "Deposit received" : "Deposit completed" }),
602
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "uf-text-muted-foreground uf-text-xs uf-whitespace-nowrap uf-ml-2", children: formatDateTime(execution.created_at || (/* @__PURE__ */ new Date()).toISOString()) })
603
+ ] }),
604
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "uf-text-muted-foreground uf-text-xs", children: isPending ? "Your account will be credited shortly." : "Your account has been credited successfully." })
605
+ ] })
606
+ ] }),
607
+ showCloseButton && onClose && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
608
+ "button",
609
+ {
610
+ onClick: onClose,
611
+ className: "uf-text-muted-foreground hover:uf-text-foreground uf-transition-colors uf-p-0.5 uf-flex-shrink-0 uf-ml-2",
612
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.X, { className: "uf-w-4 uf-h-4" })
613
+ }
614
+ )
615
+ ] }),
616
+ !isPending && execution.explorer_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-2 uf-pt-2 uf-border-t uf-border-secondary uf-text-xs uf-ml-[42px]", children: [
617
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "uf-text-muted-foreground", children: "Deposit tx:" }),
618
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
619
+ "a",
620
+ {
621
+ href: execution.explorer_url,
622
+ target: "_blank",
623
+ rel: "noopener noreferrer",
624
+ className: "uf-flex uf-items-center uf-gap-1 uf-text-blue-400 hover:uf-text-blue-300 uf-transition-colors uf-font-mono",
625
+ children: [
626
+ formatTxHash(execution.transaction_hash),
627
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.ExternalLink, { className: "uf-w-3 uf-h-3" })
628
+ ]
629
+ }
630
+ )
631
+ ] })
632
+ ] });
633
+ }
634
+
635
+ // src/components/deposits/DepositsModal.tsx
636
+ var import_jsx_runtime6 = require("react/jsx-runtime");
637
+ function DepositsModal({
638
+ open,
639
+ onOpenChange,
640
+ executions: sessionExecutions,
641
+ userId,
642
+ publishableKey,
643
+ themeClass = ""
644
+ }) {
645
+ const [allExecutions, setAllExecutions] = (0, import_react2.useState)(sessionExecutions);
646
+ (0, import_react2.useEffect)(() => {
647
+ if (!open || !userId) return;
648
+ const fetchExecutions = async () => {
649
+ try {
650
+ const response = await queryExecutions(userId, publishableKey);
651
+ const sorted = [...response.data].sort((a, b) => {
652
+ const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
653
+ const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
654
+ return timeB - timeA;
655
+ });
656
+ setAllExecutions(sorted);
657
+ } catch (error) {
658
+ console.error("Failed to fetch executions:", error);
659
+ setAllExecutions(sessionExecutions);
660
+ }
661
+ };
662
+ fetchExecutions();
663
+ const pollInterval = setInterval(fetchExecutions, 1e4);
664
+ return () => {
665
+ clearInterval(pollInterval);
666
+ };
667
+ }, [open, userId, publishableKey, sessionExecutions]);
668
+ const handleClose = () => {
669
+ onOpenChange(false);
670
+ };
671
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogContent, { className: `sm:uf-max-w-[400px] !uf-bg-card uf-border-secondary uf-text-foreground uf-p-0 uf-gap-0 [&>button]:uf-hidden ${themeClass}`, children: [
672
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DepositHeader, { title: "Deposit Tracker", onClose: handleClose }),
673
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "uf-max-h-[500px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "uf-space-y-3", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "uf-text-muted-foreground uf-text-sm", children: "No deposits yet" }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DepositExecutionItem, { execution }, execution.id)) }) }) })
674
+ ] }) });
675
+ }
676
+
677
+ // src/components/deposits/DepositSuccessToast.tsx
678
+ var import_jsx_runtime7 = require("react/jsx-runtime");
679
+ function DepositSuccessToast({
680
+ depositTx,
681
+ completionTx,
682
+ orderSubmittedAt,
683
+ orderFilledAt,
684
+ explorerUrl,
685
+ completionExplorerUrl,
686
+ status,
687
+ tokenIconUrl,
688
+ onClose
689
+ }) {
690
+ const execution = {
691
+ id: depositTx,
692
+ transaction_hash: depositTx,
693
+ explorer_url: explorerUrl,
694
+ destination_transaction_hashes: completionTx ? [completionTx] : void 0,
695
+ status,
696
+ created_at: orderSubmittedAt,
697
+ updated_at: orderFilledAt,
698
+ source_token_metadata: tokenIconUrl ? { icon_url: tokenIconUrl } : void 0
699
+ };
700
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "uf-w-full uf-animate-in uf-slide-in-from-bottom-2 uf-duration-300", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
701
+ DepositExecutionItem,
702
+ {
703
+ execution,
704
+ showCloseButton: true,
705
+ onClose
706
+ }
707
+ ) });
708
+ }
709
+
710
+ // src/components/shared/select.tsx
711
+ var React3 = __toESM(require("react"));
712
+ var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
713
+ var import_lucide_react4 = require("lucide-react");
714
+ var import_jsx_runtime8 = require("react/jsx-runtime");
715
+ var Select = SelectPrimitive.Root;
716
+ var SelectGroup = SelectPrimitive.Group;
717
+ var SelectValue = SelectPrimitive.Value;
718
+ var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
719
+ SelectPrimitive.Trigger,
720
+ {
721
+ ref,
722
+ className: cn(
723
+ "uf-flex uf-h-10 uf-w-full uf-items-center uf-justify-between uf-rounded-md uf-border uf-border-border !uf-bg-secondary uf-px-3 uf-py-2 uf-text-sm uf-text-foreground uf-ring-offset-background placeholder:uf-text-muted-foreground focus:uf-outline-none focus:uf-ring-2 focus:uf-ring-ring focus:uf-ring-offset-2 disabled:uf-cursor-not-allowed disabled:uf-opacity-50 [&>span]:uf-line-clamp-1",
724
+ className
725
+ ),
726
+ ...props,
727
+ children: [
728
+ children,
729
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronDown, { className: "uf-h-4 uf-w-4 uf-opacity-50" }) })
730
+ ]
731
+ }
732
+ ));
733
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
734
+ var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
735
+ SelectPrimitive.ScrollUpButton,
736
+ {
737
+ ref,
738
+ className: cn(
739
+ "uf-flex uf-cursor-default uf-items-center uf-justify-center uf-py-1",
740
+ className
741
+ ),
742
+ ...props,
743
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronUp, { className: "uf-h-4 uf-w-4" })
744
+ }
745
+ ));
746
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
747
+ var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
748
+ SelectPrimitive.ScrollDownButton,
749
+ {
750
+ ref,
751
+ className: cn(
752
+ "uf-flex uf-cursor-default uf-items-center uf-justify-center uf-py-1",
753
+ className
754
+ ),
755
+ ...props,
756
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.ChevronDown, { className: "uf-h-4 uf-w-4" })
757
+ }
758
+ ));
759
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
760
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => {
761
+ const { themeClass } = useTheme();
762
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
763
+ SelectPrimitive.Content,
764
+ {
765
+ ref,
766
+ className: cn(
767
+ themeClass,
768
+ "uf-relative uf-z-50 uf-max-h-96 uf-min-w-[8rem] uf-overflow-hidden uf-rounded-lg uf-border uf-border-border !uf-bg-popover uf-text-popover-foreground uf-shadow-lg data-[state=open]:uf-animate-in data-[state=closed]:uf-animate-out data-[state=closed]:uf-fade-out-0 data-[state=open]:uf-fade-in-0 data-[state=closed]:uf-zoom-out-95 data-[state=open]:uf-zoom-in-95 data-[side=bottom]:uf-slide-in-from-top-2 data-[side=left]:uf-slide-in-from-right-2 data-[side=right]:uf-slide-in-from-left-2 data-[side=top]:uf-slide-in-from-bottom-2",
769
+ position === "popper" && "data-[side=bottom]:uf-translate-y-1 data-[side=left]:uf--translate-x-1 data-[side=right]:uf-translate-x-1 data-[side=top]:uf--translate-y-1",
770
+ className
771
+ ),
772
+ position,
773
+ ...props,
774
+ children: [
775
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectScrollUpButton, {}),
776
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
777
+ SelectPrimitive.Viewport,
778
+ {
779
+ className: cn(
780
+ "uf-p-1",
781
+ position === "popper" && "uf-h-[var(--radix-select-trigger-height)] uf-w-full uf-min-w-[var(--radix-select-trigger-width)]"
782
+ ),
783
+ children
784
+ }
785
+ ),
786
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectScrollDownButton, {})
787
+ ]
788
+ }
789
+ ) });
790
+ });
791
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
792
+ var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
793
+ SelectPrimitive.Label,
794
+ {
795
+ ref,
796
+ className: cn("uf-py-1.5 uf-pl-8 uf-pr-2 uf-text-sm uf-font-semibold", className),
797
+ ...props
798
+ }
799
+ ));
800
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
801
+ var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
802
+ SelectPrimitive.Item,
803
+ {
804
+ ref,
805
+ className: cn(
806
+ "uf-relative uf-flex uf-w-full uf-cursor-default uf-select-none uf-items-center uf-rounded-sm uf-py-1.5 uf-pl-8 uf-pr-2 uf-text-sm uf-text-foreground uf-outline-none focus:uf-bg-accent focus:uf-text-accent-foreground data-[disabled]:uf-pointer-events-none data-[disabled]:uf-opacity-50 hover:uf-bg-accent",
807
+ className
808
+ ),
809
+ ...props,
810
+ children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "uf-absolute uf-left-2 uf-flex uf-h-3.5 uf-w-3.5 uf-items-center uf-justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.Check, { className: "uf-h-4 uf-w-4" }) }) }),
812
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemText, { children })
813
+ ]
814
+ }
815
+ ));
816
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
817
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
818
+ SelectPrimitive.Separator,
819
+ {
820
+ ref,
821
+ className: cn("uf--mx-1 uf-my-1 uf-h-px uf-bg-muted", className),
822
+ ...props
823
+ }
824
+ ));
825
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
826
+
827
+ // src/components/shared/button.tsx
828
+ var React4 = __toESM(require("react"));
829
+ var import_react_slot = require("@radix-ui/react-slot");
830
+ var import_class_variance_authority = require("class-variance-authority");
831
+ var import_jsx_runtime9 = require("react/jsx-runtime");
832
+ var buttonVariants = (0, import_class_variance_authority.cva)(
833
+ "uf-inline-flex uf-items-center uf-justify-center uf-whitespace-nowrap uf-rounded-md uf-text-sm uf-font-medium uf-ring-offset-background uf-transition-colors focus-visible:uf-outline-none focus-visible:uf-ring-2 focus-visible:uf-ring-ring focus-visible:uf-ring-offset-2 disabled:uf-pointer-events-none disabled:uf-opacity-50",
834
+ {
835
+ variants: {
836
+ variant: {
837
+ default: "uf-bg-primary uf-text-primary-foreground hover:uf-bg-primary/90",
838
+ destructive: "uf-bg-destructive uf-text-destructive-foreground hover:uf-bg-destructive/90",
839
+ outline: "uf-border uf-border-input uf-bg-background hover:uf-bg-accent hover:uf-text-accent-foreground",
840
+ secondary: "uf-bg-secondary uf-text-secondary-foreground hover:uf-bg-secondary/80",
841
+ ghost: "hover:uf-bg-accent hover:uf-text-accent-foreground",
842
+ link: "uf-text-primary uf-underline-offset-4 hover:uf-underline"
843
+ },
844
+ size: {
845
+ default: "uf-h-10 uf-px-4 uf-py-2",
846
+ sm: "uf-h-9 uf-rounded-md uf-px-3",
847
+ lg: "uf-h-11 uf-rounded-md uf-px-8",
848
+ icon: "uf-h-10 uf-w-10"
849
+ }
850
+ },
851
+ defaultVariants: {
852
+ variant: "default",
853
+ size: "default"
854
+ }
855
+ }
856
+ );
857
+ var Button = React4.forwardRef(
858
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
859
+ const Comp = asChild ? import_react_slot.Slot : "button";
860
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
861
+ Comp,
862
+ {
863
+ className: cn(buttonVariants({ variant, size, className })),
864
+ ref,
865
+ ...props
866
+ }
867
+ );
868
+ }
869
+ );
870
+ Button.displayName = "Button";
871
+
872
+ // src/components/shared/tooltip.tsx
873
+ var React5 = __toESM(require("react"));
874
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
875
+ var import_jsx_runtime10 = require("react/jsx-runtime");
876
+ var TooltipProvider = TooltipPrimitive.Provider;
877
+ var Tooltip = TooltipPrimitive.Root;
878
+ var TooltipTrigger = TooltipPrimitive.Trigger;
879
+ var TooltipContent = React5.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
880
+ const { themeClass } = useTheme();
881
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
882
+ TooltipPrimitive.Content,
883
+ {
884
+ ref,
885
+ sideOffset,
886
+ className: cn(
887
+ themeClass,
888
+ "uf-z-[9999] uf-w-[calc(100vw-2rem)] uf-max-w-[280px] uf-overflow-hidden uf-rounded-lg uf-bg-popover uf-px-3 uf-py-2 uf-text-xs uf-text-popover-foreground uf-shadow-lg uf-border uf-border-border uf-animate-in uf-fade-in-0 uf-zoom-in-95 data-[state=closed]:uf-animate-out data-[state=closed]:uf-fade-out-0 data-[state=closed]:uf-zoom-out-95 data-[side=bottom]:uf-slide-in-from-top-2 data-[side=left]:uf-slide-in-from-right-2 data-[side=right]:uf-slide-in-from-left-2 data-[side=top]:uf-slide-in-from-bottom-2",
889
+ className
890
+ ),
891
+ ...props
892
+ }
893
+ ) });
894
+ });
895
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
896
+
897
+ // src/lib/i18n/en.json
898
+ var en_default = {
899
+ transferCrypto: {
900
+ priceImpact: {
901
+ label: "Price impact",
902
+ tooltip: "Price impact reflects the difference between the expected price and the final execution price, influenced by trade size and available liquidity. Larger trades may move the market price during execution.",
903
+ finalCost: "The final cost reflects price impact and may vary depending on market and network conditions. Larger trade sizes typically benefit from lower relative costs."
904
+ },
905
+ slippage: {
906
+ label: "Max slippage",
907
+ auto: "Auto",
908
+ tooltip: "Slippage represents price changes that can occur while a transaction is being processed. Slippage is dynamically adjusted per trading pair to support reliable execution during market movements.",
909
+ finalCost: "The final cost includes any slippage and may change based on real-time network conditions. Costs are generally reduced for larger transaction amounts."
910
+ },
911
+ processingTime: {
912
+ label: "Processing time",
913
+ lessThanMinutes: "< {{minutes}} min",
914
+ lessThanHours: "< {{hours}} hr"
915
+ },
916
+ minDeposit: {
917
+ label: "min",
918
+ tooltip: "The minimum amount you can deposit on the selected network."
919
+ },
920
+ help: {
921
+ needHelp: "Need help?",
922
+ contactSupport: "Contact support"
923
+ },
924
+ terms: {
925
+ termsApply: "Terms apply"
926
+ },
927
+ supportedToken: "Supported token",
928
+ supportedChain: "Supported chain",
929
+ depositAddress: {
930
+ label: "Your deposit address",
931
+ tooltip: "Send any supported token to this address, and it will be automatically converted to {{token}} in your account."
932
+ },
933
+ copyAddress: "Copy address",
934
+ copied: "Copied!",
935
+ loading: "Loading...",
936
+ loadingQRCode: "Loading QR Code...",
937
+ noAddressAvailable: "No address available",
938
+ noChainsAvailable: "No chains available for this token"
939
+ },
940
+ depositModal: {
941
+ transferCrypto: {
942
+ title: "Transfer Crypto",
943
+ subtitle: "No limit \u2022 Instant"
944
+ },
945
+ depositWithCard: {
946
+ title: "Deposit with Card",
947
+ subtitle: "$50,000 limit \u2022 2 min"
948
+ },
949
+ quotes: "Quotes"
950
+ },
951
+ buyWithCard: {
952
+ onramp: {
953
+ completeTransaction: "Complete transaction with {{provider}}",
954
+ canCloseModal: "You can close this modal.",
955
+ youUse: "You use",
956
+ youBuy: "You buy",
957
+ youReceive: "You receive",
958
+ intentAddressNote: "The wallet address displayed in the payment provider is a temporary deposit address. Your funds will be automatically converted and deposited into your account."
959
+ }
960
+ }
961
+ };
962
+
963
+ // src/lib/i18n.ts
964
+ var i18n = en_default;
965
+
966
+ // src/components/deposits/TransferCryptoBase.tsx
967
+ var import_jsx_runtime11 = require("react/jsx-runtime");
968
+ var t = i18n.transferCrypto;
969
+ var getChainKey = (chainId, chainType) => {
970
+ return `${chainType}:${chainId}`;
971
+ };
972
+ var parseChainKey = (chainKey) => {
973
+ const [chainType, chainId] = chainKey.split(":");
974
+ return { chainType, chainId };
975
+ };
976
+ function TransferCryptoBase({
977
+ userId,
978
+ publishableKey,
979
+ recipientAddress,
980
+ destinationChainId,
981
+ destinationTokenAddress,
982
+ copyButtonMode = "compact",
983
+ layoutVariant = "horizontal",
984
+ showDetailedDropdowns = false,
985
+ onExecutionsChange,
986
+ onDepositSuccess,
987
+ onDepositError
988
+ }) {
989
+ const { themeClass } = useTheme();
990
+ const isDarkMode = themeClass.includes("uf-dark");
991
+ const [token, setToken] = (0, import_react3.useState)("USDC");
992
+ const [chain, setChain] = (0, import_react3.useState)("solana:mainnet");
993
+ const [copied, setCopied] = (0, import_react3.useState)(false);
994
+ const [wallets, setWallets] = (0, import_react3.useState)([]);
995
+ const [loading, setLoading] = (0, import_react3.useState)(true);
996
+ const [error, setError] = (0, import_react3.useState)(null);
997
+ const [depositExecutions, setDepositExecutions] = (0, import_react3.useState)([]);
998
+ const [trackedExecutions, setTrackedExecutions] = (0, import_react3.useState)(/* @__PURE__ */ new Map());
999
+ const [modalOpenedAt, setModalOpenedAt] = (0, import_react3.useState)(null);
1000
+ const [supportedTokens, setSupportedTokens] = (0, import_react3.useState)([]);
1001
+ const [tokensLoading, setTokensLoading] = (0, import_react3.useState)(true);
1002
+ const [detailsExpanded, setDetailsExpanded] = (0, import_react3.useState)(false);
1003
+ const [depositsModalOpen, setDepositsModalOpen] = (0, import_react3.useState)(false);
1004
+ const allChainsMap = /* @__PURE__ */ new Map();
1005
+ supportedTokens.forEach((t4) => {
1006
+ t4.chains.forEach((c) => {
1007
+ const comboKey = `${c.chain_type}:${c.chain_id}`;
1008
+ if (!allChainsMap.has(comboKey)) {
1009
+ allChainsMap.set(comboKey, c);
1010
+ }
1011
+ });
1012
+ });
1013
+ const allAvailableChains = Array.from(allChainsMap.values());
1014
+ const currentChainCombo = parseChainKey(chain);
1015
+ const currentChainData = allAvailableChains.find(
1016
+ (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
1017
+ );
1018
+ const currentChainType = currentChainData?.chain_type || "ethereum";
1019
+ const currentWallet = getWalletByChainType(wallets, currentChainType);
1020
+ const depositAddress = currentWallet?.address || "";
1021
+ (0, import_react3.useEffect)(() => {
1022
+ setModalOpenedAt(/* @__PURE__ */ new Date());
1023
+ }, []);
1024
+ (0, import_react3.useEffect)(() => {
1025
+ async function fetchSupportedTokens() {
1026
+ try {
1027
+ setTokensLoading(true);
1028
+ const response = await getSupportedDepositTokens(publishableKey);
1029
+ setSupportedTokens(response.data);
1030
+ if (response.data.length > 0) {
1031
+ const allChains = /* @__PURE__ */ new Set();
1032
+ response.data.forEach((t4) => {
1033
+ t4.chains.forEach((c) => {
1034
+ allChains.add(getChainKey(c.chain_id, c.chain_type));
1035
+ });
1036
+ });
1037
+ if (!allChains.has(chain)) {
1038
+ const firstToken = response.data[0];
1039
+ if (firstToken.chains.length > 0) {
1040
+ const firstChain = firstToken.chains[0];
1041
+ setChain(getChainKey(firstChain.chain_id, firstChain.chain_type));
1042
+ }
1043
+ }
1044
+ }
1045
+ } catch (err) {
1046
+ console.error("Error fetching supported tokens:", err);
1047
+ } finally {
1048
+ setTokensLoading(false);
1049
+ }
1050
+ }
1051
+ fetchSupportedTokens();
1052
+ }, [publishableKey, chain]);
1053
+ (0, import_react3.useEffect)(() => {
1054
+ if (onExecutionsChange) {
1055
+ onExecutionsChange(depositExecutions);
1056
+ }
1057
+ }, [depositExecutions, onExecutionsChange]);
1058
+ (0, import_react3.useEffect)(() => {
1059
+ async function fetchWallets() {
1060
+ try {
1061
+ setLoading(true);
1062
+ const response = await createEOA(
1063
+ {
1064
+ user_id: userId,
1065
+ recipient_address: recipientAddress,
1066
+ destination_chain_id: destinationChainId,
1067
+ destination_token_address: destinationTokenAddress
1068
+ },
1069
+ publishableKey
1070
+ );
1071
+ setWallets(response.data);
1072
+ setError(null);
1073
+ } catch (err) {
1074
+ setError(err instanceof Error ? err.message : "Failed to load wallets");
1075
+ console.error("Error fetching wallets:", err);
1076
+ } finally {
1077
+ setLoading(false);
1078
+ }
1079
+ }
1080
+ fetchWallets();
1081
+ }, [
1082
+ userId,
1083
+ recipientAddress,
1084
+ destinationChainId,
1085
+ destinationTokenAddress,
1086
+ publishableKey
1087
+ ]);
1088
+ (0, import_react3.useEffect)(() => {
1089
+ if (!supportedTokens.length) return;
1090
+ const currentToken = supportedTokens.find((t4) => t4.symbol === token);
1091
+ if (!currentToken || currentToken.chains.length === 0) return;
1092
+ const isChainAvailable = currentToken.chains.some((c) => {
1093
+ const key = getChainKey(c.chain_id, c.chain_type);
1094
+ return key === chain;
1095
+ });
1096
+ if (!isChainAvailable) {
1097
+ const firstChain = currentToken.chains[0];
1098
+ const newChain = getChainKey(firstChain.chain_id, firstChain.chain_type);
1099
+ setChain(newChain);
1100
+ }
1101
+ }, [token, supportedTokens, chain]);
1102
+ (0, import_react3.useEffect)(() => {
1103
+ if (!userId || !modalOpenedAt) return;
1104
+ const pollInterval = setInterval(async () => {
1105
+ try {
1106
+ const response = await queryExecutions(userId, publishableKey);
1107
+ let executionToShow = null;
1108
+ for (const execution of response.data) {
1109
+ const executionTime = execution.created_at ? new Date(execution.created_at) : null;
1110
+ if (!executionTime || executionTime <= modalOpenedAt) {
1111
+ continue;
1112
+ }
1113
+ const trackedStatus = trackedExecutions.get(execution.id);
1114
+ if (!trackedStatus) {
1115
+ executionToShow = execution;
1116
+ break;
1117
+ }
1118
+ const inProgressStatuses = [
1119
+ "pending" /* PENDING */,
1120
+ "waiting" /* WAITING */,
1121
+ "delayed" /* DELAYED */
1122
+ ];
1123
+ if (inProgressStatuses.includes(trackedStatus) && execution.status === "succeeded" /* SUCCEEDED */) {
1124
+ executionToShow = execution;
1125
+ break;
1126
+ }
1127
+ }
1128
+ if (executionToShow) {
1129
+ const execution = executionToShow;
1130
+ setDepositExecutions((prev) => {
1131
+ const existingIndex = prev.findIndex((e) => e.id === execution.id);
1132
+ if (existingIndex >= 0) {
1133
+ const updated = [...prev];
1134
+ updated[existingIndex] = execution;
1135
+ return updated;
1136
+ } else {
1137
+ return [...prev, execution];
1138
+ }
1139
+ });
1140
+ setTrackedExecutions((prev) => {
1141
+ const updated = new Map(prev);
1142
+ updated.set(execution.id, execution.status);
1143
+ return updated;
1144
+ });
1145
+ if (onDepositSuccess) {
1146
+ const isCompleted = execution.status === "succeeded" /* SUCCEEDED */;
1147
+ if (isCompleted) {
1148
+ onDepositSuccess({
1149
+ message: "Deposit completed successfully",
1150
+ transaction: execution,
1151
+ executionId: execution.id
1152
+ });
1153
+ }
1154
+ }
1155
+ }
1156
+ } catch (err) {
1157
+ console.error("Error polling executions:", err);
1158
+ if (onDepositError) {
1159
+ onDepositError({
1160
+ message: "Failed to check deposit status",
1161
+ error: err,
1162
+ code: "POLLING_ERROR"
1163
+ });
1164
+ }
1165
+ }
1166
+ }, 5e3);
1167
+ return () => clearInterval(pollInterval);
1168
+ }, [
1169
+ userId,
1170
+ trackedExecutions,
1171
+ modalOpenedAt,
1172
+ publishableKey,
1173
+ onDepositSuccess,
1174
+ onDepositError
1175
+ ]);
1176
+ const selectedToken = supportedTokens.find((t4) => t4.symbol === token);
1177
+ const availableChainsForToken = selectedToken?.chains || [];
1178
+ const currentChainFromBackend = availableChainsForToken.find((c) => {
1179
+ const key = getChainKey(c.chain_id, c.chain_type);
1180
+ return key === chain;
1181
+ }) || allAvailableChains.find((c) => {
1182
+ const key = getChainKey(c.chain_id, c.chain_type);
1183
+ return key === chain;
1184
+ });
1185
+ const handleCopyAddress = () => {
1186
+ navigator.clipboard.writeText(depositAddress);
1187
+ setCopied(true);
1188
+ setTimeout(() => setCopied(false), 2e3);
1189
+ };
1190
+ const formatProcessingTime = (seconds) => {
1191
+ if (seconds === null) {
1192
+ return t.processingTime.lessThanMinutes.replace("{{minutes}}", "1");
1193
+ }
1194
+ const minutes = Math.ceil(seconds / 60);
1195
+ if (minutes < 60) {
1196
+ return t.processingTime.lessThanMinutes.replace(
1197
+ "{{minutes}}",
1198
+ String(minutes)
1199
+ );
1200
+ }
1201
+ const hours = Math.ceil(minutes / 60);
1202
+ return t.processingTime.lessThanHours.replace("{{hours}}", String(hours));
1203
+ };
1204
+ const priceImpact = currentChainFromBackend?.estimated_price_impact_percent ?? 0;
1205
+ const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
1206
+ const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
1207
+ const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
1208
+ const renderTokenItem = (tokenData) => {
1209
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1210
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1211
+ "img",
1212
+ {
1213
+ src: tokenData.icon_url,
1214
+ alt: tokenData.symbol,
1215
+ width: 20,
1216
+ height: 20,
1217
+ className: "uf-rounded-full uf-flex-shrink-0"
1218
+ }
1219
+ ),
1220
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-normal", children: tokenData.symbol }),
1221
+ showDetailedDropdowns && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-text-muted-foreground", children: tokenData.name })
1222
+ ] });
1223
+ };
1224
+ const renderChainItem = (chainData) => {
1225
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1226
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1227
+ "img",
1228
+ {
1229
+ src: chainData.icon_url,
1230
+ alt: chainData.chain_name,
1231
+ width: 20,
1232
+ height: 20,
1233
+ className: "uf-rounded-full uf-flex-shrink-0"
1234
+ }
1235
+ ),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-normal", children: chainData.chain_name }),
1237
+ showDetailedDropdowns && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-text-muted-foreground uf-capitalize", children: chainData.chain_type })
1238
+ ] });
1239
+ };
1240
+ const selectContainerClass = layoutVariant === "horizontal" ? "uf-grid uf-grid-cols-2 uf-gap-2.5" : "uf-space-y-3";
1241
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipProvider, { delayDuration: 0, skipDelayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-space-y-3", children: [
1242
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: selectContainerClass, children: [
1243
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
1244
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-gap-1", children: t.supportedToken }),
1245
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1246
+ Select,
1247
+ {
1248
+ value: token,
1249
+ onValueChange: setToken,
1250
+ disabled: tokensLoading || supportedTokens.length === 0,
1251
+ children: [
1252
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectTrigger, { className: "uf-bg-secondary uf-border-none uf-rounded-lg uf-h-10 hover:uf-bg-accent uf-text-foreground focus:uf-ring-1 focus:uf-ring-ring disabled:uf-opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectValue, { children: tokensLoading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t.loading }) }) : selectedToken ? renderTokenItem(selectedToken) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-normal", children: token }) }) }) }),
1253
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectContent, { className: "uf-bg-secondary uf-border uf-text-foreground uf-max-h-[300px]", children: supportedTokens.map((tokenData) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1254
+ SelectItem,
1255
+ {
1256
+ value: tokenData.symbol,
1257
+ className: "focus:uf-bg-accent focus:uf-text-foreground",
1258
+ children: renderTokenItem(tokenData)
1259
+ },
1260
+ tokenData.symbol
1261
+ )) })
1262
+ ]
1263
+ }
1264
+ )
1265
+ ] }),
1266
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
1267
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-gap-1", children: [
1268
+ t.supportedChain,
1269
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-[10px]", children: [
1270
+ "$",
1271
+ minDepositUsd,
1272
+ " ",
1273
+ t.minDeposit.label
1274
+ ] }),
1275
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
1276
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1277
+ "span",
1278
+ {
1279
+ className: "uf-inline-flex uf-cursor-pointer uf-transition-colors hover:uf-text-foreground",
1280
+ tabIndex: 0,
1281
+ role: "button",
1282
+ "aria-label": "Minimum deposit information",
1283
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Info, { className: "uf-w-3 uf-h-3" })
1284
+ }
1285
+ ) }),
1286
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1287
+ TooltipContent,
1288
+ {
1289
+ side: "left",
1290
+ align: "center",
1291
+ className: "uf-max-w-[200px]",
1292
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: t.minDeposit.tooltip })
1293
+ }
1294
+ )
1295
+ ] })
1296
+ ] }),
1297
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1298
+ Select,
1299
+ {
1300
+ value: chain,
1301
+ onValueChange: setChain,
1302
+ disabled: tokensLoading || availableChainsForToken.length === 0,
1303
+ children: [
1304
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectTrigger, { className: "uf-bg-secondary uf-border-none uf-rounded-lg uf-h-10 hover:uf-bg-accent uf-text-foreground focus:uf-ring-1 focus:uf-ring-ring disabled:uf-opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectValue, { children: tokensLoading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t.loading }) }) : currentChainFromBackend ? renderChainItem(currentChainFromBackend) : currentChainData ? renderChainItem(currentChainData) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-xs uf-font-normal", children: chain }) }) }) }),
1305
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectContent, { className: "uf-bg-secondary uf-border uf-text-foreground uf-max-h-[300px]", children: availableChainsForToken.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-px-2 uf-py-3 uf-text-xs uf-text-muted-foreground uf-text-center", children: t.noChainsAvailable }) : availableChainsForToken.map((chainData) => {
1306
+ const chainKey = getChainKey(
1307
+ chainData.chain_id,
1308
+ chainData.chain_type
1309
+ );
1310
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1311
+ SelectItem,
1312
+ {
1313
+ value: chainKey,
1314
+ className: "focus:uf-bg-accent focus:uf-text-foreground",
1315
+ children: renderChainItem(chainData)
1316
+ },
1317
+ `${chainData.chain_id}-${chainData.chain_type}`
1318
+ );
1319
+ }) })
1320
+ ]
1321
+ }
1322
+ )
1323
+ ] })
1324
+ ] }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-justify-center uf-py-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-card uf-p-4 uf-rounded-2xl uf-shadow-lg uf-border uf-border-border", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1326
+ "div",
1327
+ {
1328
+ className: "uf-flex uf-items-center uf-justify-center",
1329
+ style: { width: 180, height: 180 },
1330
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-text-foreground uf-text-sm", children: t.loadingQRCode })
1331
+ }
1332
+ ) : depositAddress ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1333
+ StyledQRCode,
1334
+ {
1335
+ value: depositAddress,
1336
+ size: 180,
1337
+ imageUrl: currentChainData?.icon_url || currentChainFromBackend?.icon_url || getIconUrl("/icons/networks/ethereum.svg"),
1338
+ imageSize: 45,
1339
+ darkMode: isDarkMode
1340
+ },
1341
+ `qr-${depositAddress}-${chain}`
1342
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1343
+ "div",
1344
+ {
1345
+ className: "uf-flex uf-items-center uf-justify-center",
1346
+ style: { width: 180, height: 180 },
1347
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-text-red-400 uf-text-sm", children: t.noAddressAvailable })
1348
+ }
1349
+ ) }) }),
1350
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
1351
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-justify-between", children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
1353
+ t.depositAddress.label,
1354
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
1355
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1356
+ "span",
1357
+ {
1358
+ className: "uf-inline-flex uf-cursor-pointer uf-transition-colors hover:uf-text-foreground",
1359
+ tabIndex: 0,
1360
+ role: "button",
1361
+ "aria-label": "Deposit address information",
1362
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Info, { className: "uf-w-3 uf-h-3" })
1363
+ }
1364
+ ) }),
1365
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1366
+ TooltipContent,
1367
+ {
1368
+ side: "top",
1369
+ align: "center",
1370
+ className: "uf-max-w-[240px]",
1371
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: t.depositAddress.tooltip.replace("{{token}}", token) })
1372
+ }
1373
+ )
1374
+ ] })
1375
+ ] }),
1376
+ copyButtonMode === "compact" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1377
+ "button",
1378
+ {
1379
+ onClick: handleCopyAddress,
1380
+ disabled: loading || !depositAddress,
1381
+ className: "uf-flex uf-items-center uf-gap-1 uf-text-xs uf-text-muted-foreground hover:uf-text-foreground uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
1382
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1383
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Check, { className: "uf-w-3 uf-h-3" }),
1384
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: t.copied })
1385
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1386
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Copy, { className: "uf-w-3 uf-h-3" }),
1387
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: t.copyAddress })
1388
+ ] })
1389
+ }
1390
+ )
1391
+ ] }),
1392
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-muted-foreground uf-animate-pulse", children: t.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-red-400", children: error }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-font-mono uf-break-all", children: depositAddress || t.noAddressAvailable })
1393
+ ] }),
1394
+ copyButtonMode === "fullWidth" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1395
+ Button,
1396
+ {
1397
+ onClick: handleCopyAddress,
1398
+ disabled: loading || !depositAddress,
1399
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-text-foreground uf-rounded-lg uf-h-9 uf-text-sm uf-font-medium disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
1400
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1401
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Check, { className: "uf-w-4 uf-h-4 uf-mr-2" }),
1402
+ t.copied
1403
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1404
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Copy, { className: "uf-w-4 uf-h-4 uf-mr-2" }),
1405
+ t.copyAddress
1406
+ ] })
1407
+ }
1408
+ ),
1409
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-border-t uf-border-border", children: [
1410
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1411
+ "button",
1412
+ {
1413
+ onClick: () => setDetailsExpanded(!detailsExpanded),
1414
+ className: "uf-w-full uf-flex uf-items-center uf-justify-between uf-py-2.5",
1415
+ children: [
1416
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1417
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-full uf-p-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.DollarSign, { className: "uf-w-3 uf-h-3" }) }),
1418
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-xs", children: [
1419
+ t.priceImpact.label,
1420
+ ":",
1421
+ " ",
1422
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-foreground", children: [
1423
+ priceImpact.toFixed(2),
1424
+ "%"
1425
+ ] })
1426
+ ] }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
1428
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1429
+ "span",
1430
+ {
1431
+ className: "uf-inline-flex uf-cursor-pointer uf-text-muted-foreground uf-transition-colors hover:uf-text-foreground",
1432
+ onClick: (e) => e.stopPropagation(),
1433
+ onKeyDown: (e) => {
1434
+ if (e.key === "Enter" || e.key === " ") {
1435
+ e.stopPropagation();
1436
+ }
1437
+ },
1438
+ tabIndex: 0,
1439
+ role: "button",
1440
+ "aria-label": "Price impact information",
1441
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Info, { className: "uf-w-3 uf-h-3" })
1442
+ }
1443
+ ) }),
1444
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1445
+ TooltipContent,
1446
+ {
1447
+ side: "top",
1448
+ align: "center",
1449
+ className: "uf-max-w-[240px]",
1450
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: t.priceImpact.tooltip })
1451
+ }
1452
+ )
1453
+ ] })
1454
+ ] }),
1455
+ detailsExpanded ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.ChevronUp, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.ChevronDown, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground" })
1456
+ ]
1457
+ }
1458
+ ),
1459
+ detailsExpanded && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-pb-3 uf-space-y-2.5", children: [
1460
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1461
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-full uf-p-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.ShieldCheck, { className: "uf-w-3 uf-h-3" }) }),
1462
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-xs", children: [
1463
+ t.slippage.label,
1464
+ ":",
1465
+ " ",
1466
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-foreground", children: [
1467
+ t.slippage.auto,
1468
+ " \u2022 ",
1469
+ maxSlippage.toFixed(2),
1470
+ "%"
1471
+ ] })
1472
+ ] }),
1473
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
1474
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1475
+ "span",
1476
+ {
1477
+ className: "uf-inline-flex uf-cursor-pointer uf-text-muted-foreground uf-transition-colors hover:uf-text-foreground",
1478
+ tabIndex: 0,
1479
+ role: "button",
1480
+ "aria-label": "Slippage information",
1481
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Info, { className: "uf-w-3 uf-h-3" })
1482
+ }
1483
+ ) }),
1484
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1485
+ TooltipContent,
1486
+ {
1487
+ side: "top",
1488
+ align: "center",
1489
+ className: "uf-max-w-[240px]",
1490
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: t.slippage.tooltip })
1491
+ }
1492
+ )
1493
+ ] })
1494
+ ] }),
1495
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-full uf-p-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Clock, { className: "uf-w-3 uf-h-3" }) }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-xs", children: [
1498
+ t.processingTime.label,
1499
+ ":",
1500
+ " ",
1501
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-foreground", children: formatProcessingTime(processingTime) })
1502
+ ] })
1503
+ ] }),
1504
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1505
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-bg-secondary uf-rounded-full uf-p-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.FileText, { className: "uf-w-3 uf-h-3" }) }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "uf-text-xs", children: [
1507
+ t.help.needHelp,
1508
+ " ",
1509
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1510
+ "a",
1511
+ {
1512
+ href: "#",
1513
+ className: "uf-text-foreground uf-underline hover:uf-text-muted-foreground uf-transition-colors",
1514
+ children: t.help.contactSupport
1515
+ }
1516
+ )
1517
+ ] })
1518
+ ] })
1519
+ ] }),
1520
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-pt-2", children: [
1521
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1522
+ "a",
1523
+ {
1524
+ href: "#",
1525
+ className: "uf-text-muted-foreground uf-underline hover:uf-text-foreground uf-transition-colors",
1526
+ children: t.terms.termsApply
1527
+ }
1528
+ ),
1529
+ depositExecutions.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1530
+ "button",
1531
+ {
1532
+ onClick: () => setDepositsModalOpen(true),
1533
+ className: "uf-flex uf-items-center uf-gap-1 uf-text-muted-foreground hover:uf-text-foreground uf-transition-colors uf-animate-in uf-fade-in uf-slide-in-from-right-8 uf-duration-1000",
1534
+ children: [
1535
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.Clock, { className: "uf-w-3.5 uf-h-3.5" }),
1536
+ "Track deposits (",
1537
+ depositExecutions.length,
1538
+ ")",
1539
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.ChevronRight, { className: "uf-w-3 uf-h-3" })
1540
+ ]
1541
+ }
1542
+ )
1543
+ ] })
1544
+ ] }),
1545
+ depositExecutions.length === 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-fixed uf-bottom-4 uf-left-1/2 uf--translate-x-1/2 uf-w-[360px] uf-max-w-[calc(100vw-2rem)] uf-z-[100]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1546
+ DepositSuccessToast,
1547
+ {
1548
+ depositTx: depositExecutions[0].transaction_hash,
1549
+ completionTx: depositExecutions[0].destination_transaction_hashes?.[0] || (depositExecutions[0].status === "succeeded" /* SUCCEEDED */ ? depositExecutions[0].transaction_hash : void 0),
1550
+ orderSubmittedAt: depositExecutions[0].created_at || (/* @__PURE__ */ new Date()).toISOString(),
1551
+ orderFilledAt: depositExecutions[0].updated_at || (/* @__PURE__ */ new Date()).toISOString(),
1552
+ explorerUrl: depositExecutions[0].explorer_url,
1553
+ completionExplorerUrl: depositExecutions[0].destination_transaction_hashes?.[0] ? `https://polygonscan.com/tx/${depositExecutions[0].destination_transaction_hashes[0]}` : depositExecutions[0].status === "succeeded" /* SUCCEEDED */ ? depositExecutions[0].explorer_url : void 0,
1554
+ status: depositExecutions[0].status,
1555
+ tokenIconUrl: depositExecutions[0].source_token_metadata?.icon_url,
1556
+ onClose: () => setDepositExecutions([])
1557
+ },
1558
+ depositExecutions[0].id
1559
+ ) }),
1560
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1561
+ DepositsModal,
1562
+ {
1563
+ open: depositsModalOpen,
1564
+ onOpenChange: setDepositsModalOpen,
1565
+ executions: depositExecutions,
1566
+ userId,
1567
+ publishableKey,
1568
+ themeClass
1569
+ }
1570
+ )
1571
+ ] }) });
1572
+ }
1573
+
1574
+ // src/components/deposits/TransferCrypto.tsx
1575
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1576
+ function TransferCrypto(props) {
1577
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1578
+ TransferCryptoBase,
1579
+ {
1580
+ ...props,
1581
+ layoutVariant: "horizontal",
1582
+ showDetailedDropdowns: false
1583
+ }
1584
+ );
1585
+ }
1586
+
1587
+ // src/components/deposits/BuyWithCard.tsx
1588
+ var import_react5 = require("react");
1589
+ var import_lucide_react8 = require("lucide-react");
1590
+
1591
+ // src/components/deposits/CurrencyModal.tsx
1592
+ var import_react4 = require("react");
1593
+ var import_lucide_react7 = require("lucide-react");
1594
+
1595
+ // src/components/currency/CurrencyListItem.tsx
1596
+ var import_lucide_react6 = require("lucide-react");
1597
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1598
+ function CurrencyListItem({
1599
+ currency,
1600
+ isSelected,
1601
+ onSelect
1602
+ }) {
1603
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1604
+ "button",
1605
+ {
1606
+ onClick: () => onSelect(currency.currency_code),
1607
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
1608
+ children: [
1609
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
1610
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "uf-w-10 uf-h-10 uf-flex uf-items-center uf-justify-center uf-flex-shrink-0 uf-rounded-full uf-overflow-hidden uf-bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1611
+ "img",
1612
+ {
1613
+ src: currency.icon_url,
1614
+ alt: currency.name,
1615
+ width: 40,
1616
+ height: 40,
1617
+ className: "uf-w-full uf-h-full uf-object-cover uf-rounded-full"
1618
+ }
1619
+ ) }),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "uf-text-left", children: [
1621
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "uf-text-sm uf-font-normal uf-text-foreground", children: currency.name }),
1622
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "uf-text-xs uf-text-muted-foreground uf-font-light", children: currency.currency_code.toUpperCase() })
1623
+ ] })
1624
+ ] }),
1625
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Check, { className: "uf-w-4 uf-h-4 uf-text-foreground" })
1626
+ ]
1627
+ }
1628
+ );
1629
+ }
1630
+
1631
+ // src/components/currency/CurrencyListSection.tsx
1632
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1633
+ function CurrencyListSection({
1634
+ title,
1635
+ currencies,
1636
+ selectedCurrency,
1637
+ onSelect
1638
+ }) {
1639
+ if (currencies.length === 0) return null;
1640
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1641
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-px-1 uf-pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: title }) }),
1642
+ currencies.map((currency) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1643
+ CurrencyListItem,
1644
+ {
1645
+ currency,
1646
+ isSelected: selectedCurrency.toLowerCase() === currency.currency_code.toLowerCase(),
1647
+ onSelect
1648
+ },
1649
+ currency.currency_code
1650
+ ))
1651
+ ] });
1652
+ }
1653
+
1654
+ // src/components/deposits/CurrencyModal.tsx
1655
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1656
+ function CurrencyModal({
1657
+ open,
1658
+ onOpenChange,
1659
+ currencies,
1660
+ preferredCurrencyCodes,
1661
+ selectedCurrency,
1662
+ onSelectCurrency,
1663
+ themeClass = ""
1664
+ }) {
1665
+ const [searchQuery, setSearchQuery] = (0, import_react4.useState)("");
1666
+ const preferredCurrencies = preferredCurrencyCodes.map(
1667
+ (code) => currencies.find(
1668
+ (currency) => currency.currency_code.toLowerCase() === code.toLowerCase()
1669
+ )
1670
+ ).filter((currency) => currency !== void 0);
1671
+ const otherCurrencies = currencies.filter(
1672
+ (currency) => !preferredCurrencyCodes.includes(currency.currency_code.toLowerCase())
1673
+ );
1674
+ const filterCurrencies = (currencyList) => {
1675
+ if (!searchQuery) return currencyList;
1676
+ const query = searchQuery.toLowerCase();
1677
+ return currencyList.filter(
1678
+ (currency) => currency.name.toLowerCase().includes(query) || currency.currency_code.toLowerCase().includes(query)
1679
+ );
1680
+ };
1681
+ const filteredPreferred = filterCurrencies(preferredCurrencies);
1682
+ const filteredOther = filterCurrencies(otherCurrencies);
1683
+ const handleSelect = (currencyCode) => {
1684
+ onSelectCurrency(currencyCode);
1685
+ onOpenChange(false);
1686
+ setSearchQuery("");
1687
+ };
1688
+ const handleClose = () => {
1689
+ onOpenChange(false);
1690
+ setSearchQuery("");
1691
+ };
1692
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(DialogContent, { className: `sm:uf-max-w-[400px] !uf-bg-card uf-border-secondary uf-text-foreground uf-p-0 uf-gap-0 [&>button]:uf-hidden ${themeClass}`, children: [
1693
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1694
+ DepositHeader,
1695
+ {
1696
+ title: "Currency",
1697
+ showBack: true,
1698
+ onBack: handleClose,
1699
+ onClose: handleClose
1700
+ }
1701
+ ),
1702
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "uf-relative", children: [
1703
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react7.Search, { className: "uf-absolute uf-left-4 uf-top-1/2 uf--translate-y-1/2 uf-w-4 uf-h-4 uf-text-muted-foreground" }),
1704
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1705
+ "input",
1706
+ {
1707
+ type: "text",
1708
+ value: searchQuery,
1709
+ onChange: (e) => setSearchQuery(e.target.value),
1710
+ placeholder: "Search",
1711
+ className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-pl-11 uf-pr-4 uf-py-2.5 uf-text-sm uf-text-foreground uf-placeholder-muted-foreground uf-outline-none focus:uf-ring-2 focus:uf-ring-ring/30"
1712
+ }
1713
+ )
1714
+ ] }) }),
1715
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "uf-max-h-[500px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "uf-space-y-2", children: [
1716
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1717
+ CurrencyListSection,
1718
+ {
1719
+ title: "Popular currencies",
1720
+ currencies: filteredPreferred,
1721
+ selectedCurrency,
1722
+ onSelect: handleSelect
1723
+ }
1724
+ ),
1725
+ filteredPreferred.length > 0 && filteredOther.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "uf-h-2" }),
1726
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1727
+ CurrencyListSection,
1728
+ {
1729
+ title: "All currencies",
1730
+ currencies: filteredOther,
1731
+ selectedCurrency,
1732
+ onSelect: handleSelect
1733
+ }
1734
+ ),
1735
+ filteredPreferred.length === 0 && filteredOther.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "uf-text-center uf-py-8 uf-text-muted-foreground uf-text-sm", children: "No currencies found" })
1736
+ ] }) })
1737
+ ] }) });
1738
+ }
1739
+
1740
+ // src/hooks/use-user-ip.ts
1741
+ var import_react_query = require("@tanstack/react-query");
1742
+ async function getIpViaMoonpay(moonpayApiKey) {
1743
+ const url = `https://api.moonpay.com/v3/ip_address?apiKey=${moonpayApiKey}`;
1744
+ const response = await fetch(url);
1745
+ if (!response.ok) {
1746
+ throw new Error(`Moonpay IP API failed: ${response.statusText}`);
1747
+ }
1748
+ const data = await response.json();
1749
+ return {
1750
+ alpha2: data.alpha2.toLowerCase(),
1751
+ state: data.state?.toLowerCase()
1752
+ };
1753
+ }
1754
+ async function getIpViaIpApi() {
1755
+ const url = "https://ipapi.co/json";
1756
+ const response = await fetch(url);
1757
+ if (!response.ok) {
1758
+ throw new Error(`ipapi.co failed: ${response.statusText}`);
1759
+ }
1760
+ const data = await response.json();
1761
+ return {
1762
+ alpha2: data.country_code.toLowerCase(),
1763
+ state: data.region_code?.toLowerCase()
1764
+ };
1765
+ }
1766
+ function useUserIp(moonpayApiKey) {
1767
+ const {
1768
+ data: userIpInfo,
1769
+ isLoading,
1770
+ error
1771
+ } = (0, import_react_query.useQuery)({
1772
+ queryKey: ["getUserIpInfo"],
1773
+ queryFn: async () => {
1774
+ if (moonpayApiKey) {
1775
+ try {
1776
+ const moonpayIpData = await getIpViaMoonpay(moonpayApiKey);
1777
+ console.log("IP detected via Moonpay:", moonpayIpData);
1778
+ return moonpayIpData;
1779
+ } catch (error2) {
1780
+ console.warn("Moonpay IP API failed, trying fallback:", error2);
1781
+ }
1782
+ }
1783
+ try {
1784
+ const ipApiData = await getIpViaIpApi();
1785
+ console.log("IP detected via ipapi.co:", ipApiData);
1786
+ return ipApiData;
1787
+ } catch (ipApiError) {
1788
+ console.error("All IP detection methods failed:", ipApiError);
1789
+ throw ipApiError;
1790
+ }
1791
+ },
1792
+ // Cache configuration to reduce API calls
1793
+ refetchOnMount: false,
1794
+ refetchOnReconnect: true,
1795
+ refetchOnWindowFocus: false,
1796
+ // Optional: Increase cache duration to 1 hour for even better rate limit protection
1797
+ staleTime: 1e3 * 60 * 60,
1798
+ // 1 hour - data considered fresh for 1 hour
1799
+ gcTime: 1e3 * 60 * 60 * 24
1800
+ // 24 hours - keep in cache for 24 hours
1801
+ });
1802
+ return {
1803
+ userIpInfo,
1804
+ isLoading,
1805
+ error
1806
+ };
1807
+ }
1808
+
1809
+ // src/components/deposits/BuyWithCard.tsx
1810
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1811
+ var t2 = i18n.buyWithCard;
1812
+ var QUICK_AMOUNTS = [100, 500, 1e3];
1813
+ function getCurrencySymbol(currencyCode) {
1814
+ try {
1815
+ return new Intl.NumberFormat("en", {
1816
+ style: "currency",
1817
+ currency: currencyCode.toUpperCase(),
1818
+ minimumFractionDigits: 0,
1819
+ maximumFractionDigits: 0
1820
+ }).format(0).replace(/\d/g, "").trim();
1821
+ } catch {
1822
+ return currencyCode.toUpperCase();
1823
+ }
1824
+ }
1825
+ function BuyWithCard({
1826
+ userId,
1827
+ publishableKey,
1828
+ view: externalView,
1829
+ onViewChange,
1830
+ maxAmountUsd = 5e4,
1831
+ accentColor = "#0052FF",
1832
+ destinationTokenSymbol,
1833
+ recipientAddress,
1834
+ destinationChainId,
1835
+ destinationTokenAddress,
1836
+ themeClass = ""
1837
+ }) {
1838
+ const [amount, setAmount] = (0, import_react5.useState)("500.00");
1839
+ const [currency, setCurrency] = (0, import_react5.useState)("usd");
1840
+ const [showCurrencyModal, setShowCurrencyModal] = (0, import_react5.useState)(false);
1841
+ const [quotes, setQuotes] = (0, import_react5.useState)([]);
1842
+ const [quotesLoading, setQuotesLoading] = (0, import_react5.useState)(false);
1843
+ const [quotesError, setQuotesError] = (0, import_react5.useState)(null);
1844
+ const [internalView, setInternalView] = (0, import_react5.useState)("amount");
1845
+ const { userIpInfo, isLoading: isLoadingIp } = useUserIp();
1846
+ const [onrampSession, setOnrampSession] = (0, import_react5.useState)(
1847
+ null
1848
+ );
1849
+ const currentView = externalView ?? internalView;
1850
+ const showQuotesView = currentView === "quotes";
1851
+ const showOnrampView = currentView === "onramp";
1852
+ (0, import_react5.useEffect)(() => {
1853
+ if (externalView) {
1854
+ setInternalView(externalView);
1855
+ }
1856
+ }, [externalView]);
1857
+ const handleViewChange = (newView) => {
1858
+ setInternalView(newView);
1859
+ if (newView === "quotes") {
1860
+ onViewChange?.(newView, quotes.length);
1861
+ } else {
1862
+ onViewChange?.(newView);
1863
+ }
1864
+ };
1865
+ const [selectedProvider, setSelectedProvider] = (0, import_react5.useState)(
1866
+ null
1867
+ );
1868
+ const [isAutoSelected, setIsAutoSelected] = (0, import_react5.useState)(true);
1869
+ const [autoSelectedProvider, setAutoSelectedProvider] = (0, import_react5.useState)(null);
1870
+ const [hasManualSelection, setHasManualSelection] = (0, import_react5.useState)(false);
1871
+ const [wallets, setWallets] = (0, import_react5.useState)([]);
1872
+ const [walletsLoading, setWalletsLoading] = (0, import_react5.useState)(true);
1873
+ const [countdown, setCountdown] = (0, import_react5.useState)(60);
1874
+ const [fiatCurrencies, setFiatCurrencies] = (0, import_react5.useState)([]);
1875
+ const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0, import_react5.useState)([]);
1876
+ const [currenciesLoading, setCurrenciesLoading] = (0, import_react5.useState)(true);
1877
+ const [supportedTokens, setSupportedTokens] = (0, import_react5.useState)([]);
1878
+ const destinationWallet = getWalletByChainType(wallets, "ethereum");
1879
+ const walletDestinationChainId = destinationWallet?.destination_chain_id;
1880
+ const resolvedDestinationChainId = destinationChainId || walletDestinationChainId;
1881
+ const displayTokenSymbol = destinationTokenSymbol || supportedTokens[0]?.symbol || "USDC";
1882
+ const destinationToken = supportedTokens[0];
1883
+ const destinationChain = destinationToken?.chains.find(
1884
+ (c) => c.chain_id === resolvedDestinationChainId
1885
+ );
1886
+ (0, import_react5.useEffect)(() => {
1887
+ async function fetchFiatCurrencies() {
1888
+ try {
1889
+ const response = await getFiatCurrencies(publishableKey);
1890
+ setFiatCurrencies(response.data);
1891
+ setPreferredCurrencyCodes(response.preferred || []);
1892
+ } catch (err) {
1893
+ console.error("Error fetching fiat currencies:", err);
1894
+ } finally {
1895
+ setCurrenciesLoading(false);
1896
+ }
1897
+ }
1898
+ fetchFiatCurrencies();
1899
+ }, [publishableKey]);
1900
+ (0, import_react5.useEffect)(() => {
1901
+ async function fetchWallets() {
1902
+ try {
1903
+ const response = await createEOA(
1904
+ {
1905
+ user_id: userId,
1906
+ recipient_address: recipientAddress,
1907
+ destination_chain_id: destinationChainId,
1908
+ destination_token_address: destinationTokenAddress
1909
+ },
1910
+ publishableKey
1911
+ );
1912
+ setWallets(response.data);
1913
+ } catch (err) {
1914
+ console.error("Error fetching wallets:", err);
1915
+ setQuotesError("Failed to load wallet addresses");
1916
+ } finally {
1917
+ setWalletsLoading(false);
1918
+ }
1919
+ }
1920
+ fetchWallets();
1921
+ }, [userId, recipientAddress, destinationChainId, destinationTokenAddress, publishableKey]);
1922
+ (0, import_react5.useEffect)(() => {
1923
+ async function fetchSupportedTokens() {
1924
+ try {
1925
+ const response = await getSupportedDepositTokens(publishableKey);
1926
+ setSupportedTokens(response.data);
1927
+ } catch (err) {
1928
+ console.error("Error fetching supported tokens:", err);
1929
+ }
1930
+ }
1931
+ fetchSupportedTokens();
1932
+ }, [publishableKey]);
1933
+ (0, import_react5.useEffect)(() => {
1934
+ const amountNum = parseFloat(amount);
1935
+ if (isNaN(amountNum) || amountNum <= 0) {
1936
+ setQuotes([]);
1937
+ return;
1938
+ }
1939
+ if (isLoadingIp || !userIpInfo) {
1940
+ return;
1941
+ }
1942
+ if (currency.toLowerCase() === "usd" && amountNum > maxAmountUsd) {
1943
+ setQuotes([]);
1944
+ setQuotesError(
1945
+ `Maximum amount is ${getCurrencySymbol("usd")}${maxAmountUsd.toLocaleString()}`
1946
+ );
1947
+ return;
1948
+ }
1949
+ const timer = setTimeout(() => {
1950
+ fetchQuotes(amountNum);
1951
+ }, 500);
1952
+ return () => clearTimeout(timer);
1953
+ }, [amount, currency, maxAmountUsd, userIpInfo, isLoadingIp, publishableKey]);
1954
+ const fetchQuotes = async (sourceAmount) => {
1955
+ if (!userIpInfo?.alpha2) {
1956
+ setQuotesError("Detecting your location...");
1957
+ return;
1958
+ }
1959
+ setQuotesLoading(true);
1960
+ setQuotesError(null);
1961
+ try {
1962
+ const request = {
1963
+ country_code: userIpInfo.alpha2.toUpperCase(),
1964
+ destination_currency_code: "usdc_polygon",
1965
+ source_amount: sourceAmount.toString(),
1966
+ source_currency_code: currency.toLowerCase()
1967
+ };
1968
+ const response = await getMeldQuotes(request, publishableKey);
1969
+ setQuotes(response.data);
1970
+ if (hasManualSelection && selectedProvider) {
1971
+ const manualProviderStillExists = response.data.find(
1972
+ (q) => q.service_provider === selectedProvider.service_provider
1973
+ );
1974
+ if (manualProviderStillExists) {
1975
+ setSelectedProvider(manualProviderStillExists);
1976
+ const bestProvider = response.data.reduce(
1977
+ (best, current) => current.destination_amount > best.destination_amount ? current : best
1978
+ );
1979
+ if (!autoSelectedProvider) {
1980
+ setAutoSelectedProvider(bestProvider.service_provider);
1981
+ }
1982
+ setIsAutoSelected(
1983
+ manualProviderStillExists.service_provider === autoSelectedProvider
1984
+ );
1985
+ } else {
1986
+ const bestProvider = response.data.reduce(
1987
+ (best, current) => current.destination_amount > best.destination_amount ? current : best
1988
+ );
1989
+ setSelectedProvider(bestProvider);
1990
+ setAutoSelectedProvider(bestProvider.service_provider);
1991
+ setIsAutoSelected(true);
1992
+ setHasManualSelection(false);
1993
+ }
1994
+ } else {
1995
+ if (response.data.length > 0) {
1996
+ const bestProvider = response.data.reduce(
1997
+ (best, current) => current.destination_amount > best.destination_amount ? current : best
1998
+ );
1999
+ setSelectedProvider(bestProvider);
2000
+ setAutoSelectedProvider(bestProvider.service_provider);
2001
+ setIsAutoSelected(true);
2002
+ }
2003
+ }
2004
+ setCountdown(60);
2005
+ } catch (error) {
2006
+ console.error("Failed to fetch quotes:", error);
2007
+ setQuotesError("Failed to fetch quotes");
2008
+ setQuotes([]);
2009
+ } finally {
2010
+ setQuotesLoading(false);
2011
+ }
2012
+ };
2013
+ (0, import_react5.useEffect)(() => {
2014
+ if (quotes.length === 0) return;
2015
+ const timer = setInterval(() => {
2016
+ setCountdown((prev) => {
2017
+ if (prev <= 1) {
2018
+ const amountNum = parseFloat(amount);
2019
+ if (!isNaN(amountNum) && amountNum > 0) {
2020
+ fetchQuotes(amountNum);
2021
+ }
2022
+ return 60;
2023
+ }
2024
+ return prev - 1;
2025
+ });
2026
+ }, 1e3);
2027
+ return () => clearInterval(timer);
2028
+ }, [quotes.length, amount]);
2029
+ const handleAmountChange = (value) => {
2030
+ const regex = /^\d*\.?\d{0,2}$/;
2031
+ if (regex.test(value) || value === "") {
2032
+ setAmount(value);
2033
+ }
2034
+ };
2035
+ const handleQuickAmount = (quickAmount) => {
2036
+ setAmount(quickAmount.toFixed(2));
2037
+ };
2038
+ const calculateUSDC = () => {
2039
+ if (!selectedProvider) return "0.000000";
2040
+ return selectedProvider.destination_amount.toFixed(6);
2041
+ };
2042
+ const selectedCurrencyData = fiatCurrencies.find(
2043
+ (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
2044
+ );
2045
+ const handleContinue = async () => {
2046
+ if (!selectedProvider) return;
2047
+ try {
2048
+ const wallet = getWalletByChainType(wallets, "ethereum");
2049
+ if (!wallet?.address) {
2050
+ setQuotesError("Wallet address not available");
2051
+ return;
2052
+ }
2053
+ const sessionRequest = {
2054
+ service_provider: selectedProvider.service_provider,
2055
+ country_code: selectedProvider.country_code.toUpperCase(),
2056
+ destination_currency_code: selectedProvider.destination_currency_code,
2057
+ source_currency_code: selectedProvider.source_currency_code,
2058
+ wallet_address: wallet.address,
2059
+ source_amount: amount
2060
+ };
2061
+ const session = await createMeldSession(sessionRequest, publishableKey);
2062
+ setOnrampSession({
2063
+ provider: selectedProvider,
2064
+ sourceCurrency: currency,
2065
+ sourceAmount: amount
2066
+ });
2067
+ window.open(session.widget_url, "_blank");
2068
+ handleViewChange("onramp");
2069
+ } catch (error) {
2070
+ console.error("Failed to create session:", error);
2071
+ setQuotesError("Failed to start payment flow");
2072
+ }
2073
+ };
2074
+ const getProviderBadges = (quote, allQuotes) => {
2075
+ const badges = [];
2076
+ const maxDestination = Math.max(
2077
+ ...allQuotes.map((q) => q.destination_amount)
2078
+ );
2079
+ if (quote.destination_amount === maxDestination) {
2080
+ badges.push("Best price");
2081
+ }
2082
+ return badges;
2083
+ };
2084
+ const sortedQuotes = [...quotes].sort(
2085
+ (a, b) => b.destination_amount - a.destination_amount
2086
+ );
2087
+ const currencySymbol = getCurrencySymbol(currency);
2088
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-pb-1 uf-relative uf-overflow-hidden", children: [
2089
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2090
+ "div",
2091
+ {
2092
+ className: `uf-transition-all uf-duration-300 ${showQuotesView || showOnrampView ? "uf-opacity-0 uf-pointer-events-none uf-absolute uf-inset-0" : "uf-opacity-100"}`,
2093
+ children: [
2094
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-mb-6 uf-pt-4", children: [
2095
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2096
+ "button",
2097
+ {
2098
+ onClick: () => setShowCurrencyModal(true),
2099
+ disabled: currenciesLoading,
2100
+ className: "uf-flex uf-items-center uf-gap-1.5 uf-px-3 uf-py-1.5 uf-rounded-lg uf-bg-secondary hover:uf-bg-accent uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
2101
+ children: [
2102
+ selectedCurrencyData && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-w-4 uf-h-4 uf-rounded-full uf-overflow-hidden uf-flex uf-items-center uf-justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2103
+ "img",
2104
+ {
2105
+ src: selectedCurrencyData.icon_url,
2106
+ alt: selectedCurrencyData.name,
2107
+ width: 16,
2108
+ height: 16,
2109
+ className: "uf-w-full uf-h-full uf-object-cover uf-rounded-full"
2110
+ }
2111
+ ) }),
2112
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-sm uf-text-foreground uf-font-medium", children: currency.toUpperCase() }),
2113
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.ChevronDown, { className: "uf-w-3.5 uf-h-3.5 uf-text-muted-foreground" })
2114
+ ]
2115
+ }
2116
+ ) }),
2117
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-center uf-mb-4", children: [
2118
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-mb-2 uf-px-8", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-max-w-full", children: [
2119
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2120
+ "span",
2121
+ {
2122
+ className: "uf-font-normal uf-text-foreground uf-flex-shrink-0 uf-mr-1",
2123
+ style: {
2124
+ fontSize: `${Math.max(3.75 - amount.length * 0.15, 2)}rem`
2125
+ },
2126
+ children: currencySymbol
2127
+ }
2128
+ ),
2129
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2130
+ "input",
2131
+ {
2132
+ type: "text",
2133
+ value: amount,
2134
+ onChange: (e) => handleAmountChange(e.target.value),
2135
+ className: "uf-font-normal uf-text-foreground uf-bg-transparent uf-text-left uf-outline-none uf-min-w-[1ch]",
2136
+ placeholder: "0",
2137
+ style: {
2138
+ caretColor: "currentColor",
2139
+ fontSize: `${Math.max(3.75 - amount.length * 0.15, 2)}rem`,
2140
+ width: `${Math.max(amount.length || 1, 1)}ch`
2141
+ }
2142
+ }
2143
+ )
2144
+ ] }) }),
2145
+ quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-h-4 uf-bg-muted uf-rounded uf-w-40 uf-animate-pulse" }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-sm uf-text-muted-foreground uf-font-normal", children: [
2146
+ calculateUSDC(),
2147
+ " USDC (Perps)"
2148
+ ] })
2149
+ ] }),
2150
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-gap-3 uf-justify-center", children: QUICK_AMOUNTS.map((quickAmount) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2151
+ "button",
2152
+ {
2153
+ onClick: () => handleQuickAmount(quickAmount),
2154
+ className: "uf-w-24 uf-py-2 uf-rounded-lg uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-text-sm uf-text-foreground uf-font-medium",
2155
+ children: [
2156
+ getCurrencySymbol(currency),
2157
+ quickAmount.toLocaleString()
2158
+ ]
2159
+ },
2160
+ quickAmount
2161
+ )) })
2162
+ ] }),
2163
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-mb-6", children: [
2164
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-font-medium uf-mb-2 uf-px-1", children: [
2165
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-foreground", children: "Provider" }),
2166
+ quotes.length > 0 && !quotesLoading && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "uf-text-[10px] uf-text-foreground uf-font-normal", children: [
2167
+ "Refreshing in ",
2168
+ countdown,
2169
+ "s"
2170
+ ] })
2171
+ ] }),
2172
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2173
+ "button",
2174
+ {
2175
+ onClick: () => handleViewChange("quotes"),
2176
+ disabled: quotesLoading || quotes.length === 0,
2177
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-4 uf-group disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
2178
+ children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
2179
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-h-3 uf-bg-muted uf-rounded uf-w-28 uf-mb-3" }),
2180
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
2181
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-w-8 uf-h-8 uf-bg-muted uf-rounded-full" }),
2182
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-h-4 uf-bg-muted uf-rounded uf-w-32" })
2183
+ ] })
2184
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
2185
+ isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-xs uf-text-muted-foreground uf-font-normal uf-mb-2", children: "Auto-picked for you" }),
2186
+ selectedProvider && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
2187
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2188
+ "img",
2189
+ {
2190
+ src: selectedProvider.icon_url,
2191
+ alt: selectedProvider.service_provider,
2192
+ width: 32,
2193
+ height: 32,
2194
+ className: "uf-rounded-full uf-flex-shrink-0"
2195
+ }
2196
+ ),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex-1 uf-min-w-0", children: [
2198
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-sm uf-text-foreground uf-font-medium", children: selectedProvider.service_provider_display_name }),
2199
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
2200
+ isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-green-400 uf-font-normal", children: "Best price" }),
2201
+ isAutoSelected && selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground", children: "\u2022" }),
2202
+ selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" })
2203
+ ] })
2204
+ ] }),
2205
+ quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.ChevronRight, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0" })
2206
+ ] })
2207
+ ] })
2208
+ }
2209
+ ),
2210
+ quotesError && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-xs uf-text-red-400 uf-mt-2 uf-px-1", children: quotesError })
2211
+ ] }),
2212
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2213
+ "button",
2214
+ {
2215
+ onClick: handleContinue,
2216
+ disabled: quotesLoading || walletsLoading || isLoadingIp || !selectedProvider || parseFloat(amount) <= 0 || currency.toLowerCase() === "usd" && parseFloat(amount) > maxAmountUsd,
2217
+ style: {
2218
+ backgroundColor: accentColor
2219
+ },
2220
+ className: "uf-w-full disabled:uf-cursor-not-allowed disabled:!uf-bg-muted uf-text-white uf-rounded-xl uf-py-4 uf-font-medium uf-text-base uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-50 disabled:uf-text-muted-foreground",
2221
+ children: isLoadingIp ? "Detecting location..." : walletsLoading ? "Loading..." : "Continue"
2222
+ }
2223
+ )
2224
+ ]
2225
+ }
2226
+ ),
2227
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2228
+ "div",
2229
+ {
2230
+ className: `uf-transition-all uf-duration-300 ${showQuotesView && !showOnrampView ? "uf-opacity-100" : "uf-opacity-0 uf-pointer-events-none uf-absolute uf-inset-0"}`,
2231
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-space-y-2 uf-pt-2", children: sortedQuotes.map((quote, index) => {
2232
+ const badges = getProviderBadges(quote, sortedQuotes);
2233
+ const displayName = quote.service_provider_display_name;
2234
+ const isSelected = selectedProvider?.service_provider === quote.service_provider;
2235
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2236
+ "button",
2237
+ {
2238
+ onClick: () => {
2239
+ setSelectedProvider(quote);
2240
+ setHasManualSelection(true);
2241
+ setIsAutoSelected(
2242
+ quote.service_provider === autoSelectedProvider
2243
+ );
2244
+ handleViewChange("amount");
2245
+ },
2246
+ className: `uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-group ${isSelected ? "uf-ring-2 uf-ring-inset uf-ring-primary" : ""}`,
2247
+ children: [
2248
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
2249
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-w-10 uf-h-10 uf-flex uf-items-center uf-justify-center uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2250
+ "img",
2251
+ {
2252
+ src: quote.icon_url,
2253
+ alt: displayName,
2254
+ width: 40,
2255
+ height: 40,
2256
+ className: "uf-rounded-full"
2257
+ }
2258
+ ) }),
2259
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-left", children: [
2260
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: displayName }),
2261
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
2262
+ badges.map((badge, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2263
+ "span",
2264
+ {
2265
+ className: "uf-text-[10px] uf-text-green-400 uf-font-normal",
2266
+ children: [
2267
+ badge,
2268
+ i < badges.length - 1 && ","
2269
+ ]
2270
+ },
2271
+ i
2272
+ )),
2273
+ quote.low_kyc === false && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground", children: "\u2022" }),
2274
+ quote.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" })
2275
+ ] })
2276
+ ] })
2277
+ ] }),
2278
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-right", children: [
2279
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: [
2280
+ quote.destination_amount.toFixed(2),
2281
+ " USDC"
2282
+ ] }),
2283
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-text-xs uf-text-muted-foreground uf-font-normal", children: [
2284
+ currencySymbol,
2285
+ " ",
2286
+ amount
2287
+ ] })
2288
+ ] })
2289
+ ]
2290
+ },
2291
+ index
2292
+ );
2293
+ }) })
2294
+ }
2295
+ ),
2296
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2297
+ "div",
2298
+ {
2299
+ className: `uf-transition-all uf-duration-300 ${showOnrampView ? "uf-opacity-100" : "uf-opacity-0 uf-pointer-events-none uf-absolute uf-inset-0"}`,
2300
+ children: onrampSession && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-6 uf-pb-4 uf-px-2", children: [
2301
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2302
+ "img",
2303
+ {
2304
+ src: onrampSession.provider.icon_url,
2305
+ alt: onrampSession.provider.service_provider_display_name,
2306
+ width: 64,
2307
+ height: 64,
2308
+ className: "uf-rounded-2xl"
2309
+ }
2310
+ ) }),
2311
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { className: "uf-text-xl uf-font-medium uf-text-foreground uf-mb-2", children: t2.onramp.completeTransaction.replace(
2312
+ "{{provider}}",
2313
+ onrampSession.provider.service_provider_display_name
2314
+ ) }),
2315
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-mb-8", children: t2.onramp.canCloseModal }),
2316
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-4 uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
2317
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex-1 uf-flex uf-flex-col uf-items-center", children: [
2318
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2319
+ "img",
2320
+ {
2321
+ src: getIconUrl(
2322
+ `/icons/currencies/${onrampSession.sourceCurrency.toLowerCase()}.svg`
2323
+ ),
2324
+ alt: onrampSession.sourceCurrency.toUpperCase(),
2325
+ width: 28,
2326
+ height: 28,
2327
+ className: "uf-rounded-full"
2328
+ }
2329
+ ) }),
2330
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground", children: t2.onramp.youUse }),
2331
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: onrampSession.sourceCurrency.toUpperCase() })
2332
+ ] }),
2333
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-muted-foreground uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.ChevronRight, { className: "uf-w-5 uf-h-5" }) }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex-1 uf-flex uf-flex-col uf-items-center", children: [
2335
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-relative", children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2337
+ "img",
2338
+ {
2339
+ src: getIconUrl("/icons/tokens/usdc.svg"),
2340
+ alt: "USDC",
2341
+ width: 28,
2342
+ height: 28,
2343
+ className: "uf-rounded-full"
2344
+ }
2345
+ ),
2346
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2347
+ "img",
2348
+ {
2349
+ src: getIconUrl("/icons/networks/polygon.svg"),
2350
+ alt: "Polygon",
2351
+ width: 14,
2352
+ height: 14,
2353
+ className: "uf-absolute uf--bottom-0.5 uf--right-0.5 uf-rounded-full"
2354
+ }
2355
+ )
2356
+ ] }) }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground", children: t2.onramp.youBuy }),
2358
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: "USDC" })
2359
+ ] }),
2360
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-text-muted-foreground uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react8.ChevronRight, { className: "uf-w-5 uf-h-5" }) }),
2361
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-flex-1 uf-flex uf-flex-col uf-items-center", children: [
2362
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "uf-relative", children: [
2363
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2364
+ "img",
2365
+ {
2366
+ src: destinationToken?.icon_url || getIconUrl("/icons/tokens/usdc.svg"),
2367
+ alt: displayTokenSymbol,
2368
+ width: 28,
2369
+ height: 28,
2370
+ className: "uf-rounded-full"
2371
+ }
2372
+ ),
2373
+ destinationChain?.icon_url && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2374
+ "img",
2375
+ {
2376
+ src: destinationChain.icon_url,
2377
+ alt: destinationChain.chain_name,
2378
+ width: 14,
2379
+ height: 14,
2380
+ className: "uf-absolute uf--bottom-0.5 uf--right-0.5 uf-rounded-full"
2381
+ }
2382
+ )
2383
+ ] }) }),
2384
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground", children: t2.onramp.youReceive }),
2385
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: displayTokenSymbol })
2386
+ ] })
2387
+ ] }) }),
2388
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "uf-text-xs uf-text-muted-foreground uf-leading-relaxed", children: t2.onramp.intentAddressNote }) })
2389
+ ] })
2390
+ }
2391
+ ),
2392
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2393
+ CurrencyModal,
2394
+ {
2395
+ open: showCurrencyModal,
2396
+ onOpenChange: setShowCurrencyModal,
2397
+ currencies: fiatCurrencies,
2398
+ preferredCurrencyCodes,
2399
+ selectedCurrency: currency,
2400
+ onSelectCurrency: (currencyCode) => {
2401
+ setCurrency(currencyCode.toLowerCase());
2402
+ },
2403
+ themeClass
2404
+ }
2405
+ )
2406
+ ] });
2407
+ }
2408
+
2409
+ // src/components/deposits/buttons/TransferCryptoButton.tsx
2410
+ var import_lucide_react9 = require("lucide-react");
2411
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2412
+ function TransferCryptoButton({
2413
+ onClick,
2414
+ title,
2415
+ subtitle
2416
+ }) {
2417
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2418
+ "button",
2419
+ {
2420
+ onClick,
2421
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
2422
+ children: [
2423
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
2424
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react9.Zap, { className: "uf-w-5 uf-h-5" }) }),
2425
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "uf-text-left", children: [
2426
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "uf-text-sm uf-font-normal uf-mb-0.5 uf-text-foreground", children: title }),
2427
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "uf-text-muted-foreground uf-text-xs uf-font-light", children: subtitle })
2428
+ ] })
2429
+ ] }),
2430
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
2431
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "uf-flex uf--space-x-1", children: [
2432
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2433
+ "img",
2434
+ {
2435
+ src: getIconUrl("/icons/networks/ethereum.svg"),
2436
+ alt: "ETH",
2437
+ width: 20,
2438
+ height: 20,
2439
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2440
+ }
2441
+ ),
2442
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2443
+ "img",
2444
+ {
2445
+ src: getIconUrl("/icons/networks/optimism.svg"),
2446
+ alt: "OP",
2447
+ width: 20,
2448
+ height: 20,
2449
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2450
+ }
2451
+ ),
2452
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2453
+ "img",
2454
+ {
2455
+ src: getIconUrl("/icons/networks/polygon.svg"),
2456
+ alt: "MATIC",
2457
+ width: 20,
2458
+ height: 20,
2459
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2460
+ }
2461
+ ),
2462
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2463
+ "img",
2464
+ {
2465
+ src: getIconUrl("/icons/networks/arbitrum.svg"),
2466
+ alt: "ARB",
2467
+ width: 20,
2468
+ height: 20,
2469
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2470
+ }
2471
+ ),
2472
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2473
+ "img",
2474
+ {
2475
+ src: getIconUrl("/icons/tokens/usdc.svg"),
2476
+ alt: "USDC",
2477
+ width: 20,
2478
+ height: 20,
2479
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2480
+ }
2481
+ ),
2482
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2483
+ "img",
2484
+ {
2485
+ src: getIconUrl("/icons/networks/solana.svg"),
2486
+ alt: "SOL",
2487
+ width: 20,
2488
+ height: 20,
2489
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2490
+ }
2491
+ ),
2492
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2493
+ "img",
2494
+ {
2495
+ src: getIconUrl("/icons/tokens/avax.svg"),
2496
+ alt: "AVAX",
2497
+ width: 20,
2498
+ height: 20,
2499
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2500
+ }
2501
+ ),
2502
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2503
+ "img",
2504
+ {
2505
+ src: getIconUrl("/icons/networks/bitcoin.svg"),
2506
+ alt: "BTC",
2507
+ width: 20,
2508
+ height: 20,
2509
+ className: "uf-rounded-full uf-border-2 uf-border-secondary"
2510
+ }
2511
+ )
2512
+ ] }),
2513
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react9.ChevronRight, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground group-hover:uf-text-foreground uf-transition-colors" })
2514
+ ] })
2515
+ ]
2516
+ }
2517
+ );
2518
+ }
2519
+
2520
+ // src/components/deposits/buttons/DepositWithCardButton.tsx
2521
+ var import_lucide_react10 = require("lucide-react");
2522
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2523
+ function DepositWithCardButton({
2524
+ onClick,
2525
+ title,
2526
+ subtitle
2527
+ }) {
2528
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2529
+ "button",
2530
+ {
2531
+ onClick,
2532
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
2533
+ children: [
2534
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
2535
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react10.CreditCard, { className: "uf-w-5 uf-h-5" }) }),
2536
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "uf-text-left", children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-text-sm uf-font-normal uf-mb-0.5 uf-text-foreground", children: title }),
2538
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-text-muted-foreground uf-text-xs uf-font-light", children: subtitle })
2539
+ ] })
2540
+ ] }),
2541
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
2542
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5", children: [
2543
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2544
+ "img",
2545
+ {
2546
+ src: getIconUrl("/icons/networks/mastercard.svg"),
2547
+ alt: "Mastercard",
2548
+ width: 32,
2549
+ height: 32,
2550
+ className: "uf-rounded"
2551
+ }
2552
+ ),
2553
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2554
+ "img",
2555
+ {
2556
+ src: getIconUrl("/icons/networks/visa.svg"),
2557
+ alt: "Visa",
2558
+ width: 32,
2559
+ height: 32,
2560
+ className: "uf-rounded"
2561
+ }
2562
+ )
2563
+ ] }),
2564
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react10.ChevronRight, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground group-hover:uf-text-foreground uf-transition-colors" })
2565
+ ] })
2566
+ ]
2567
+ }
2568
+ );
2569
+ }
2570
+
2571
+ // src/components/deposits/buttons/DepositTrackerButton.tsx
2572
+ var import_lucide_react11 = require("lucide-react");
2573
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2574
+ function DepositTrackerButton({
2575
+ onClick,
2576
+ title,
2577
+ subtitle,
2578
+ badge
2579
+ }) {
2580
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2581
+ "button",
2582
+ {
2583
+ onClick,
2584
+ className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-transition-colors uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
2585
+ children: [
2586
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
2587
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-bg-muted uf-rounded-lg uf-p-2 uf-relative", children: [
2588
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react11.Clock, { className: "uf-w-5 uf-h-5" }),
2589
+ badge !== void 0 && badge > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-absolute -uf-top-1 -uf-right-1 uf-bg-blue-500 uf-text-primary-foreground uf-text-[10px] uf-font-semibold uf-rounded-full uf-min-w-[18px] uf-h-[18px] uf-flex uf-items-center uf-justify-center uf-px-1", children: badge > 99 ? "99+" : badge })
2590
+ ] }),
2591
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-text-left", children: [
2592
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-text-sm uf-font-normal uf-mb-0.5 uf-text-foreground", children: title }),
2593
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-text-muted-foreground uf-text-xs uf-font-light", children: subtitle })
2594
+ ] })
2595
+ ] }),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react11.ChevronRight, { className: "uf-w-4 uf-h-4 uf-text-muted-foreground group-hover:uf-text-foreground uf-transition-colors" })
2597
+ ]
2598
+ }
2599
+ );
2600
+ }
2601
+
2602
+ // src/components/deposits/DepositModal.tsx
2603
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2604
+ var t3 = i18n.depositModal;
2605
+ function DepositModal({
2606
+ open,
2607
+ onOpenChange,
2608
+ userId,
2609
+ publishableKey,
2610
+ modalTitle,
2611
+ destinationTokenSymbol,
2612
+ recipientAddress,
2613
+ destinationChainId,
2614
+ destinationTokenAddress,
2615
+ hideDepositTracker = false,
2616
+ onDepositSuccess,
2617
+ onDepositError,
2618
+ theme = "dark"
2619
+ }) {
2620
+ const [view, setView] = (0, import_react6.useState)("main");
2621
+ const [cardView, setCardView] = (0, import_react6.useState)(
2622
+ "amount"
2623
+ );
2624
+ const [quotesCount, setQuotesCount] = (0, import_react6.useState)(0);
2625
+ const [depositsModalOpen, setDepositsModalOpen] = (0, import_react6.useState)(false);
2626
+ const [depositExecutions, setDepositExecutions] = (0, import_react6.useState)([]);
2627
+ const [resolvedTheme, setResolvedTheme] = (0, import_react6.useState)(theme === "auto" ? "dark" : theme);
2628
+ (0, import_react6.useEffect)(() => {
2629
+ if (theme === "auto") {
2630
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
2631
+ setResolvedTheme(mediaQuery.matches ? "dark" : "light");
2632
+ const handler = (e) => {
2633
+ setResolvedTheme(e.matches ? "dark" : "light");
2634
+ };
2635
+ mediaQuery.addEventListener("change", handler);
2636
+ return () => mediaQuery.removeEventListener("change", handler);
2637
+ } else {
2638
+ setResolvedTheme(theme);
2639
+ }
2640
+ }, [theme]);
2641
+ const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
2642
+ const handleClose = () => {
2643
+ onOpenChange(false);
2644
+ setTimeout(() => {
2645
+ setView("main");
2646
+ setCardView("amount");
2647
+ }, 200);
2648
+ };
2649
+ const handleBack = () => {
2650
+ if (view === "card" && cardView === "quotes") {
2651
+ setCardView("amount");
2652
+ } else if (view === "card" && cardView === "onramp") {
2653
+ setCardView("amount");
2654
+ } else {
2655
+ setView("main");
2656
+ setCardView("amount");
2657
+ }
2658
+ };
2659
+ const handleCardViewChange = (newView, count) => {
2660
+ setCardView(newView);
2661
+ if (count !== void 0) {
2662
+ setQuotesCount(count);
2663
+ }
2664
+ };
2665
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThemeProvider, { themeClass, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Dialog, { open, onOpenChange: handleClose, children: [
2666
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2667
+ DialogContent,
2668
+ {
2669
+ className: `sm:uf-max-w-[400px] !uf-bg-card uf-border-secondary uf-text-foreground uf-p-0 uf-gap-0 uf-overflow-visible [&>button]:uf-hidden ${themeClass}`,
2670
+ onPointerDownOutside: (e) => e.preventDefault(),
2671
+ onInteractOutside: (e) => e.preventDefault(),
2672
+ children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2673
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2674
+ DepositHeader,
2675
+ {
2676
+ title: modalTitle || "Deposit",
2677
+ onClose: handleClose
2678
+ }
2679
+ ),
2680
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-pb-4 uf-space-y-3", children: [
2681
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2682
+ TransferCryptoButton,
2683
+ {
2684
+ onClick: () => setView("transfer"),
2685
+ title: t3.transferCrypto.title,
2686
+ subtitle: t3.transferCrypto.subtitle
2687
+ }
2688
+ ),
2689
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2690
+ DepositWithCardButton,
2691
+ {
2692
+ onClick: () => setView("card"),
2693
+ title: t3.depositWithCard.title,
2694
+ subtitle: t3.depositWithCard.subtitle
2695
+ }
2696
+ ),
2697
+ !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2698
+ DepositTrackerButton,
2699
+ {
2700
+ onClick: () => setDepositsModalOpen(true),
2701
+ title: "Deposit Tracker",
2702
+ subtitle: "Track your deposit progress",
2703
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
2704
+ }
2705
+ )
2706
+ ] })
2707
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2708
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2709
+ DepositHeader,
2710
+ {
2711
+ title: t3.transferCrypto.title,
2712
+ showBack: true,
2713
+ onBack: handleBack,
2714
+ onClose: handleClose
2715
+ }
2716
+ ),
2717
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2718
+ TransferCrypto,
2719
+ {
2720
+ userId,
2721
+ publishableKey,
2722
+ recipientAddress,
2723
+ destinationChainId,
2724
+ destinationTokenAddress,
2725
+ onExecutionsChange: setDepositExecutions,
2726
+ onDepositSuccess,
2727
+ onDepositError
2728
+ }
2729
+ )
2730
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2731
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2732
+ DepositHeader,
2733
+ {
2734
+ title: cardView === "quotes" ? t3.quotes : modalTitle || "Deposit",
2735
+ showBack: true,
2736
+ onBack: handleBack,
2737
+ onClose: handleClose,
2738
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0
2739
+ }
2740
+ ),
2741
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2742
+ BuyWithCard,
2743
+ {
2744
+ userId,
2745
+ publishableKey,
2746
+ view: cardView,
2747
+ onViewChange: handleCardViewChange,
2748
+ destinationTokenSymbol,
2749
+ recipientAddress,
2750
+ destinationChainId,
2751
+ destinationTokenAddress,
2752
+ onDepositSuccess,
2753
+ onDepositError,
2754
+ themeClass
2755
+ }
2756
+ )
2757
+ ] })
2758
+ }
2759
+ ),
2760
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2761
+ DepositsModal,
2762
+ {
2763
+ open: depositsModalOpen,
2764
+ onOpenChange: setDepositsModalOpen,
2765
+ executions: depositExecutions,
2766
+ userId,
2767
+ publishableKey,
2768
+ themeClass
2769
+ }
2770
+ )
2771
+ ] }) });
2772
+ }
2773
+
2774
+ // src/components/deposits/TransferCrypto2.tsx
2775
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2776
+ function TransferCrypto2(props) {
2777
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2778
+ TransferCryptoBase,
2779
+ {
2780
+ ...props,
2781
+ layoutVariant: "vertical",
2782
+ showDetailedDropdowns: true
2783
+ }
2784
+ );
2785
+ }
2786
+ // Annotate the CommonJS export names for ESM import in node:
2787
+ 0 && (module.exports = {
2788
+ Button,
2789
+ BuyWithCard,
2790
+ CurrencyListItem,
2791
+ CurrencyListSection,
2792
+ CurrencyModal,
2793
+ DepositExecutionItem,
2794
+ DepositHeader,
2795
+ DepositModal,
2796
+ DepositSuccessToast,
2797
+ DepositTrackerButton,
2798
+ DepositWithCardButton,
2799
+ DepositsModal,
2800
+ Dialog,
2801
+ DialogClose,
2802
+ DialogContent,
2803
+ DialogDescription,
2804
+ DialogFooter,
2805
+ DialogHeader,
2806
+ DialogOverlay,
2807
+ DialogPortal,
2808
+ DialogTitle,
2809
+ DialogTrigger,
2810
+ ExecutionStatus,
2811
+ SOLANA_USDC_ADDRESS,
2812
+ Select,
2813
+ SelectContent,
2814
+ SelectGroup,
2815
+ SelectItem,
2816
+ SelectLabel,
2817
+ SelectScrollDownButton,
2818
+ SelectScrollUpButton,
2819
+ SelectSeparator,
2820
+ SelectTrigger,
2821
+ SelectValue,
2822
+ StyledQRCode,
2823
+ ThemeProvider,
2824
+ Tooltip,
2825
+ TooltipContent,
2826
+ TooltipProvider,
2827
+ TooltipTrigger,
2828
+ TransferCrypto,
2829
+ TransferCrypto2,
2830
+ TransferCryptoBase,
2831
+ TransferCryptoButton,
2832
+ buttonVariants,
2833
+ cn,
2834
+ createEOA,
2835
+ createMeldSession,
2836
+ getApiBaseUrl,
2837
+ getFiatCurrencies,
2838
+ getIconUrl,
2839
+ getMeldQuotes,
2840
+ getSupportedDepositTokens,
2841
+ getWalletByChainType,
2842
+ i18n,
2843
+ queryExecutions,
2844
+ setApiConfig,
2845
+ useTheme,
2846
+ useUserIp
2847
+ });