@oasisprotocol/privana-sdk 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  "use client";
2
- import { usePrivanaContext, createHostedAuthPendingStorageKey, clearHostedAuthPendingTransaction, HostedAuthRequiredError, HostedAuthError, createPkceVerifier, createPkceChallenge, createHostedAuthState, persistHostedAuthPendingTransaction, parseHostedAuthCallback, readHostedAuthPendingTransaction, HostedAuthStateMismatchError, buildHostedAuthSession, useSafePrivanaContext, usePrivateReadRequest, formatTokenAmount, submitPendingLock, PostDepositLockError, useDepositVerification, useEnsureCorrectChain, getTransactionReceipt, getBlockNumber, waitForTransactionReceipt, canUseBrowserStorage, clampLockAmount, requireDepositLockOwner, getWalletClient, createSignedLockRequest, requireServiceAddress, signWithdrawMessage, signLockMessage, signTransferMessage, signTransferLockedMessage, signModifyLockMessage, cn, stripHostedAuthCallbackParams, AccountingApiError, getBrowserStorageItem, removeBrowserStorageItem, isSignedLockUsable, setBrowserStorageItem, canUseSharedBrowserStorage, DEFAULT_LOCK_DURATION_SECONDS, parseTokenAmount, Skeleton, shortenAddress, formatCountdown, FiatOnRampForm, getExplorerAddressUrl, getExplorerLabel, formatTimeRemaining, getSharedBrowserStorageItem, removeSharedBrowserStorageItem, setSharedBrowserStorageItem } from './chunk-4VOTSHNC.js';
3
- export { AccountingApiError, Button, DEFAULT_LOCK_DURATION_SECONDS, DEFAULT_ONRAMP_LOCK_BUFFER, HOSTED_AUTH_CLOCK_SKEW_MS, HostedAuthError, HostedAuthRequiredError, HostedAuthStateMismatchError, HttpClient, LOCK_TYPES, MODIFY_LOCK_TYPES, NETWORK_CONFIG, NetworkError, PostDepositLockError, PrivanaClient, PrivanaProvider, SUPPORTED_CHAINS, SiweAuthProvider, Skeleton, TRANSFER_LOCKED_TYPES, TRANSFER_TYPES, ValidationError, WITHDRAW_FROM_LOCK_TYPES, WITHDRAW_TYPES, applyLockBuffer, applyRefreshResponse, buildHostedAuthSession, buildSiweStatement, buttonVariants, clampLockAmount, clearHostedAuthPendingTransaction, clearPendingLock, createDomain, createHostedAuthPendingStorageKey, createHostedAuthState, createHostedAuthStorageKey, createLockExpiry, createPkceChallenge, createPkceVerifier, createSignedLockRequest, getAccountingContract, getApiUrl, getChainById, getChainId, getExplorerAddressUrl, getExplorerLabel, isHostedAuthRefreshActive, isHostedAuthSessionActive, isSignedLockUsable, loadPendingLock, normalizeAddress, normalizeHex, parseHostedAuthCallback, persistHostedAuthPendingTransaction, readHostedAuthPendingTransaction, readStoredHostedAuthSession, requireDepositLockOwner, requireServiceAddress, savePendingLock, signLockMessage, signModifyLockMessage, signTransferLockedMessage, signTransferMessage, signWithdrawFromLockMessage, signWithdrawMessage, stripHostedAuthCallbackParams, submitPendingLock, syncHostedAuthSessionToClient, useDepositVerification, usePrivanaContext, useSafeAccount, useSafePrivanaContext, useSiweAuth } from './chunk-4VOTSHNC.js';
2
+ import { usePrivanaContext, createHostedAuthPendingStorageKey, clearHostedAuthPendingTransaction, HostedAuthRequiredError, HostedAuthError, createPkceVerifier, createPkceChallenge, createHostedAuthState, persistHostedAuthPendingTransaction, parseHostedAuthCallback, readHostedAuthPendingTransaction, HostedAuthStateMismatchError, buildHostedAuthSession, useSafePrivanaContext, usePrivateReadRequest, formatTokenAmount, submitPendingLock, PostDepositLockError, useDepositVerification, useEnsureCorrectChain, getTransactionReceipt, getBlockNumber, waitForTransactionReceipt, canUseBrowserStorage, clampLockAmount, requireDepositLockOwner, getWalletClient, createSignedLockRequest, requireServiceAddress, signWithdrawMessage, signLockMessage, signTransferMessage, signTransferLockedMessage, signModifyLockMessage, cn, stripHostedAuthCallbackParams, AccountingApiError, getBrowserStorageItem, removeBrowserStorageItem, isSignedLockUsable, setBrowserStorageItem, resolveProductOnRamp, matchesProductOnRampScope, createProductOnRampOutcomeCallbacks, canUseSharedBrowserStorage, DEFAULT_LOCK_DURATION_SECONDS, isMoonPayProductOnRamp, parseTokenAmount, createProductOnRampFlowSnapshot, Skeleton, shortenAddress, formatCountdown, getExplorerAddressUrl, getExplorerLabel, formatTimeRemaining, getSharedBrowserStorageItem, removeSharedBrowserStorageItem, setSharedBrowserStorageItem, matchesOnRampTransaction, useTransakOnRamp, getTransakMinimumTargetBaseUnits, matchesFrozenOnRampToken, Button, canRetryOnRampVerification, FiatOnRampForm } from './chunk-ONXJGUOH.js';
3
+ export { AccountingApiError, Button, DEFAULT_LOCK_DURATION_SECONDS, DEFAULT_ONRAMP_LOCK_BUFFER, HOSTED_AUTH_CLOCK_SKEW_MS, HostedAuthError, HostedAuthRequiredError, HostedAuthStateMismatchError, HttpClient, LOCK_TYPES, MODIFY_LOCK_TYPES, NETWORK_CONFIG, NetworkError, PostDepositLockError, PrivanaClient, PrivanaProvider, SUPPORTED_CHAINS, SiweAuthProvider, Skeleton, TRANSFER_LOCKED_TYPES, TRANSFER_TYPES, ValidationError, WITHDRAW_FROM_LOCK_TYPES, WITHDRAW_TYPES, applyLockBuffer, applyRefreshResponse, buildHostedAuthSession, buildSiweStatement, buttonVariants, clampLockAmount, clearHostedAuthPendingTransaction, clearPendingLock, createDomain, createHostedAuthPendingStorageKey, createHostedAuthState, createHostedAuthStorageKey, createLockExpiry, createPkceChallenge, createPkceVerifier, createSignedLockRequest, getAccountingContract, getApiUrl, getChainById, getChainId, getExplorerAddressUrl, getExplorerLabel, isHostedAuthRefreshActive, isHostedAuthSessionActive, isSignedLockUsable, loadPendingLock, normalizeAddress, normalizeHex, parseHostedAuthCallback, persistHostedAuthPendingTransaction, readHostedAuthPendingTransaction, readStoredHostedAuthSession, requireDepositLockOwner, requireServiceAddress, savePendingLock, signLockMessage, signModifyLockMessage, signTransferLockedMessage, signTransferMessage, signWithdrawFromLockMessage, signWithdrawMessage, stripHostedAuthCallbackParams, submitPendingLock, syncHostedAuthSessionToClient, useDepositVerification, usePrivanaContext, useSafeAccount, useSafePrivanaContext, useSiweAuth } from './chunk-ONXJGUOH.js';
4
4
  import { useState, useRef, useMemo, useCallback, useContext, useEffect, useId } from 'react';
