@b3dotfun/sdk 0.0.16 → 0.0.17-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +5 -2
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +264 -55
  3. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +25 -29
  4. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
  5. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +49 -0
  6. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
  7. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +118 -0
  8. package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
  9. package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +71 -0
  10. package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +2 -0
  11. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +41 -60
  12. package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
  13. package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +42 -0
  14. package/dist/cjs/anyspend/react/components/common/OrderStatus.js +28 -5
  15. package/dist/cjs/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
  16. package/dist/cjs/anyspend/react/components/common/OrderTokenAmountFiat.js +50 -0
  17. package/dist/cjs/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
  18. package/dist/cjs/anyspend/react/components/common/OrderTokenAmountNew.js +63 -0
  19. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
  20. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +53 -15
  21. package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +1 -12
  22. package/dist/cjs/anyspend/react/components/common/PaymentStripeWeb2.js +4 -12
  23. package/dist/cjs/anyspend/react/components/common/StepProgress.d.ts +11 -0
  24. package/dist/cjs/anyspend/react/components/common/StepProgress.js +22 -0
  25. package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
  26. package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +73 -0
  27. package/dist/cjs/anyspend/react/components/index.d.ts +3 -0
  28. package/dist/cjs/anyspend/react/components/index.js +7 -1
  29. package/dist/cjs/anyspend/react/components/webview/WebviewOnrampPayment.js +1 -10
  30. package/dist/cjs/anyspend/utils/format.d.ts +1 -0
  31. package/dist/cjs/anyspend/utils/format.js +23 -10
  32. package/dist/cjs/anyspend/utils/number.d.ts +7 -0
  33. package/dist/cjs/anyspend/utils/number.js +18 -0
  34. package/dist/esm/anyspend/react/components/AnySpend.d.ts +5 -2
  35. package/dist/esm/anyspend/react/components/AnySpend.js +266 -57
  36. package/dist/esm/anyspend/react/components/AnySpendCustom.js +27 -31
  37. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
  38. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +46 -0
  39. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
  40. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +114 -0
  41. package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
  42. package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +67 -0
  43. package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +2 -0
  44. package/dist/esm/anyspend/react/components/common/OrderDetails.js +43 -62
  45. package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
  46. package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +36 -0
  47. package/dist/esm/anyspend/react/components/common/OrderStatus.js +27 -4
  48. package/dist/esm/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
  49. package/dist/esm/anyspend/react/components/common/OrderTokenAmountFiat.js +47 -0
  50. package/dist/esm/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
  51. package/dist/esm/anyspend/react/components/common/OrderTokenAmountNew.js +60 -0
  52. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
  53. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +54 -16
  54. package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +1 -12
  55. package/dist/esm/anyspend/react/components/common/PaymentStripeWeb2.js +7 -15
  56. package/dist/esm/anyspend/react/components/common/StepProgress.d.ts +11 -0
  57. package/dist/esm/anyspend/react/components/common/StepProgress.js +19 -0
  58. package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
  59. package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +70 -0
  60. package/dist/esm/anyspend/react/components/index.d.ts +3 -0
  61. package/dist/esm/anyspend/react/components/index.js +3 -0
  62. package/dist/esm/anyspend/react/components/webview/WebviewOnrampPayment.js +1 -10
  63. package/dist/esm/anyspend/utils/format.d.ts +1 -0
  64. package/dist/esm/anyspend/utils/format.js +23 -10
  65. package/dist/esm/anyspend/utils/number.d.ts +7 -0
  66. package/dist/esm/anyspend/utils/number.js +17 -0
  67. package/dist/styles/index.css +1 -1
  68. package/dist/types/anyspend/react/components/AnySpend.d.ts +5 -2
  69. package/dist/types/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
  70. package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
  71. package/dist/types/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
  72. package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +2 -0
  73. package/dist/types/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
  74. package/dist/types/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
  75. package/dist/types/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
  76. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
  77. package/dist/types/anyspend/react/components/common/StepProgress.d.ts +11 -0
  78. package/dist/types/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
  79. package/dist/types/anyspend/react/components/index.d.ts +3 -0
  80. package/dist/types/anyspend/utils/format.d.ts +1 -0
  81. package/dist/types/anyspend/utils/number.d.ts +7 -0
  82. package/package.json +1 -1
  83. package/src/anyspend/react/components/AnySpend.tsx +535 -177
  84. package/src/anyspend/react/components/AnySpendCustom.tsx +33 -38
  85. package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +124 -0
  86. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +227 -0
  87. package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +173 -0
  88. package/src/anyspend/react/components/common/OrderDetails.tsx +123 -250
  89. package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +156 -0
  90. package/src/anyspend/react/components/common/OrderStatus.tsx +47 -24
  91. package/src/anyspend/react/components/common/OrderTokenAmountFiat.tsx +147 -0
  92. package/src/anyspend/react/components/common/OrderTokenAmountNew.tsx +215 -0
  93. package/src/anyspend/react/components/common/PanelOnramp.tsx +215 -62
  94. package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +1 -14
  95. package/src/anyspend/react/components/common/PaymentStripeWeb2.tsx +42 -99
  96. package/src/anyspend/react/components/common/StepProgress.tsx +104 -0
  97. package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +261 -0
  98. package/src/anyspend/react/components/index.ts +3 -0
  99. package/src/anyspend/react/components/webview/WebviewOnrampPayment.tsx +1 -11
  100. package/src/anyspend/utils/format.ts +24 -11
  101. package/src/anyspend/utils/number.ts +18 -0
  102. package/src/styles/index.css +30 -11
@@ -1,14 +1,53 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCoinbaseOnrampOptions } from "../../../../anyspend/react/index.js";
3
- import { Input, useGetGeo } from "../../../../global-account/react/index.js";
4
- import { AnimatePresence, motion } from "motion/react";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCoinbaseOnrampOptions, useGeoOnrampOptions } from "../../../../anyspend/react/index.js";
3
+ import { ALL_CHAINS } from "../../../../anyspend/utils/chain.js";
4
+ import { Input, useGetGeo, useProfile } from "../../../../global-account/react/index.js";
5
+ import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
6
+ import { ChevronRight, Wallet } from "lucide-react";
5
7
  import { useRef } from "react";
6
8
  import { toast } from "sonner";
7
- import { PaymentOptions } from "./PaymentOptions.js";
8
- export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, }) {
9
+ import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
10
+ import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
11
+ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, }) {
12
+ // Get geo-based onramp options to access fee information
13
+ const { stripeWeb2Support } = useGeoOnrampOptions(true, srcAmountOnRamp);
14
+ // Helper function to get fees from API data
15
+ const getFeeFromApi = (paymentMethod) => {
16
+ switch (paymentMethod) {
17
+ case FiatPaymentMethod.COINBASE_PAY:
18
+ // Coinbase doesn't provide fee info in API, return 0
19
+ return 0;
20
+ case FiatPaymentMethod.STRIPE:
21
+ // Get fee from Stripe API response
22
+ if (stripeWeb2Support && "formattedFeeUsd" in stripeWeb2Support) {
23
+ return parseFloat(stripeWeb2Support.formattedFeeUsd) || 0;
24
+ }
25
+ return null;
26
+ default:
27
+ return null; // No fee when no payment method selected
28
+ }
29
+ };
30
+ // Helper function to get total amount from API (for Stripe) or calculate it (for others)
31
+ const getTotalAmount = (paymentMethod) => {
32
+ const baseAmount = parseFloat(srcAmountOnRamp) || 5;
33
+ const fee = getFeeFromApi(paymentMethod);
34
+ if (paymentMethod === FiatPaymentMethod.STRIPE && stripeWeb2Support && "formattedTotalUsd" in stripeWeb2Support) {
35
+ // Use the total from Stripe API if available
36
+ return parseFloat(stripeWeb2Support.formattedTotalUsd) || baseAmount;
37
+ }
38
+ // For Coinbase or when fee is available, calculate manually
39
+ if (fee !== null) {
40
+ return baseAmount + fee;
41
+ }
42
+ // No fee available, return base amount
43
+ return baseAmount;
44
+ };
9
45
  // Get geo data for onramp availability
10
46
  const { geoData } = useGetGeo();
11
47
  const { coinbaseOnrampOptions } = useCoinbaseOnrampOptions(true, geoData?.country || "US");
48
+ // Get recipient profile for displaying name
49
+ const recipientProfile = useProfile({ address: _recipientAddress });
50
+ const recipientName = recipientProfile.data?.name?.replace(/\.b3\.fun/g, "");
12
51
  const amountInputRef = useRef(null);
13
52
  const handleAmountChange = (e) => {
14
53
  // Only allow numbers and decimal points
@@ -26,14 +65,13 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, }) {
26
65
  const handleQuickAmount = (value) => {
27
66
  setSrcAmountOnRamp(value);
28
67
  };
29
- return (_jsxs("div", { className: "bg-as-on-surface-1 relative flex w-full flex-col gap-4 rounded-2xl p-4 pb-6", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-primary/50 flex items-center text-sm", children: "Buy" }), _jsx(PaymentOptions, {})] }), _jsxs("div", { className: "hover:bg-as-brand/30 hover:border-as-brand border-as-stroke relative flex w-full flex-col items-center justify-center rounded-lg border transition-all duration-200", children: [parseFloat(srcAmountOnRamp) >
30
- (coinbaseOnrampOptions?.paymentCurrencies?.[0]?.limits?.find(l => l.id === "ACH_BANK_ACCOUNT")?.max
31
- ? parseFloat(coinbaseOnrampOptions.paymentCurrencies[0].limits.find(l => l.id === "ACH_BANK_ACCOUNT")?.max || "25000")
32
- : 25000) ? (_jsxs("p", { className: "label-style -mb-3 mt-3 text-xs text-red-400 dark:bg-transparent", children: ["Maximum amount is $", coinbaseOnrampOptions?.paymentCurrencies?.[0]?.limits?.find(l => l.id === "ACH_BANK_ACCOUNT")?.max ||
33
- "25,000"] })) : (_jsx("p", { className: "label-style text-b3-react-foreground/60 -mb-3 mt-3 text-xs dark:bg-transparent", children: "Buy amount in USD" })), _jsxs("div", { className: "relative inline-flex items-center dark:bg-transparent", children: [_jsx("span", { className: "text-b3-react-foreground/60 -ms-3 -mt-2 text-2xl font-semibold dark:bg-transparent", children: "$" }), _jsx(Input, { ref: amountInputRef, type: "text", value: srcAmountOnRamp, onChange: handleAmountChange, placeholder: "0.00", className: "placeholder:text-b3-react-foreground/60 h-auto min-w-[70px] border-0 bg-transparent py-6 text-center text-4xl font-semibold focus-visible:ring-0 focus-visible:ring-offset-0 dark:bg-transparent", style: {
34
- width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
35
- minWidth: srcAmountOnRamp ? `auto` : "105px",
36
- } }), _jsx(AnimatePresence, { mode: "wait", children: _jsx(motion.div, { animate: { opacity: !srcAmountOnRamp || parseFloat(srcAmountOnRamp) <= 0 ? 1 : 0 }, exit: { opacity: 0 }, transition: { duration: 0.5, ease: "easeInOut" }, className: "border-b3-react-foreground/10 absolute bottom-3 left-1 h-1 w-[90%] rounded-full border-t-2 border-dashed bg-transparent" }) })] })] }), _jsx("div", { className: "grid grid-cols-4 gap-4", children: ["5", "10", "25", "100"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `rounded-lg border px-4 py-3 ${srcAmountOnRamp === value
37
- ? "border-as-brand bg-as-brand/30"
38
- : "border-as-stroke hover:border-as-brand hover:bg-as-brand/30"} transition-all duration-200`, children: ["$", value] }, value))) })] }));
68
+ return (_jsxs("div", { className: "bg-as-surface-primary flex w-full flex-col", children: [_jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm font-bold", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm", onClick: () => setActivePanel(7), children: selectedPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "C" }) }), "Coinbase Pay"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedPaymentMethod === FiatPaymentMethod.STRIPE ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "S" }) }), "Stripe"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { ref: amountInputRef, type: "text", value: srcAmountOnRamp, onChange: handleAmountChange, placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
69
+ width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
70
+ } })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "25", "100"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmountOnRamp === value
71
+ ? "border-as-border-secondary bg-as-surface-secondary"
72
+ : "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && (_jsx(OrderTokenAmountFiat, { address: _recipientAddress, context: "to", inputValue: destinationAmount || "0", onChangeInput: () => { }, chainId: destinationChainId, setChainId: onDestinationChainChange || (() => { }), token: destinationToken, setToken: onDestinationTokenChange || (() => { }) }))] }), _jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary mt-4 flex w-full flex-col gap-3 rounded-xl border p-4", children: [_jsxs("div", { className: "flex w-full items-center justify-between gap-2", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm", children: "Recipient" }), _recipientAddress ? (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-orange-500 text-xs text-white", children: "\uD83E\uDD8A" }), _jsx("span", { className: "text-sm", children: recipientName || shortenAddress(_recipientAddress) }), _jsx(ChevronRight, { size: 16 })] })) : (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx(Wallet, { className: "text-as-brand", size: 16 }), "Select recipient", _jsx(ChevronRight, { size: 16 })] }))] }), _jsx("div", { className: "divider w-full" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Expected to receive" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: [destinationAmount || "0", " ", destinationToken?.symbol || ""] }), _jsxs("span", { className: "text-as-tertiarry text-sm", children: ["on ", destinationChainId ? ALL_CHAINS[destinationChainId]?.name : ""] }), destinationToken && destinationChainId && destinationToken.metadata?.logoURI && (_jsx("img", { src: ALL_CHAINS[destinationChainId]?.logoUrl, alt: "Chain", className: "h-4 w-4 rounded-full" }))] })] }), _jsx("div", { className: "divider w-full" }), _jsx("div", { className: "", children: _jsx("div", { className: "flex items-center justify-between", children: (() => {
73
+ const currentPaymentMethod = selectedPaymentMethod || FiatPaymentMethod.NONE;
74
+ const fee = getFeeFromApi(currentPaymentMethod);
75
+ return (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total" }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(currentPaymentMethod).toFixed(2)] })] }));
76
+ })() }) })] })] }));
39
77
  }