5
5
  import { QueryClientContext, useQuery, useQueryClient, useMutation, keepPreviousData } from '@tanstack/react-query';
6
6
  import { useAccount, useWalletClient, useConfig, useWriteContract, useSendTransaction, useBalance as useBalance$1, useReadContract } from 'wagmi';
7
- import { zeroAddress, erc20Abi, formatUnits } from 'viem';
7
+ import { zeroAddress, erc20Abi, formatUnits, parseUnits } from 'viem';
8
8
  import { MoonPayProvider, MoonPayContext } from '@moonpay/moonpay-react';
9
9
  import * as DialogPrimitive from '@radix-ui/react-dialog';
10
- import { XIcon } from 'lucide-react';
10
+ import { XIcon, CircleCheckIcon, Loader2 } from 'lucide-react';
11
11
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
12
12
  import { toast } from 'sonner';
13
13
  import { QRCodeSVG } from 'qrcode.react';
@@ -2455,15 +2455,356 @@ function TokenSelectorView({ selectedTokenId, onSelect }) {
2455
2455
  enabledTokens.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground px-3 py-6 text-center text-sm", children: "No tokens available" })
2456
2456
  ] }) });
2457
2457
  }
2458
+ function assertTransakCheckoutPreconditions({
2459
+ activeIntentId,
2460
+ canOpen,
2461
+ canRecreateSession
2462
+ }) {
2463
+ if (activeIntentId && !canRecreateSession) {
2464
+ throw new Error("Continue signed-intent recovery instead of reopening this checkout");
2465
+ }
2466
+ if (!canOpen) {
2467
+ throw new Error("Card checkout is unavailable; close this purchase and start again");
2468
+ }
2469
+ }
2470
+ function TransakCardWidgetView({
2471
+ token,
2472
+ providerAssetCode,
2473
+ amount,
2474
+ allowance,
2475
+ lockServiceAddress,
2476
+ onCredited,
2477
+ onLockSubmitted,
2478
+ onLockFailed,
2479
+ onLeave,
2480
+ onUnsafeToCloseChange,
2481
+ onActiveFlowChange,
2482
+ useOnRamp = useTransakOnRamp
2483
+ }) {
2484
+ const [actionError, setActionError] = useState(null);
2485
+ const [rowError, setRowError] = useState(null);
2486
+ const [lockSettled, setLockSettled] = useState(false);
2487
+ const [lockError, setLockError] = useState(null);
2488
+ const [ownedTerminal, setOwnedTerminal] = useState(false);
2489
+ const ownedIntentIdRef = useRef(null);
2490
+ const postDepositLock = useMemo(
2491
+ () => allowance ? {
2492
+ serviceAddress: lockServiceAddress,
2493
+ maxAmount: BigInt(allowance.value),
2494
+ lockDuration: allowance.lockDuration
2495
+ } : void 0,
2496
+ [allowance, lockServiceAddress]
2497
+ );
2498
+ const ownsRecord = useCallback(
2499
+ (record) => Boolean(
2500
+ ownedIntentIdRef.current && matchesOnRampTransaction(record, ownedIntentIdRef.current)
2501
+ ),
2502
+ []
2503
+ );
2504
+ const {
2505
+ status,
2506
+ activeIntentId,
2507
+ pending,
2508
+ activeVerificationId,
2509
+ error,
2510
+ finalityProgress,
2511
+ depositAddress,
2512
+ minDepositBaseUnits,
2513
+ selectedToken,
2514
+ isLaunching,
2515
+ isWidgetOpen,
2516
+ canRecreateSession,
2517
+ widget,
2518
+ launch,
2519
+ recreateSession,
2520
+ closeWidget,
2521
+ finishPendingVerification,
2522
+ refreshPending
2523
+ } = useOnRamp({
2524
+ tokenId: token.id,
2525
+ postDepositLock,
2526
+ iframeTitle: "Card checkout",
2527
+ iframeClassName: "h-[680px] w-full border-0",
2528
+ onCredited: (_depositTxHash, record) => {
2529
+ if (!ownsRecord(record)) return;
2530
+ onCredited?.();
2531
+ if (!postDepositLock) {
2532
+ setOwnedTerminal(true);
2533
+ onActiveFlowChange?.(false);
2534
+ }
2535
+ },
2536
+ onLockSubmitted: (_response, record) => {
2537
+ if (!ownsRecord(record)) return;
2538
+ setLockError(null);
2539
+ setLockSettled(true);
2540
+ setOwnedTerminal(true);
2541
+ onActiveFlowChange?.(false);
2542
+ onLockSubmitted?.();
2543
+ },
2544
+ onLockFailed: (nextError, record) => {
2545
+ if (!ownsRecord(record)) return;
2546
+ setLockError(nextError);
2547
+ setOwnedTerminal(true);
2548
+ onActiveFlowChange?.(false);
2549
+ onLockFailed?.(nextError);
2550
+ }
2551
+ });
2552
+ const ownedIntentId = ownedIntentIdRef.current ?? activeIntentId;
2553
+ useEffect(() => {
2554
+ if (activeIntentId && !ownedIntentIdRef.current) {
2555
+ ownedIntentIdRef.current = activeIntentId;
2556
+ }
2557
+ }, [activeIntentId]);
2558
+ let amountBaseUnits;
2559
+ try {
2560
+ amountBaseUnits = parseUnits(amount, token.decimals);
2561
+ } catch {
2562
+ }
2563
+ const minimumTargetBaseUnits = minDepositBaseUnits === void 0 ? void 0 : getTransakMinimumTargetBaseUnits(minDepositBaseUnits);
2564
+ const belowMinimum = amountBaseUnits !== void 0 && minimumTargetBaseUnits !== void 0 && amountBaseUnits < minimumTargetBaseUnits;
2565
+ const minimumUnknown = minimumTargetBaseUnits === void 0;
2566
+ const tokenMismatch = !matchesFrozenOnRampToken(token, selectedToken);
2567
+ const isSettling = status === "awaiting-delivery" || status === "verifying";
2568
+ const lockPending = !!allowance && status === "credited" && !lockSettled && !lockError;
2569
+ const ownedPending = ownedIntentId ? pending.filter((record) => matchesOnRampTransaction(record, ownedIntentId)) : [];
2570
+ const ownedFlowActive = !ownedTerminal && (Boolean(activeIntentId && activeIntentId === ownedIntentId) || ownedPending.length > 0 || lockPending);
2571
+ const canOpen = Boolean(selectedToken && depositAddress && amountBaseUnits && amountBaseUnits > 0n) && !tokenMismatch && !minimumUnknown && !belowMinimum && !isLaunching && !isWidgetOpen && !isSettling && status !== "credited" && (!activeIntentId || canRecreateSession);
2572
+ useEffect(() => {
2573
+ onActiveFlowChange?.(ownedFlowActive);
2574
+ }, [onActiveFlowChange, ownedFlowActive]);
2575
+ const unsafeToClose = isLaunching || lockPending;
2576
+ useEffect(() => {
2577
+ onUnsafeToCloseChange?.(unsafeToClose);
2578
+ return () => onUnsafeToCloseChange?.(false);
2579
+ }, [onUnsafeToCloseChange, unsafeToClose]);
2580
+ const runCheckout = useCallback(async () => {
2581
+ setActionError(null);
2582
+ try {
2583
+ assertTransakCheckoutPreconditions({ activeIntentId, canOpen, canRecreateSession });
2584
+ setLockError(null);
2585
+ setLockSettled(false);
2586
+ setOwnedTerminal(false);
2587
+ if (!activeIntentId) ownedIntentIdRef.current = null;
2588
+ if (activeIntentId) await recreateSession();
2589
+ else await launch({ providerAssetCode, quoteCurrencyAmount: amount });
2590
+ } catch (nextError) {
2591
+ setActionError(
2592
+ nextError instanceof Error ? nextError : new Error("Failed to open card checkout")
2593
+ );
2594
+ }
2595
+ }, [
2596
+ activeIntentId,
2597
+ amount,
2598
+ canOpen,
2599
+ canRecreateSession,
2600
+ launch,
2601
+ providerAssetCode,
2602
+ recreateSession
2603
+ ]);
2604
+ const handleClose = useCallback(async () => {
2605
+ setActionError(null);
2606
+ try {
2607
+ await closeWidget();
2608
+ } catch (nextError) {
2609
+ setActionError(
2610
+ nextError instanceof Error ? nextError : new Error("Failed to close card checkout")
2611
+ );
2612
+ }
2613
+ }, [closeWidget]);
2614
+ const handleLeave = useCallback(() => {
2615
+ setActionError(null);
2616
+ onActiveFlowChange?.(false);
2617
+ onLeave?.();
2618
+ }, [onActiveFlowChange, onLeave]);
2619
+ return /* @__PURE__ */ jsxs("div", { className: "bg-muted flex flex-col gap-4 rounded-[10px] p-5", children: [
2620
+ /* @__PURE__ */ jsxs("div", { children: [
2621
+ /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Complete your purchase" }),
2622
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground mt-1 text-sm", children: [
2623
+ "Buy ",
2624
+ token.symbol,
2625
+ " and deposit it directly into your Privana balance."
2626
+ ] })
2627
+ ] }),
2628
+ /* @__PURE__ */ jsxs("div", { className: "border-border bg-card rounded-lg border p-3 text-sm", children: [
2629
+ /* @__PURE__ */ jsxs("p", { className: "text-foreground font-medium", children: [
2630
+ "Target receipt: at least ",
2631
+ amount,
2632
+ " ",
2633
+ token.symbol
2634
+ ] }),
2635
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: "In Transak, adjust the fiat amount until \u201CYou receive\u201D is at least this target." }),
2636
+ allowance && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: "The pre-signed lock is 98% of the target, capped by the service allowance." })
2637
+ ] }),
2638
+ widget ? /* @__PURE__ */ jsxs("div", { className: "border-border bg-card overflow-hidden rounded-xl border", children: [
2639
+ /* @__PURE__ */ jsxs("div", { className: "border-border flex items-center justify-between border-b px-4 py-2 text-sm", children: [
2640
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Card checkout" }),
2641
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void handleClose(), children: "Close" })
2642
+ ] }),
2643
+ widget
2644
+ ] }) : status === "credited" && !lockPending && !lockError ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 py-8 text-center", children: [
2645
+ /* @__PURE__ */ jsx(CircleCheckIcon, { className: "text-primary size-8", "aria-hidden": true }),
2646
+ /* @__PURE__ */ jsx("p", { className: "text-foreground text-sm font-medium", children: "Purchase credited" }),
2647
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-sm", children: [
2648
+ "Your ",
2649
+ token.symbol,
2650
+ " deposit is now available in your balance."
2651
+ ] })
2652
+ ] }) : !activeIntentId || canRecreateSession ? /* @__PURE__ */ jsxs(Button, { type: "button", disabled: !canOpen, onClick: () => void runCheckout(), children: [
2653
+ isLaunching && /* @__PURE__ */ jsx(Loader2, { className: "animate-spin", "aria-hidden": true }),
2654
+ isLaunching ? "Opening checkout\u2026" : activeIntentId ? "Reopen card checkout" : allowance ? "Sign policy and open checkout" : "Open card checkout"
2655
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "This signed purchase is in recovery. Do not open another checkout for it." }),
2656
+ !depositAddress && !error && !actionError && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Preparing your secure deposit address\u2026" }),
2657
+ tokenMismatch && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", role: "alert", children: "The token configuration changed. Close this purchase and start again." }),
2658
+ !tokenMismatch && depositAddress && minimumUnknown && !error && !actionError && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", role: "alert", children: "The minimum purchase amount is unavailable. Close this purchase and try again." }),
2659
+ belowMinimum && minimumTargetBaseUnits !== void 0 && /* @__PURE__ */ jsxs("p", { className: "text-destructive text-sm", role: "alert", children: [
2660
+ "Minimum target is ",
2661
+ formatUnits(minimumTargetBaseUnits, token.decimals),
2662
+ " ",
2663
+ token.symbol,
2664
+ ", including a 5% delivery buffer."
2665
+ ] }),
2666
+ isSettling && pending.length === 0 && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [
2667
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
2668
+ "Verifying your purchase\u2026"
2669
+ ] }),
2670
+ lockPending && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [
2671
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
2672
+ "Purchase credited. Locking your funds\u2026"
2673
+ ] }),
2674
+ pending.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2675
+ /* @__PURE__ */ jsx("p", { className: "text-foreground text-sm font-medium", children: "Validating purchases" }),
2676
+ pending.map((record) => {
2677
+ const isActivelyVerifying = record.transaction_id === activeVerificationId;
2678
+ const progress = parseFinalityProgress(finalityProgress[record.transaction_id]);
2679
+ const showRetry = canRetryOnRampVerification(record, activeVerificationId);
2680
+ return /* @__PURE__ */ jsxs(
2681
+ "div",
2682
+ {
2683
+ className: "border-border flex flex-col gap-2 rounded-md border p-2",
2684
+ children: [
2685
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground flex items-center gap-1 text-xs", children: [
2686
+ /* @__PURE__ */ jsx(Loader2, { className: "size-3 animate-spin", "aria-hidden": true }),
2687
+ record.on_chain_tx_hash ? progress ?? (isActivelyVerifying ? "Verifying\u2026" : "Ready to verify") : "Waiting for provider delivery\u2026"
2688
+ ] }),
2689
+ rowError?.id === record.transaction_id && /* @__PURE__ */ jsx("p", { className: "text-destructive text-xs", children: rowError.message }),
2690
+ showRetry && /* @__PURE__ */ jsx(
2691
+ Button,
2692
+ {
2693
+ type: "button",
2694
+ variant: "outline",
2695
+ size: "sm",
2696
+ onClick: async () => {
2697
+ setRowError(null);
2698
+ try {
2699
+ await finishPendingVerification(record);
2700
+ } catch (nextError) {
2701
+ setRowError({
2702
+ id: record.transaction_id,
2703
+ message: nextError instanceof Error ? nextError.message : "Verification failed"
2704
+ });
2705
+ }
2706
+ },
2707
+ children: "Retry verification"
2708
+ }
2709
+ ),
2710
+ !record.on_chain_tx_hash && /* @__PURE__ */ jsx(
2711
+ Button,
2712
+ {
2713
+ type: "button",
2714
+ variant: "outline",
2715
+ size: "sm",
2716
+ onClick: () => void refreshPending(),
2717
+ children: "Refresh delivery"
2718
+ }
2719
+ )
2720
+ ]
2721
+ },
2722
+ record.transaction_id
2723
+ );
2724
+ })
2725
+ ] }),
2726
+ onLeave && ownedFlowActive && !unsafeToClose && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2727
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: handleLeave, children: "Leave checkout" }),
2728
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: "Privana will keep this signed purchase available for exact recovery." })
2729
+ ] }),
2730
+ (actionError ?? error) && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", role: "alert", children: (actionError ?? error)?.message }),
2731
+ lockError && /* @__PURE__ */ jsxs("p", { className: "text-destructive text-sm", role: "alert", children: [
2732
+ "Purchase credited, but locking the funds failed: ",
2733
+ lockError.message
2734
+ ] })
2735
+ ] });
2736
+ }
2737
+ function parseFinalityProgress(message) {
2738
+ if (!message) return null;
2739
+ const match = message.match(/(\d+\/\d+)\s+confirmations/i);
2740
+ return match ? `${match[1]} confirmations` : null;
2741
+ }
2458
2742
  function CreditCardWidgetView({
2459
2743
  token,
2744
+ onRamp,
2460
2745
  amount,
2461
2746
  allowance,
2747
+ lockServiceAddress,
2462
2748
  onCredited,
2463
2749
  onLockSubmitted,
2464
- onLockFailed
2750
+ onLockFailed,
2751
+ onLeave,
2752
+ onUnsafeToCloseChange,
2753
+ onActiveFlowChange
2754
+ }) {
2755
+ if (onRamp.unavailableReason || !token || !onRamp.provider || !onRamp.providerAssetCode) {
2756
+ return /* @__PURE__ */ jsxs("div", { className: "bg-muted flex flex-col gap-2 rounded-[10px] p-5", children: [
2757
+ /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Card purchases unavailable" }),
2758
+ /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", children: onRamp.unavailableReason ?? "The card on-ramp is not configured for this token." })
2759
+ ] });
2760
+ }
2761
+ if (onRamp.provider === "transak") {
2762
+ return /* @__PURE__ */ jsx(
2763
+ TransakCardWidgetView,
2764
+ {
2765
+ token,
2766
+ providerAssetCode: onRamp.providerAssetCode,
2767
+ amount,
2768
+ allowance,
2769
+ lockServiceAddress,
2770
+ onCredited,
2771
+ onLockSubmitted,
2772
+ onLockFailed,
2773
+ onLeave,
2774
+ onUnsafeToCloseChange,
2775
+ onActiveFlowChange
2776
+ }
2777
+ );
2778
+ }
2779
+ return /* @__PURE__ */ jsx(
2780
+ MoonPayCardWidgetView,
2781
+ {
2782
+ token,
2783
+ amount,
2784
+ allowance,
2785
+ lockServiceAddress,
2786
+ onCredited,
2787
+ onLockSubmitted,
2788
+ onLockFailed,
2789
+ onLeaveFlow: onLeave,
2790
+ onUnsafeToCloseChange,
2791
+ onActiveFlowChange
2792
+ }
2793
+ );
2794
+ }
2795
+ function MoonPayCardWidgetView({
2796
+ token,
2797
+ amount,
2798
+ allowance,
2799
+ lockServiceAddress,
2800
+ onCredited,
2801
+ onLockSubmitted,
2802
+ onLockFailed,
2803
+ onLeaveFlow,
2804
+ onUnsafeToCloseChange,
2805
+ onActiveFlowChange
2465
2806
  }) {
2466
- const moonpayCurrencyCode = token?.moonpayCurrencyCode;
2807
+ const moonpayCurrencyCode = token.moonpayCurrencyCode;
2467
2808
  const containerRef = useRef(null);
2468
2809
  const [widgetTheme, setWidgetTheme] = useState();
2469
2810
  useEffect(() => {
@@ -2471,26 +2812,32 @@ function CreditCardWidgetView({
2471
2812
  }, []);
2472
2813
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
2473
2814
  /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Complete your purchase" }),
2474
- token && moonpayCurrencyCode ? /* @__PURE__ */ jsx(
2815
+ moonpayCurrencyCode ? /* @__PURE__ */ jsx(
2475
2816
  FiatOnRampForm,
2476
2817
  {
2477
2818
  tokenId: token.id,
2819
+ frozenToken: token,
2478
2820
  currencyCode: moonpayCurrencyCode,
2479
2821
  quoteCurrencyAmount: amount || void 0,
2480
2822
  lockAmount: true,
2481
2823
  variant: "embedded",
2482
2824
  autoStart: true,
2483
2825
  theme: widgetTheme,
2826
+ onlyRouteActiveIntentCallbacks: true,
2827
+ onUnsafeToCloseChange,
2828
+ onActiveFlowChange,
2484
2829
  postDepositLock: allowance ? {
2830
+ serviceAddress: lockServiceAddress,
2485
2831
  maxAmount: BigInt(allowance.value),
2486
2832
  lockDuration: allowance.lockDuration
2487
2833
  } : void 0,
2488
2834
  onCredited,
2489
2835
  onLockSubmitted,
2490
- onLockFailed
2836
+ onLockFailed,
2837
+ onLeaveFlow
2491
2838
  }
2492
2839
  ) : /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-sm", children: [
2493
- token?.symbol ?? "This token",
2840
+ token.symbol,
2494
2841
  " isn\u2019t available for card purchases yet."
2495
2842
  ] })
2496
2843
  ] });