@@ -5,7 +5,6 @@ import centerTruncate from "../../../../shared/utils/centerTruncate.js";
5
5
  import invariant from "invariant";
6
6
  import { ChevronLeft, ChevronRight, Landmark, Loader2 } from "lucide-react";
7
7
  import { motion } from "motion/react";
8
- import { useEffect, useRef, useState } from "react";
9
8
  import { toast } from "sonner";
10
9
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
11
10
  export function PanelOnrampPayment(props) {
@@ -14,17 +13,7 @@ export function PanelOnrampPayment(props) {
14
13
  }
15
14
  function PanelOnrampPaymentInner(props) {
16
15
  const { srcAmountOnRamp, recipientAddress, isMainnet, isBuyMode, destinationTokenChainId, destinationTokenAddress, selectedDstChainId, selectedDstToken, anyspendQuote, globalAddress, onOrderCreated, onBack, orderType, nft, tournament, payload, recipientEnsName, recipientImageUrl, } = props;
17
- // Use a stable amount for geo onramp options to prevent unnecessary refetches
18
- const [stableAmountForGeo, setStableAmountForGeo] = useState(srcAmountOnRamp);
19
- const hasInitialized = useRef(false);
20
- // Only update the stable amount on first render or when explicitly needed
21
- useEffect(() => {
22
- if (!hasInitialized.current && srcAmountOnRamp) {
23
- setStableAmountForGeo(srcAmountOnRamp);
24
- hasInitialized.current = true;
25
- }
26
- }, [srcAmountOnRamp]);
27
- const { geoData, coinbaseOnrampOptions, coinbaseAvailablePaymentMethods, isStripeOnrampSupported, stripeWeb2Support, isLoading: isLoadingGeoOnramp, } = useGeoOnrampOptions(isMainnet, stableAmountForGeo);
16
+ const { geoData, coinbaseOnrampOptions, coinbaseAvailablePaymentMethods, isStripeOnrampSupported, stripeWeb2Support, isLoading: isLoadingGeoOnramp, } = useGeoOnrampOptions(isMainnet, srcAmountOnRamp);
28
17
  const isLoading = isLoadingGeoOnramp;
29
18
  const { createOrder, isCreatingOrder } = useAnyspendCreateOnrampOrder({
30
19
  onSuccess: data => {
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { USDC_BASE } from "../../../../anyspend/index.js";
3
2
  import { STRIPE_CONFIG } from "../../../../anyspend/constants/index.js";
4
- import { useStripeClientSecret } from "../../../../anyspend/react/index.js";
5
- import { ShinyButton, useB3, useModalStore } from "../../../../global-account/react/index.js";
3
+ import { OrderDetailsCollapsible, useStripeClientSecret } from "../../../../anyspend/react/index.js";
4
+ import { ShinyButton, useB3, useModalStore, useProfile } from "../../../../global-account/react/index.js";
5
+ import { formatTokenAmount } from "../../../../shared/utils/number.js";
6
6
  import { formatStripeAmount } from "../../../../shared/utils/payment.utils.js";
7
7
  import { AddressElement, Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
8
8
  import { loadStripe } from "@stripe/stripe-js";
9
- import { HelpCircle, Info, X } from "lucide-react";
9
+ import { X } from "lucide-react";
10
10
  import { useEffect, useState } from "react";
11
11
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
12
12
  import HowItWorks from "./HowItWorks.js";
@@ -125,6 +125,8 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
125
125
  window.history.replaceState({}, "", url.toString());
126
126
  }
127
127
  }, [setB3ModalOpen]);
128
+ const profile = useProfile({ address: order.recipientAddress });
129
+ const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
128
130
  if (!stripeReady) {
129
131
  return _jsx(StripeLoadingState, {});
130
132
  }
@@ -152,12 +154,7 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
152
154
  description: "After payment confirmation, your order will be processed and completed automatically",
153
155
  },
154
156
  ];
155
- return (_jsxs("div", { className: "relative my-8 flex w-full flex-1 flex-col items-center justify-center", children: [_jsxs("form", { onSubmit: handleSubmit, className: "w-full space-y-6", children: [_jsxs("div", { className: "bg-as-on-surface-1 w-full rounded-2xl p-6", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "bg-as-brand/20 flex h-8 w-8 shrink-0 items-center justify-center rounded-full", children: _jsx("svg", { className: "text-as-brand h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }) }), _jsxs("div", { children: [_jsx("div", { className: "text-as-primary text-sm font-medium", children: "Secured by Stripe" }), _jsx("div", { className: "text-as-primary/50 text-xs", children: "End-to-end encrypted payment" })] })] }), _jsxs("button", { type: "button", onClick: () => setShowHowItWorks(true), className: "text-as-primary/60 hover:text-as-primary flex items-center gap-1 text-xs transition-colors", children: [_jsx(HelpCircle, { className: "h-4 w-4" }), _jsx("span", { children: "How it works" })] })] }), amount && (_jsxs("div", { className: "border-as-stroke border-t pt-4", children: [_jsx("div", { className: "text-as-primary/50 mb-3 text-sm", children: "Payment Breakdown" }), (() => {
156
- const originalAmount = Number(order.srcAmount) / 10 ** USDC_BASE.decimals;
157
- const finalAmount = Number(amount);
158
- const calculatedFee = finalAmount - originalAmount;
159
- return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "text-as-primary/60", children: "Amount" }), _jsxs("span", { className: "text-as-primary", children: ["$", originalAmount.toFixed(2)] })] }), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-as-primary/60", children: "Processing fee" }), _jsx(Tooltip, { content: `Credit card companies charge a processing fee of 5.4% + $0.30 for all transactions.\n\nThis fee covers secure payment processing and fraud protection.`, children: _jsx(Info, { className: "text-as-primary/40 hover:text-as-primary/60 h-3 w-3 transition-colors" }) })] }), _jsxs("span", { className: "text-as-primary", children: ["$", calculatedFee.toFixed(2)] })] }), _jsx("div", { className: "border-as-stroke border-t pt-2", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary font-semibold", children: "Total Amount" }), _jsxs("span", { className: "text-as-primary text-2xl font-bold", children: ["$", finalAmount.toFixed(2), " USD"] })] }) })] }));
160
- })()] }))] }), _jsxs("div", { className: "bg-as-on-surface-1 w-full rounded-2xl p-6", children: [_jsx("div", { className: "text-as-primary mb-4 text-lg font-semibold", children: "Payment Details" }), _jsx(PaymentElement, { onChange: handlePaymentElementChange, options: stripeElementOptions }), showAddressElement && (_jsx(AddressElement, { options: {
157
+ return (_jsxs("div", { className: "relative mt-1 flex w-full flex-1 flex-col items-center justify-center", children: [_jsxs("form", { onSubmit: handleSubmit, className: "w-full space-y-6", children: [_jsx(OrderDetailsCollapsible, { order: order, dstToken: order.metadata.dstToken, tournament: order.type === "join_tournament" || order.type === "fund_tournament" ? order.metadata.tournament : undefined, nft: order.type === "mint_nft" ? order.metadata.nft : undefined, recipientName: recipientName, formattedExpectedDstAmount: formatTokenAmount(BigInt(order.srcAmount), order.metadata.dstToken.decimals), showTotal: true, totalAmount: amount ? `$${Number(amount).toFixed(2)}` : undefined }), _jsxs("div", { className: "w-full", children: [_jsx("div", { className: "text-as-primary mb-4 text-lg font-semibold", children: "Payment Details" }), _jsx(PaymentElement, { onChange: handlePaymentElementChange, options: stripeElementOptions }), showAddressElement && (_jsx(AddressElement, { options: {
161
158
  mode: "billing",
162
159
  fields: {
163
160
  phone: "always",
@@ -174,8 +171,3 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
174
171
  },
175
172
  } }))] }), message && (_jsxs("div", { className: "bg-as-red/10 border-as-red/20 flex w-full items-center gap-3 rounded-2xl border p-4", children: [_jsx("div", { className: "bg-as-red flex h-6 w-6 shrink-0 items-center justify-center rounded-full", children: _jsx("svg", { className: "h-4 w-4 text-white", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }), _jsx("div", { className: "text-as-red text-sm font-medium", children: message })] })), _jsx(ShinyButton, { type: "submit", accentColor: "hsl(var(--as-brand))", disabled: !stripe || !elements || loading, className: "relative w-full py-4 text-lg font-semibold", children: loading ? (_jsxs("div", { className: "flex items-center justify-center gap-3", children: [_jsx("div", { className: "h-5 w-5 animate-spin rounded-full border-2 border-current border-t-transparent" }), _jsx("span", { className: "text-white", children: "Processing Payment..." })] })) : (_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx("span", { className: "text-white", children: "Complete Payment" }), amount && _jsxs("span", { className: "text-white/90", children: ["$", Number(amount).toFixed(2)] })] })) })] }), showHowItWorks && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: _jsxs("div", { className: "bg-as-on-surface-1 relative max-h-[80vh] w-full max-w-2xl overflow-y-auto rounded-2xl p-6", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsx("h2", { className: "text-as-primary text-xl font-semibold", children: "How it works" }), _jsx("button", { onClick: () => setShowHowItWorks(false), className: "text-as-primary/60 hover:text-as-primary transition-colors", children: _jsx(X, { className: "h-6 w-6" }) })] }), _jsxs("div", { className: "space-y-6", children: [_jsx(PaymentMethodIcons, {}), _jsx(HowItWorks, { steps: howItWorksSteps })] })] }) }))] }));