@@ -2799,7 +3146,7 @@ function CopyIcon() {
2799
3146
  }
2800
3147
  );
2801
3148
  }
2802
- function CircleCheckIcon() {
3149
+ function CircleCheckIcon2() {
2803
3150
  return /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
2804
3151
  /* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
2805
3152
  /* @__PURE__ */ jsx(
@@ -2918,7 +3265,7 @@ function PolicyTermRow({
2918
3265
  "mt-0.5 shrink-0",
2919
3266
  kind === "permission" ? "text-emerald-500" : "text-orange-500"
2920
3267
  ),
2921
- children: kind === "permission" ? /* @__PURE__ */ jsx(CircleCheckIcon, {}) : /* @__PURE__ */ jsx(CircleXIcon, {})
3268
+ children: kind === "permission" ? /* @__PURE__ */ jsx(CircleCheckIcon2, {}) : /* @__PURE__ */ jsx(CircleXIcon, {})
2922
3269
  }
2923
3270
  ),
2924
3271
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
@@ -2978,6 +3325,7 @@ function AllowancePolicySection({
2978
3325
  function DepositView({
2979
3326
  source,
2980
3327
  selectedToken,
3328
+ onRamp,
2981
3329
  amount,
2982
3330
  allowance,
2983
3331
  externalMinimum,
@@ -2996,6 +3344,8 @@ function DepositView({
2996
3344
  const isConnectedSource = source === "connected";
2997
3345
  const isExternal = source === "external";
2998
3346
  const isCreditCard = source === "credit-card";
3347
+ const isMoonPayCard = isCreditCard && isMoonPayProductOnRamp(onRamp);
3348
+ const isTransakCard = isCreditCard && onRamp.provider === "transak";
2999
3349
  const isNative = selectedToken?.contract === zeroAddress;
3000
3350
  const { data: nativeBalanceData } = useBalance$1({
3001
3351
  address,
@@ -3019,15 +3369,15 @@ function DepositView({
3019
3369
  } = useMoonpayLimits({
3020
3370
  currencyCode: selectedToken?.moonpayCurrencyCode,
3021
3371
  apiBaseUrl: networkConfig.moonpayApiUrl,
3022
- enabled: isCreditCard
3372
+ enabled: isMoonPayCard
3023
3373
  });
3024
3374
  const hasValidAmount = !!amount && parseFloat(amount) > 0;
3025
- const maxAmountDecimals = isCreditCard ? 2 : selectedToken?.decimals;
3375
+ const maxAmountDecimals = isMoonPayCard ? 2 : selectedToken?.decimals;
3026
3376
  const tooManyDecimals = hasValidAmount && maxAmountDecimals != null && amount.includes(".") && amount.split(".")[1].length > maxAmountDecimals;
3027
3377
  const exceedsBalance = isConnectedSource && hasValidAmount && !tooManyDecimals && !!selectedToken && walletBalance != null && parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
3028
- const belowMoonpayMin = isCreditCard && hasValidAmount && moonpayMinBuy != null && parseFloat(amount) < moonpayMinBuy;
3029
- const moonpayLimitsUnready = isCreditCard && !!selectedToken?.moonpayCurrencyCode && moonpayMinBuy == null;
3030
- const creditCardUnavailable = isCreditCard && !!selectedToken && !selectedToken.moonpayCurrencyCode;
3378
+ const belowMoonpayMin = isMoonPayCard && hasValidAmount && moonpayMinBuy != null && parseFloat(amount) < moonpayMinBuy;
3379
+ const moonpayLimitsUnready = isMoonPayCard && !!onRamp.providerAssetCode && moonpayMinBuy == null;
3380
+ const creditCardUnavailable = isCreditCard && !!onRamp.unavailableReason;
3031
3381
  const externalTokenUnavailable = isExternal && !!selectedToken && isNative;
3032
3382
  const externalMinimumRequired = isExternal && !!allowance && !!selectedToken;
3033
3383
  const externalMinimumLoading = externalMinimumRequired && externalMinimum === void 0;
@@ -3042,8 +3392,8 @@ function DepositView({
3042
3392
  };
3043
3393
  return /* @__PURE__ */ jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
3044
3394
  isCreditCard ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3045
- /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Buy with credit card and deposit" }),
3046
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Enter your deposit amount and proceed to sign a policy." })
3395
+ /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Buy with card and deposit" }),
3396
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: isTransakCard ? "Enter your target deposit amount and continue." : "Enter your deposit amount and proceed to sign a policy." })
3047
3397
  ] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3048
3398
  /* @__PURE__ */ jsxs("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: [
3049
3399
  "Deposit from ",
@@ -3058,7 +3408,7 @@ function DepositView({
3058
3408
  {
3059
3409
  type: "button",
3060
3410
  onClick: onSelectToken,
3061
- disabled: isSubmitting,
3411
+ disabled: isSubmitting || isCreditCard && onRamp.tokenSelectionLocked,
3062
3412
  className: "border-border bg-input flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left disabled:cursor-not-allowed disabled:opacity-50",
3063
3413
  children: [
3064
3414
  selectedToken ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3071,7 +3421,7 @@ function DepositView({
3071
3421
  ] })
3072
3422
  ] })
3073
3423
  ] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground flex-1 text-sm", children: "Select token" }),
3074
- /* @__PURE__ */ jsx("div", { className: "text-muted-foreground flex h-5 w-5 items-center justify-center", children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) })
3424
+ (!isCreditCard || !onRamp.tokenSelectionLocked) && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground flex h-5 w-5 items-center justify-center", children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) })
3075
3425
  ]
3076
3426
  }
3077
3427
  )
@@ -3141,12 +3491,9 @@ function DepositView({
3141
3491
  ] }),
3142
3492
  externalMinimumLoading && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Checking minimum deposit\u2026" }),
3143
3493
  externalMinimumUnavailable && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load the minimum deposit. Please try again." }),
3144
- isCreditCard && moonpayLimitsError && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load purchase limits. Please try again." }),
3145
- isCreditCard && moonpayLimitsLoading && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Checking purchase limits\u2026" }),
3146
- creditCardUnavailable && /* @__PURE__ */ jsxs("p", { className: "text-destructive text-sm", children: [
3147
- selectedToken?.symbol ?? "This token",
3148
- " isn\u2019t available for card purchases yet."
3149
- ] }),
3494
+ isMoonPayCard && moonpayLimitsError && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load purchase limits. Please try again." }),
3495
+ isMoonPayCard && moonpayLimitsLoading && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Checking purchase limits\u2026" }),
3496
+ creditCardUnavailable && /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", children: onRamp.unavailableReason }),
3150
3497
  externalTokenUnavailable && /* @__PURE__ */ jsxs("p", { className: "text-destructive text-sm", children: [
3151
3498
  selectedToken?.symbol ?? "This token",
3152
3499
  " can\u2019t be used for external deposits. Choose an ERC20 token."
@@ -3173,7 +3520,7 @@ function DepositView({
3173
3520
  if (selectedToken) onSubmit({ source, tokenId: selectedToken.id, amount });
3174
3521
  },
3175
3522
  className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
3176
- children: needsConnect ? "Connect Wallet" : allowance ? "Sign Policy and Deposit" : "Deposit"
3523
+ children: needsConnect ? "Connect Wallet" : isTransakCard ? "Continue" : allowance ? "Sign Policy and Deposit" : "Deposit"
3177
3524
  }
3178
3525
  )
3179
3526
  ] });
@@ -3485,9 +3832,11 @@ function ExternalDepositView({
3485
3832
  ] })
3486
3833
  ] });
3487
3834
  }
3488
- function MoonPayGate({ enabled, children }) {
3489
- const { networkConfig } = usePrivanaContext();
3490
- const apiKey = networkConfig.moonpayApiKey;
3835
+ function MoonPayGate({
3836
+ enabled,
3837
+ apiKey,
3838
+ children
3839
+ }) {
3491
3840
  if (!enabled || !apiKey) return /* @__PURE__ */ jsx(Fragment, { children });
3492
3841
  return /* @__PURE__ */ jsx(MoonPayProvider, { apiKey, children });
3493
3842
  }
@@ -3574,15 +3923,52 @@ function DepositModalContent({
3574
3923
  onCloseBlockedChange,
3575
3924
  onExit
3576
3925
  }) {
3577
- const { serviceName, enabledTokens, defaultToken, hostedAuthConfig, getChainById: getChainById2, getTokenById } = usePrivanaContext();
3926
+ const {
3927
+ serviceName,
3928
+ enabledTokens,
3929
+ defaultToken,
3930
+ hostedAuthConfig,
3931
+ serviceAddress,
3932
+ getChainById: getChainById2,
3933
+ getTokenById,
3934
+ networkConfig,
3935
+ onRamp
3936
+ } = usePrivanaContext();
3578
3937
  const { address } = useAccount();
3938
+ const { privateReadQueryScope } = usePrivateReadRequest();
3939
+ const [privateReadApiUrl, accountingChainId, beneficiaryAddress] = privateReadQueryScope;
3579
3940
  const appName = serviceName ?? "Privana";
3580
3941
  const [activeTab, setActiveTab] = useState(defaultTab);
3581
3942
  const [view, setView] = useState("method");
3582
3943
  const [source, setSource] = useState("connected");
3583
3944
  const [selectedTokenId, setSelectedTokenId] = useState(defaultToken?.id ?? "");
3584
3945
  const [amount, setAmount] = useState("");
3585
- const selectedToken = enabledTokens.find((t) => t.id === selectedTokenId) ?? defaultToken;
3946
+ const [cardFlow, setCardFlow] = useState(null);
3947
+ const [cardFlowActive, setCardFlowActive] = useState(false);
3948
+ const [cardUnsafeToClose, setCardUnsafeToClose] = useState(false);
3949
+ const nextCardFlowId = useRef(0);
3950
+ const stateSelectedToken = enabledTokens.find((t) => t.id === selectedTokenId) ?? defaultToken;
3951
+ const cardOnRamp = useMemo(
3952
+ () => resolveProductOnRamp({
3953
+ config: onRamp,
3954
+ enabledTokens,
3955
+ legacyToken: stateSelectedToken,
3956
+ moonpayApiKey: networkConfig.moonpayApiKey
3957
+ }),
3958
+ [enabledTokens, networkConfig.moonpayApiKey, onRamp, stateSelectedToken]
3959
+ );
3960
+ const cardOnRampScope = useMemo(
3961
+ () => ({
3962
+ apiUrl: privateReadApiUrl,
3963
+ accountingChainId,
3964
+ accountingContract: networkConfig.accountingContract,
3965
+ beneficiaryAddress
3966
+ }),
3967
+ [accountingChainId, beneficiaryAddress, networkConfig.accountingContract, privateReadApiUrl]
3968
+ );
3969
+ const mountedCardFlow = cardFlow && matchesProductOnRampScope(cardFlow.scope, cardOnRampScope) ? cardFlow : null;
3970
+ const displayedCardOnRamp = view === "credit-card-widget" && mountedCardFlow ? mountedCardFlow.selection : cardOnRamp;
3971
+ const selectedToken = source === "credit-card" ? displayedCardOnRamp.token : stateSelectedToken;
3586
3972
  const externalDepositAddress = useDepositAddress({
3587
3973
  enabled: source === "external" && (view === "deposit" || view === "external-deposit")
3588
3974
  });
@@ -3596,6 +3982,9 @@ function DepositModalContent({
3596
3982
  setView("method");
3597
3983
  setAmount("");
3598
3984
  setSelectedTokenId("");
3985
+ setCardFlow(null);
3986
+ setCardFlowActive(false);
3987
+ setCardUnsafeToClose(false);
3599
3988
  }
3600
3989
  }, [address, hostedAuthConfig]);
3601
3990
  const openDeposit = (next) => {
@@ -3618,9 +4007,33 @@ function DepositModalContent({
3618
4007
  }
3619
4008
  };
3620
4009
  const finishCardPurchase = () => {
4010
+ setCardFlowActive(false);
4011
+ setCardUnsafeToClose(false);
3621
4012
  setAmount("");
3622
4013
  onDepositSuccess?.();
3623
4014
  };
4015
+ const leaveCardPurchase = useCallback(() => {
4016
+ setCardFlow(null);
4017
+ setCardFlowActive(false);
4018
+ setCardUnsafeToClose(false);
4019
+ setAmount("");
4020
+ setView("deposit");
4021
+ }, []);
4022
+ useEffect(() => {
4023
+ if (cardFlow && !matchesProductOnRampScope(cardFlow.scope, cardOnRampScope)) {
4024
+ leaveCardPurchase();
4025
+ }
4026
+ }, [cardFlow, cardOnRampScope, leaveCardPurchase]);
4027
+ const cardOutcomeCallbacks = mountedCardFlow ? createProductOnRampOutcomeCallbacks({
4028
+ requiresLock: mountedCardFlow.requiresLock,
4029
+ onComplete: finishCardPurchase,
4030
+ onLockFailed: (err) => {
4031
+ setCardFlowActive(false);
4032
+ setCardUnsafeToClose(false);
4033
+ setLockFailure(err);
4034
+ onLockFailed?.(err);
4035
+ }
4036
+ }) : null;
3624
4037
  const {
3625
4038
  txHash,
3626
4039
  isGettingAddress,
@@ -3690,7 +4103,7 @@ function DepositModalContent({
3690
4103
  setView("deposit");
3691
4104
  }
3692
4105
  }, [allowance, externalLock.session, view]);
3693
- const isUnsafeToClose = (isGettingAddress || isSendingTransaction) && !cancelled || externalLock.isSigning || externalLock.isSubmittingLock;
4106
+ const isUnsafeToClose = (isGettingAddress || isSendingTransaction) && !cancelled || externalLock.isSigning || externalLock.isSubmittingLock || cardUnsafeToClose;
3694
4107
  useEffect(() => {
3695
4108
  onCloseBlockedChange?.(isUnsafeToClose);
3696
4109
  }, [isUnsafeToClose, onCloseBlockedChange]);
@@ -3733,6 +4146,28 @@ function DepositModalContent({
3733
4146
  return;
3734
4147
  }
3735
4148
  if (args.source === "credit-card") {
4149
+ if (cardFlow && cardFlowActive) {
4150
+ setView("credit-card-widget");
4151
+ return;
4152
+ }
4153
+ try {
4154
+ setCardFlow(
4155
+ createProductOnRampFlowSnapshot({
4156
+ id: ++nextCardFlowId.current,
4157
+ selection: cardOnRamp,
4158
+ amount: args.amount,
4159
+ allowance,
4160
+ lockServiceAddress: serviceAddress,
4161
+ moonpayApiKey: networkConfig.moonpayApiKey,
4162
+ scope: cardOnRampScope
4163
+ })
4164
+ );
4165
+ } catch (error) {
4166
+ toast.error(error instanceof Error ? error.message : "Card purchase is unavailable");
4167
+ return;
4168
+ }
4169
+ setCardFlowActive(false);
4170
+ setCardUnsafeToClose(false);
3736
4171
  setView("credit-card-widget");
3737
4172
  return;
3738
4173
  }
@@ -3810,6 +4245,12 @@ function DepositModalContent({
3810
4245
  setCancelled(false);
3811
4246
  resetDeposit();
3812
4247
  if (view === "external-deposit") setView("deposit");
4248
+ if (view === "credit-card-widget") {
4249
+ setCardFlow(null);
4250
+ setCardFlowActive(false);
4251
+ setCardUnsafeToClose(false);
4252
+ setView("deposit");
4253
+ }
3813
4254
  };
3814
4255
  const handleExternalLockRetry = () => {
3815
4256
  externalLock.retryAfterCredit().catch((err) => {
@@ -3833,12 +4274,20 @@ function DepositModalContent({
3833
4274
  retryVerification().catch(() => {
3834
4275
  });
3835
4276
  };
3836
- const back = view === "external-deposit" ? { to: "deposit", label: "Deposit from External Wallet" } : view === "credit-card-widget" ? { to: "deposit", label: "Buy with credit card and deposit" } : view === "select-token" ? { to: "deposit", label: "Deposit" } : { to: "method", label: "Deposit Method" };
4277
+ const back = view === "external-deposit" ? { to: "deposit", label: "Deposit from External Wallet" } : view === "credit-card-widget" ? { to: "deposit", label: "Buy with card and deposit" } : view === "select-token" ? { to: "deposit", label: "Deposit" } : { to: "method", label: "Deposit Method" };
3837
4278
  const goBack = () => {
3838
4279
  if (view === "external-deposit" && externalLock.session) {
3839
4280
  toast.error("Cancel the active deposit from the address screen before going back");
3840
4281
  return;
3841
4282
  }
4283
+ if (view === "credit-card-widget" && (cardUnsafeToClose || cardFlowActive)) {
4284
+ toast.error("Finish or recover the active card purchase before going back");
4285
+ return;
4286
+ }
4287
+ if (view === "credit-card-widget") {
4288
+ setCardFlow(null);
4289
+ setCardUnsafeToClose(false);
4290
+ }
3842
4291
  if (back.to === "method") {
3843
4292
  setAmount("");
3844
4293
  setSelectedTokenId("");
@@ -3924,8 +4373,8 @@ function DepositModalContent({
3924
4373
  ] }),
3925
4374
  activeView === "method" && /* @__PURE__ */ jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
3926
4375
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3927
- /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: activeTab === "crypto" ? "Choose the deposit method" : "Buy with credit card and deposit" }),
3928
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: activeTab === "crypto" ? "Choose the deposit method." : "Use credit card to buy crypto and deposit" })
4376
+ /* @__PURE__ */ jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: activeTab === "crypto" ? "Choose the deposit method" : "Buy with card and deposit" }),
4377
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: activeTab === "crypto" ? "Choose the deposit method." : "Buy crypto by card and deposit it into your account." })
3929
4378
  ] }),