176
173
  }
177
- // Add tooltip component
178
- function Tooltip({ children, content }) {
179
- const [isVisible, setIsVisible] = useState(false);
180
- return (_jsxs("div", { className: "relative inline-block", children: [_jsx("div", { onMouseEnter: () => setIsVisible(true), onMouseLeave: () => setIsVisible(false), className: "cursor-help", children: children }), isVisible && (_jsx("div", { className: "absolute bottom-full left-1/2 z-50 mb-2 w-80 -translate-x-1/2", children: _jsxs("div", { className: "bg-as-on-surface-1 border-as-stroke text-as-primary rounded-lg border p-3 text-sm shadow-lg", children: [_jsx("div", { className: "whitespace-pre-line", children: content }), _jsx("div", { className: "absolute left-1/2 top-full -translate-x-1/2", children: _jsx("div", { className: "border-t-as-on-surface-1 border-l-4 border-r-4 border-t-4 border-transparent" }) })] }) }))] }));
181
- }
@@ -0,0 +1,11 @@
1
+ export interface Step {
2
+ id: string | number;
3
+ title: string;
4
+ description?: string;
5
+ }
6
+ export interface StepProgressProps {
7
+ steps: Step[];
8
+ currentStepIndex: number;
9
+ className?: string;
10
+ }
11
+ export declare function StepProgress({ steps, currentStepIndex, className }: StepProgressProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { motion } from "framer-motion";
4
+ import { CheckIcon } from "lucide-react";
5
+ export function StepProgress({ steps, currentStepIndex, className = "" }) {
6
+ const currentStep = steps[currentStepIndex];
7
+ return (_jsxs("div", { className: `flex w-full flex-col items-center gap-4 ${className}`, children: [_jsx("div", { className: "flex items-center gap-2", children: steps.map((step, index) => (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center", children: _jsx(motion.div, { initial: { scale: 0.8, opacity: 0 }, animate: { scale: 1, opacity: 1 }, transition: { delay: index * 0.2 }, className: `relative flex h-10 w-10 items-center justify-center rounded-full ${index < currentStepIndex
8
+ ? "bg-as-success-secondary" // Completed step
9
+ : index === currentStepIndex
10
+ ? "border-as-border-secondary border-[3px]" // Current step
11
+ : "border-as-border-secondary border-[3px]" // Future step
12
+ } `, children: index < currentStepIndex ? (
13
+ // Completed step - show check icon
14
+ _jsx(CheckIcon, { className: "text-as-content-icon-success h-6 w-6" })) : index === currentStepIndex ? (
15
+ // Current step - show spinning border and step number
16
+ _jsxs(_Fragment, { children: [_jsx("div", { className: "border-t-as-primary absolute -inset-0.5 animate-spin rounded-full border-[3px] border-transparent" }), _jsx("span", { className: "text-as-primary font-semibold", children: index + 1 })] })) : (
17
+ // Future step - show step number with disabled styling
18
+ _jsx("span", { className: "text-as-content-disabled font-semibold", children: index + 1 })) }) }, step.id), index < steps.length - 1 && (_jsx("div", { className: "flex w-8 items-center justify-center gap-1", children: Array.from({ length: 6 }).map((_, dotIndex) => (_jsx("div", { className: "bg-as-primary/30 h-[2px] w-[2px] rounded-full" }, dotIndex))) }))] }))) }), currentStep && (_jsxs(motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.3 }, className: "text-center", children: [_jsx("h2", { className: "text-as-primary text-xl font-semibold", children: currentStep.title }), currentStep.description && _jsx("p", { className: "text-as-primary/50 mt-1 text-sm", children: currentStep.description })] }))] }));
19
+ }
@@ -0,0 +1,16 @@
1
+ import { components } from "../../../../anyspend/types/api";
2
+ type Order = components["schemas"]["Order"];
3
+ type Token = components["schemas"]["Token"];
4
+ type Tournament = components["schemas"]["Tournament"];
5
+ type NFT = components["schemas"]["NFT"];
6
+ interface TransferCryptoDetailsProps {
7
+ order: Order;
8
+ srcToken: Token;
9
+ dstToken: Token;
10
+ tournament?: Tournament;
11
+ nft?: NFT;
12
+ onBack: () => void;
13
+ recipientName?: string;
14
+ }
15
+ export declare const TransferCryptoDetails: import("react").NamedExoticComponent<TransferCryptoDetailsProps>;
16
+ export {};
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ALL_CHAINS, getChainName, getPaymentUrl, RELAY_ETH_ADDRESS } from "../../../../anyspend/index.js";
4
+ import { CopyToClipboard, ShinyButton, TextLoop } from "../../../../global-account/react/index.js";
5
+ import { cn } from "../../../../shared/utils/index.js";
6
+ import { formatTokenAmount } from "../../../../shared/utils/number.js";
7
+ import { WalletCoinbase, WalletMetamask, WalletPhantom, WalletTrust } from "@web3icons/react";
8
+ import { ChevronLeft, Copy } from "lucide-react";
9
+ import { QRCodeSVG } from "qrcode.react";
10
+ import { memo, useEffect, useMemo, useState } from "react";
11
+ import { toast } from "sonner";
12
+ import { b3 } from "viem/chains";
13
+ import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible.js";
14
+ export const TransferCryptoDetails = memo(function TransferCryptoDetails({ order, srcToken, dstToken, tournament, nft, onBack, recipientName, }) {
15
+ const [timeLeft, setTimeLeft] = useState(0);
16
+ useEffect(() => {
17
+ const calculateTimeLeft = () => {
18
+ if (!order.expiredAt)
19
+ return 0;
20
+ const now = Date.now();
21
+ const expiredAt = new Date(order.expiredAt).getTime();
22
+ const diff = Math.max(0, Math.floor((expiredAt - now) / 1000));
23
+ return diff;
24
+ };
25
+ // Set initial time
26
+ setTimeLeft(calculateTimeLeft());
27
+ const timer = setInterval(() => {
28
+ setTimeLeft(calculateTimeLeft());
29
+ }, 1000);
30
+ return () => clearInterval(timer);
31
+ }, [order.expiredAt]);
32
+ const formatTime = (seconds) => {
33
+ const minutes = Math.floor(seconds / 60);
34
+ const remainingSeconds = seconds % 60;
35
+ return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
36
+ };
37
+ const totalTime = useMemo(() => {
38
+ if (!order.expiredAt)
39
+ return 15 * 60; // fallback to 15 minutes
40
+ const now = Date.now();
41
+ const expiredAt = new Date(order.expiredAt).getTime();
42
+ const createdAt = order.createdAt ? new Date(order.createdAt).getTime() : now;
43
+ return Math.max(0, Math.floor((expiredAt - createdAt) / 1000));
44
+ }, [order.expiredAt, order.createdAt]);
45
+ const roundedUpSrcAmount = useMemo(() => {
46
+ // Display the full transfer amount without rounding since users need to see the exact value they're transferring.
47
+ // Use 21 significant digits (max allowed by Intl.NumberFormat)
48
+ const formattedSrcAmount = srcToken
49
+ ? formatTokenAmount(BigInt(order.srcAmount), srcToken.decimals, 21, false)
50
+ : undefined;
51
+ // Simple function to round up the amount (you may need to implement this based on your utils)
52
+ return formattedSrcAmount;
53
+ }, [order.srcAmount, srcToken]);
54
+ const expectedDstAmount = order.type === "mint_nft" ||
55
+ order.type === "join_tournament" ||
56
+ order.type === "fund_tournament" ||
57
+ order.type === "custom"
58
+ ? "0"
59
+ : order.payload.expectedDstAmount.toString();
60
+ const formattedExpectedDstAmount = formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
61
+ const handleCopyAddress = () => {
62
+ navigator.clipboard.writeText(order.globalAddress);
63
+ toast.success("Deposit address copied to clipboard");
64
+ };
65
+ return (_jsxs("div", { className: "flex w-full flex-col gap-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("button", { onClick: onBack, className: "text-as-primary/60 hover:text-as-primary flex h-10 w-10 items-center justify-center rounded-full transition-colors", children: _jsx(ChevronLeft, { size: 24, className: "text-as-quaternary" }) }), _jsx("h2", { className: "text-as-primary text-lg font-semibold", children: "Transfer crypto" }), _jsxs("div", { className: "relative flex h-11 w-11 items-center justify-center", children: [_jsxs("svg", { className: "h-11 w-11 -rotate-90", viewBox: "0 0 44 44", children: [_jsx("circle", { cx: "22", cy: "22", r: "18", stroke: "currentColor", strokeWidth: "3", fill: "none", className: "text-gray-200" }), _jsx("circle", { cx: "22", cy: "22", r: "18", stroke: "currentColor", strokeWidth: "3", fill: "none", strokeLinecap: "round", className: "text-blue-500", strokeDasharray: `${2 * Math.PI * 18}`, strokeDashoffset: `${2 * Math.PI * 18 * (1 - timeLeft / totalTime)}`, style: {
66
+ transition: "stroke-dashoffset 1s linear",
67
+ } })] }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("span", { className: "text-as-primary text-[10px] font-semibold", children: formatTime(timeLeft) }) })] })] }), _jsxs("div", { className: "flex w-full flex-col gap-4", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Amount" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsx(CopyToClipboard, { text: roundedUpSrcAmount || "", onCopy: () => {
68
+ toast.success("Amount copied to clipboard");
69
+ }, children: _jsxs("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [_jsxs("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), _jsx(Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), _jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.srcChain].logoUrl, alt: getChainName(order.srcChain), className: cn("h-6 rounded-full", order.srcChain === b3.id && "h-5 rounded-none") }), _jsx("span", { className: "text-as-primary text-sm font-semibold", children: getChainName(order.srcChain) })] }) })] })] }), _jsxs("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [_jsx("div", { className: "border-as-border-primary h-full w-full border-r", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress), className: "bg-as-surface-secondary max-h-48 max-w-48" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), _jsxs("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), _jsxs("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [_jsx("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), _jsx("div", { className: "place-self-end", children: _jsx(Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), _jsx("div", { className: "flex flex-col gap-3", children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
70
+ });
@@ -10,11 +10,14 @@ export { AnySpendTournament } from "./AnySpendTournament";
10
10
  export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
11
11
  export { ChainTokenIcon } from "./common/ChainTokenIcon";
12
12
  export { OrderDetails } from "./common/OrderDetails";
13
+ export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
13
14
  export { OrderHistory } from "./common/OrderHistory";
14
15
  export { OrderHistoryItem } from "./common/OrderHistoryItem";
15
16
  export { OrderStatus } from "./common/OrderStatus";
16
17
  export { OrderToken } from "./common/OrderToken";
17
18
  export { OrderTokenAmount } from "./common/OrderTokenAmount";
19
+ export { StepProgress } from "./common/StepProgress";
18
20
  export { TokenBalance } from "./common/TokenBalance";
21
+ export { TransferCryptoDetails } from "./common/TransferCryptoDetails";
19
22
  export { WebviewOnrampOrderStatus } from "./webview/WebviewOnrampOrderStatus";
20
23
  export { WebviewOnrampPayment } from "./webview/WebviewOnrampPayment";
@@ -12,11 +12,14 @@ export { AnySpendNFTButton } from "./common/AnySpendNFTButton.js";
12
12
  // Common Components
13
13
  export { ChainTokenIcon } from "./common/ChainTokenIcon.js";
14
14
  export { OrderDetails } from "./common/OrderDetails.js";
15
+ export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible.js";
15
16
  export { OrderHistory } from "./common/OrderHistory.js";
16
17
  export { OrderHistoryItem } from "./common/OrderHistoryItem.js";
17
18
  export { OrderStatus } from "./common/OrderStatus.js";
18
19
  export { OrderToken } from "./common/OrderToken.js";
19
20
  export { OrderTokenAmount } from "./common/OrderTokenAmount.js";
21
+ export { StepProgress } from "./common/StepProgress.js";
20
22
  export { TokenBalance } from "./common/TokenBalance.js";
23
+ export { TransferCryptoDetails } from "./common/TransferCryptoDetails.js";
21
24
  export { WebviewOnrampOrderStatus } from "./webview/WebviewOnrampOrderStatus.js";
22
25
  export { WebviewOnrampPayment } from "./webview/WebviewOnrampPayment.js";
@@ -85,18 +85,9 @@ function StripePaymentForm({ order, onPaymentSuccess, }) {
85
85
  } }) })), error && (_jsx("div", { className: "mt-4 rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-600", children: error })), _jsx("button", { type: "submit", disabled: !stripe || isProcessing, className: "mt-6 w-full rounded-xl bg-blue-600 px-4 py-3 font-medium text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50", children: isProcessing ? (_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx(Loader2, { className: "h-5 w-5 animate-spin" }), _jsx("span", { children: "Processing..." })] })) : (_jsx("span", { children: "Complete Payment" })) })] }) }) }));
86
86
  }
87
87
  function WebviewOnrampPaymentInner({ srcAmountOnRamp, recipientAddress, destinationToken, anyspendQuote, onPaymentSuccess, userId, partnerId, }) {
88
- const [stableAmountForGeo, setStableAmountForGeo] = useState(srcAmountOnRamp);
89
- const hasInitialized = useRef(false);
90
88
  const [createdOrder, setCreatedOrder] = useState(null);
91
89
  const orderCreationAttempted = useRef(false);
92
- // Only update the stable amount on first render or when explicitly needed
93
- useEffect(() => {
94
- if (!hasInitialized.current && srcAmountOnRamp) {
95
- setStableAmountForGeo(srcAmountOnRamp);
96
- hasInitialized.current = true;
97
- }
98
- }, [srcAmountOnRamp]);
99
- const { geoData, stripeWeb2Support, isLoading: isLoadingGeoOnramp } = useGeoOnrampOptions(true, stableAmountForGeo);
90
+ const { geoData, stripeWeb2Support, isLoading: isLoadingGeoOnramp } = useGeoOnrampOptions(true, srcAmountOnRamp);
100
91
  const { createOrder, isCreatingOrder } = useAnyspendCreateOnrampOrder({
101
92
  onSuccess: data => {
102
93
  setCreatedOrder(data.data);
@@ -2,5 +2,6 @@ import { components } from "../../anyspend/types/api";
2
2
  export declare const getStatusDisplay: (order: components["schemas"]["Order"]) => {
3
3
  text: string;
4
4
  status: "processing" | "success" | "failure";
5
+ description?: string;
5
6
  };
6
7
  export declare const getErrorDisplay: (errorDetails: string) => string;
@@ -9,31 +9,44 @@ export const getStatusDisplay = (order) => {
9
9
  return {
10
10
  text: "Awaiting Payment",
11
11
  status: "processing",
12
+ description: "Complete your payment securely with Stripe to move forward",
12
13
  };
13
14
  case "expired":
14
- return { text: "Order Expired", status: "failure" };
15
+ return {
16
+ text: "Order Expired",
17
+ status: "failure",
18
+ description: "This order is no longer valid because the order expired.",
19
+ };
15
20
  case "sending_token_from_vault":
16
21
  return { text: "Sending Token", status: "processing" };
17
22
  case "relay":
18
- return { text: "Executing Order", status: "processing" };
23
+ return {
24
+ text: "Executing Order",
25
+ status: "processing",
26
+ description: "It will take approximately one minute to complete.",
27
+ };
19
28
  case "executed": {
20
- const text = order.type === "swap"
21
- ? "Swap Complete"
29
+ const { text, description } = order.type === "swap"
30
+ ? { text: "Swap Complete", description: "Your swap has been completed successfully." }
22
31
  : order.type === "mint_nft"
23
- ? "NFT Minted"
32
+ ? { text: "NFT Minted", description: "Your NFT has been minted" }
24
33
  : order.type === "join_tournament"
25
- ? "Tournament Joined"
34
+ ? { text: "Tournament Joined", description: "You have joined the tournament" }
26
35
  : order.type === "fund_tournament"
27
- ? "Tournament Funded"
28
- : "Order Complete";
29
- return { text, status: "success" };
36
+ ? { text: "Tournament Funded", description: "You have funded the tournament" }
37
+ : { text: "Order Complete", description: "Your order has been completed" };
38
+ return { text, status: "success", description };
30
39
  }
31
40
  case "refunding":
32
41
  return { text: "Order Refunding", status: "processing" };
33
42
  case "refunded":
34
43
  return { text: "Order Refunded", status: "failure" };
35
44
  case "failure":
36
- return { text: "Order Failure", status: "failure" };
45
+ return {
46
+ text: "Order Failure",
47
+ status: "failure",
48
+ description: "This order has failed. Please try again or contact support.",
49
+ };
37
50
  default:
38
51
  throw new Error("Invalid order status");
39
52
  }
@@ -11,3 +11,10 @@ export declare function escapeRegExp(string: string): string;
11
11
  * For example, roundUpUSDCBaseAmountToNearest("2663988") = "2670000"
12
12
  */
13
13
  export declare function roundUpUSDCBaseAmountToNearest(value: string): string;
14
+ /**
15
+ * Round up a USD amount to the nearest multiple of 0.01 USD
16
+ * @param value - The USD amount to round up
17
+ * @returns The rounded USD amount
18
+ * For example, roundUpUsdAmountToNearest("2.663988") = "2.67"
19
+ */
20
+ export declare function roundUpUsdAmountToNearest(value: string): string;
@@ -77,3 +77,20 @@ export function roundUpUSDCBaseAmountToNearest(value) {
77
77
  const res = srcAmountBig.plus(divisor.minus(remainder)).toString();
78
78
  return res;
79
79
  }
80
+ /**
81
+ * Round up a USD amount to the nearest multiple of 0.01 USD
82
+ * @param value - The USD amount to round up
83
+ * @returns The rounded USD amount
84
+ * For example, roundUpUsdAmountToNearest("2.663988") = "2.67"
85
+ */
86
+ export function roundUpUsdAmountToNearest(value) {
87
+ const divisor = new Big(0.01); // Round to nearest 0.01 USD
88
+ const srcAmountBig = new Big(value);
89
+ const remainder = srcAmountBig.mod(divisor);
90
+ // If remainder is already 0 (exactly divisible by 0.01), return the original amount
91
+ if (remainder.eq(0)) {
92
+ return value;
93
+ }
94
+ const res = srcAmountBig.plus(divisor.minus(remainder)).toString();
95
+ return res;
96
+ }