3930
4379
  /* @__PURE__ */ jsx(MethodTabs, { activeTab, onTabChange: setActiveTab }),
3931
4380
  activeTab === "crypto" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
@@ -3954,8 +4403,8 @@ function DepositModalContent({
3954
4403
  ] }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx(
3955
4404
  MethodOption,
3956
4405
  {
3957
- title: "Moonpay",
3958
- description: "on selected address",
4406
+ title: "Buy with card",
4407
+ description: "Purchase and deposit directly into your account.",
3959
4408
  onClick: () => {
3960
4409
  onSelectCreditCard?.();
3961
4410
  openDeposit("credit-card");
@@ -3963,21 +4412,29 @@ function DepositModalContent({
3963
4412
  }
3964
4413
  ) })
3965
4414
  ] }),
3966
- activeView === "deposit" && /* @__PURE__ */ jsx(MoonPayGate, { enabled: source === "credit-card", children: /* @__PURE__ */ jsx(
3967
- DepositView,
4415
+ activeView === "deposit" && /* @__PURE__ */ jsx(
4416
+ MoonPayGate,
3968
4417
  {
3969
- source,
3970
- selectedToken,
3971
- amount,
3972
- allowance,
3973
- externalMinimum,
3974
- onAmountChange: setAmount,
3975
- onSelectToken: () => setView("select-token"),
3976
- onConnectWallet,
3977
- onSubmit: handleSubmit,
3978
- isSubmitting: isPending || externalLock.isSigning || externalLock.isSubmittingLock
4418
+ enabled: source === "credit-card" && cardOnRamp.provider === "moonpay" && !cardOnRamp.unavailableReason,
4419
+ apiKey: networkConfig.moonpayApiKey,
4420
+ children: /* @__PURE__ */ jsx(
4421
+ DepositView,
4422
+ {
4423
+ source,
4424
+ selectedToken,
4425
+ onRamp: cardOnRamp,
4426
+ amount,
4427
+ allowance,
4428
+ externalMinimum,
4429
+ onAmountChange: setAmount,
4430
+ onSelectToken: () => setView("select-token"),
4431
+ onConnectWallet,
4432
+ onSubmit: handleSubmit,
4433
+ isSubmitting: isPending || externalLock.isSigning || externalLock.isSubmittingLock
4434
+ }
4435
+ )
3979
4436
  }
3980
- ) }),
4437
+ ),
3981
4438
  activeView === "select-token" && /* @__PURE__ */ jsx(
3982
4439
  TokenSelectorView,
3983
4440
  {
@@ -3999,20 +4456,30 @@ function DepositModalContent({
3999
4456
  lock: externalLock.session ? externalLock : void 0
4000
4457
  }
4001
4458
  ),
4002
- activeView === "credit-card-widget" && /* @__PURE__ */ jsx(MoonPayGate, { enabled: true, children: /* @__PURE__ */ jsx(
4003
- CreditCardWidgetView,
4459
+ activeView === "credit-card-widget" && mountedCardFlow && /* @__PURE__ */ jsx(
4460
+ MoonPayGate,
4004
4461
  {
4005
- token: selectedToken,
4006
- amount,
4007
- allowance,
4008
- onCredited: allowance ? void 0 : finishCardPurchase,
4009
- onLockSubmitted: finishCardPurchase,
4010
- onLockFailed: (err) => {
4011
- setLockFailure(err);
4012
- onLockFailed?.(err);
4013
- }
4462
+ enabled: mountedCardFlow.selection.provider === "moonpay",
4463
+ apiKey: mountedCardFlow.moonpayApiKey,
4464
+ children: /* @__PURE__ */ jsx(
4465
+ CreditCardWidgetView,
4466
+ {
4467
+ token: mountedCardFlow.selection.token,
4468
+ onRamp: mountedCardFlow.selection,
4469
+ amount: mountedCardFlow.amount,
4470
+ allowance: mountedCardFlow.allowance,
4471
+ lockServiceAddress: mountedCardFlow.lockServiceAddress,
4472
+ onUnsafeToCloseChange: setCardUnsafeToClose,
4473
+ onActiveFlowChange: setCardFlowActive,
4474
+ onCredited: cardOutcomeCallbacks?.onCredited,
4475
+ onLockSubmitted: cardOutcomeCallbacks?.onLockSubmitted,
4476
+ onLockFailed: cardOutcomeCallbacks?.onLockFailed,
4477
+ onLeave: leaveCardPurchase
4478
+ },
4479
+ mountedCardFlow.id
4480
+ )
4014
4481
  }
4015
- ) })
4482
+ )
4016
4483
  ] });
4017
4484
  }
4018
4485
  function DepositModal({ open, onClose, ...handlers }) {