@b3dotfun/sdk 0.0.28-alpha.0 → 0.0.28-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/cjs/anyspend/abis/escrow.d.ts +987 -0
  2. package/dist/cjs/anyspend/abis/escrow.js +1275 -0
  3. package/dist/cjs/anyspend/react/components/AnySpend.js +10 -168
  4. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +2 -2
  5. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
  6. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +263 -0
  7. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
  8. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +53 -0
  9. package/dist/cjs/anyspend/react/components/common/ErrorSection.d.ts +6 -0
  10. package/dist/cjs/anyspend/react/components/common/ErrorSection.js +12 -0
  11. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
  12. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +2 -2
  13. package/dist/cjs/anyspend/react/components/common/PaySection.d.ts +20 -0
  14. package/dist/cjs/anyspend/react/components/common/PaySection.js +58 -0
  15. package/dist/cjs/anyspend/react/components/common/TabSection.d.ts +10 -0
  16. package/dist/cjs/anyspend/react/components/common/TabSection.js +18 -0
  17. package/dist/cjs/anyspend/react/components/index.d.ts +2 -0
  18. package/dist/cjs/anyspend/react/components/index.js +5 -1
  19. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
  20. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +184 -0
  21. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +2 -2
  22. package/dist/cjs/global-account/react/components/B3DynamicModal.js +3 -0
  23. package/dist/cjs/global-account/react/components/custom/Button.d.ts +1 -1
  24. package/dist/cjs/global-account/react/components/ui/button.d.ts +1 -1
  25. package/dist/cjs/global-account/react/components/ui/command.d.ts +2 -2
  26. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +17 -1
  27. package/dist/cjs/shared/constants/chains/b3Chain.d.ts +1 -1
  28. package/dist/cjs/shared/constants/chains/supported.d.ts +3 -3
  29. package/dist/esm/anyspend/abis/escrow.d.ts +987 -0
  30. package/dist/esm/anyspend/abis/escrow.js +1272 -0
  31. package/dist/esm/anyspend/react/components/AnySpend.js +12 -170
  32. package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -3
  33. package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
  34. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +257 -0
  35. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
  36. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +50 -0
  37. package/dist/esm/anyspend/react/components/common/ErrorSection.d.ts +6 -0
  38. package/dist/esm/anyspend/react/components/common/ErrorSection.js +9 -0
  39. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
  40. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +2 -2
  41. package/dist/esm/anyspend/react/components/common/PaySection.d.ts +20 -0
  42. package/dist/esm/anyspend/react/components/common/PaySection.js +55 -0
  43. package/dist/esm/anyspend/react/components/common/TabSection.d.ts +10 -0
  44. package/dist/esm/anyspend/react/components/common/TabSection.js +15 -0
  45. package/dist/esm/anyspend/react/components/index.d.ts +2 -0
  46. package/dist/esm/anyspend/react/components/index.js +2 -0
  47. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
  48. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +180 -0
  49. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +2 -2
  50. package/dist/esm/global-account/react/components/B3DynamicModal.js +3 -0
  51. package/dist/esm/global-account/react/components/custom/Button.d.ts +1 -1
  52. package/dist/esm/global-account/react/components/ui/button.d.ts +1 -1
  53. package/dist/esm/global-account/react/components/ui/command.d.ts +2 -2
  54. package/dist/esm/global-account/react/stores/useModalStore.d.ts +17 -1
  55. package/dist/esm/shared/constants/chains/b3Chain.d.ts +1 -1
  56. package/dist/esm/shared/constants/chains/supported.d.ts +3 -3
  57. package/dist/styles/index.css +1 -1
  58. package/dist/types/anyspend/abis/escrow.d.ts +987 -0
  59. package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
  60. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
  61. package/dist/types/anyspend/react/components/common/ErrorSection.d.ts +6 -0
  62. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
  63. package/dist/types/anyspend/react/components/common/PaySection.d.ts +20 -0
  64. package/dist/types/anyspend/react/components/common/TabSection.d.ts +10 -0
  65. package/dist/types/anyspend/react/components/index.d.ts +2 -0
  66. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
  67. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +2 -2
  68. package/dist/types/global-account/react/components/custom/Button.d.ts +1 -1
  69. package/dist/types/global-account/react/components/ui/button.d.ts +1 -1
  70. package/dist/types/global-account/react/components/ui/command.d.ts +2 -2
  71. package/dist/types/global-account/react/stores/useModalStore.d.ts +17 -1
  72. package/dist/types/shared/constants/chains/b3Chain.d.ts +1 -1
  73. package/dist/types/shared/constants/chains/supported.d.ts +3 -3
  74. package/package.json +1 -1
  75. package/src/anyspend/abis/escrow.ts +1272 -0
  76. package/src/anyspend/react/components/AnySpend.tsx +48 -389
  77. package/src/anyspend/react/components/AnySpendCustom.tsx +2 -10
  78. package/src/anyspend/react/components/AnyspendDepositHype.tsx +525 -0
  79. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +152 -0
  80. package/src/anyspend/react/components/common/ErrorSection.tsx +21 -0
  81. package/src/anyspend/react/components/common/PanelOnramp.tsx +4 -2
  82. package/src/anyspend/react/components/common/PaySection.tsx +222 -0
  83. package/src/anyspend/react/components/common/TabSection.tsx +58 -0
  84. package/src/anyspend/react/components/index.ts +2 -0
  85. package/src/anyspend/react/hooks/useAnyspendFlow.ts +226 -0
  86. package/src/global-account/react/components/B3DynamicModal.tsx +3 -0
  87. package/src/global-account/react/stores/useModalStore.ts +19 -1
@@ -21,6 +21,7 @@ export function PanelOnramp({
21
21
  destinationAmount,
22
22
  onDestinationTokenChange,
23
23
  onDestinationChainChange,
24
+ fiatPaymentMethodIndex,
24
25
  }: {
25
26
  srcAmountOnRamp: string;
26
27
  setSrcAmountOnRamp: (amount: string) => void;
@@ -32,6 +33,7 @@ export function PanelOnramp({
32
33
  destinationAmount?: string;
33
34
  onDestinationTokenChange?: (token: components["schemas"]["Token"]) => void;
34
35
  onDestinationChainChange?: (chainId: number) => void;
36
+ fiatPaymentMethodIndex: number;
35
37
  }) {
36
38
  // Get geo-based onramp options to access fee information
37
39
  const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
@@ -102,14 +104,14 @@ export function PanelOnramp({
102
104
  };
103
105
 
104
106
  return (
105
- <div className="bg-as-surface-primary flex w-full flex-col">
107
+ <div className="panel-onramp bg-as-surface-primary flex w-full flex-col">
106
108
  {/* Pay Section */}
107
109
  <div className="border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4">
108
110
  <div className="flex h-7 w-full items-center justify-between">
109
111
  <span className="text-as-tertiarry flex items-center text-sm font-bold">Pay</span>
110
112
  <button
111
113
  className="text-as-tertiarry flex h-7 items-center gap-1 text-sm"
112
- onClick={() => setActivePanel(7)} // PanelView.FIAT_PAYMENT_METHOD
114
+ onClick={() => setActivePanel(fiatPaymentMethodIndex)} // PanelView.FIAT_PAYMENT_METHOD
113
115
  >
114
116
  {selectedPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (
115
117
  <>
@@ -0,0 +1,222 @@
1
+ import { Input, useAccountWallet, useTokenData } from "@b3dotfun/sdk/global-account/react";
2
+ import { formatUsername } from "@b3dotfun/sdk/shared/utils";
3
+ import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
4
+ import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
5
+ import { ChevronRight } from "lucide-react";
6
+ import { motion } from "motion/react";
7
+ import { useEffect, useRef } from "react";
8
+ import { components } from "../../../types/api";
9
+ import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
10
+ import { FiatPaymentMethod } from "./FiatPaymentMethod";
11
+ import { OrderTokenAmount } from "./OrderTokenAmount";
12
+ import { TokenBalance } from "./TokenBalance";
13
+
14
+ interface PaySectionProps {
15
+ paymentType: "crypto" | "fiat";
16
+ // Token state
17
+ selectedSrcChainId: number;
18
+ setSelectedSrcChainId: (chainId: number) => void;
19
+ selectedSrcToken: components["schemas"]["Token"];
20
+ setSelectedSrcToken: (token: components["schemas"]["Token"]) => void;
21
+ srcAmount: string;
22
+ setSrcAmount: (amount: string) => void;
23
+ setIsSrcInputDirty: (dirty: boolean) => void;
24
+ // Payment method state
25
+ selectedCryptoPaymentMethod: CryptoPaymentMethodType;
26
+ selectedFiatPaymentMethod: FiatPaymentMethod;
27
+ onSelectCryptoPaymentMethod: () => void;
28
+ onSelectFiatPaymentMethod: () => void;
29
+ // Quote data
30
+ anyspendQuote?: any;
31
+ }
32
+
33
+ export function PaySection({
34
+ paymentType,
35
+ selectedSrcChainId,
36
+ setSelectedSrcChainId,
37
+ selectedSrcToken,
38
+ setSelectedSrcToken,
39
+ srcAmount,
40
+ setSrcAmount,
41
+ setIsSrcInputDirty,
42
+ selectedCryptoPaymentMethod,
43
+ selectedFiatPaymentMethod,
44
+ onSelectCryptoPaymentMethod,
45
+ onSelectFiatPaymentMethod,
46
+ anyspendQuote,
47
+ }: PaySectionProps) {
48
+ const { address: globalAddress, wallet: globalWallet, ensName: connectedName } = useAccountWallet();
49
+ const connectedAddress = globalWallet?.address;
50
+ const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
51
+
52
+ // Add ref to track if we've applied metadata
53
+ const appliedSrcMetadataRef = useRef(false);
54
+
55
+ // Update source token with metadata
56
+ useEffect(() => {
57
+ if (selectedSrcToken && srcTokenMetadata && !appliedSrcMetadataRef.current) {
58
+ // Mark as applied
59
+ appliedSrcMetadataRef.current = true;
60
+
61
+ const enhancedToken = {
62
+ ...selectedSrcToken,
63
+ decimals: srcTokenMetadata.decimals || selectedSrcToken.decimals,
64
+ symbol: srcTokenMetadata.symbol || selectedSrcToken.symbol,
65
+ name: srcTokenMetadata.name || selectedSrcToken.name,
66
+ metadata: {
67
+ ...selectedSrcToken.metadata,
68
+ logoURI: srcTokenMetadata?.logoURI || selectedSrcToken.metadata.logoURI,
69
+ },
70
+ };
71
+ setSelectedSrcToken(enhancedToken);
72
+ }
73
+ }, [srcTokenMetadata, selectedSrcToken, setSelectedSrcToken]);
74
+
75
+ // Reset source token ref when address/chain changes
76
+ useEffect(() => {
77
+ appliedSrcMetadataRef.current = false;
78
+ }, [selectedSrcToken.address, selectedSrcToken.chainId]);
79
+
80
+ return (
81
+ <motion.div
82
+ initial={{ opacity: 0, y: 20, filter: "blur(10px)" }}
83
+ animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
84
+ transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
85
+ className="bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6"
86
+ >
87
+ <div className="flex items-center justify-between">
88
+ <div className="text-as-primary/50 flex h-7 items-center text-sm">Pay</div>
89
+ {paymentType === "crypto" ? (
90
+ <button
91
+ className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors"
92
+ onClick={onSelectCryptoPaymentMethod}
93
+ >
94
+ {selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
95
+ <>
96
+ {globalAddress ? (
97
+ <div className="flex items-center gap-1">
98
+ {connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "")}
99
+ </div>
100
+ ) : (
101
+ "Connect wallet"
102
+ )}
103
+ <ChevronRight className="h-4 w-4" />
104
+ </>
105
+ ) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
106
+ <>
107
+ Transfer crypto
108
+ <ChevronRight className="h-4 w-4" />
109
+ </>
110
+ ) : (
111
+ <>
112
+ Select payment method
113
+ <ChevronRight className="h-4 w-4" />
114
+ </>
115
+ )}
116
+ </button>
117
+ ) : (
118
+ <button
119
+ className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors"
120
+ onClick={onSelectFiatPaymentMethod}
121
+ >
122
+ {selectedFiatPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (
123
+ <>
124
+ <div className="flex items-center gap-2">
125
+ <div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
126
+ <span className="text-xs font-bold text-white">C</span>
127
+ </div>
128
+ Coinbase Pay
129
+ </div>
130
+ <ChevronRight className="h-4 w-4" />
131
+ </>
132
+ ) : selectedFiatPaymentMethod === FiatPaymentMethod.STRIPE ? (
133
+ <>
134
+ <div className="flex items-center gap-2">
135
+ <div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
136
+ <span className="text-xs font-bold text-white">S</span>
137
+ </div>
138
+ Credit/Debit Card
139
+ </div>
140
+ <ChevronRight className="h-4 w-4" />
141
+ </>
142
+ ) : (
143
+ <>
144
+ Select payment method
145
+ <ChevronRight className="h-4 w-4" />
146
+ </>
147
+ )}
148
+ </button>
149
+ )}
150
+ </div>
151
+ {paymentType === "crypto" ? (
152
+ <>
153
+ <OrderTokenAmount
154
+ address={globalAddress}
155
+ context="from"
156
+ inputValue={srcAmount}
157
+ onChangeInput={value => {
158
+ setIsSrcInputDirty(true);
159
+ setSrcAmount(value);
160
+ }}
161
+ chainId={selectedSrcChainId}
162
+ setChainId={setSelectedSrcChainId}
163
+ token={selectedSrcToken}
164
+ setToken={setSelectedSrcToken}
165
+ />
166
+ <div className="flex items-center justify-between">
167
+ <div className="text-as-primary/50 flex h-5 items-center text-sm">
168
+ {formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
169
+ style: "currency",
170
+ fallback: "",
171
+ })}
172
+ </div>
173
+ <TokenBalance
174
+ token={selectedSrcToken}
175
+ walletAddress={globalAddress}
176
+ onChangeInput={value => {
177
+ setIsSrcInputDirty(true);
178
+ setSrcAmount(value);
179
+ }}
180
+ />
181
+ </div>
182
+ </>
183
+ ) : (
184
+ <>
185
+ {/* Fiat amount input - styled like PanelOnramp */}
186
+ <div className="flex items-center justify-center pb-2 pt-8">
187
+ <div className="flex gap-1">
188
+ <span className="text-as-tertiarry text-2xl font-bold">$</span>
189
+ <Input
190
+ type="text"
191
+ value={srcAmount}
192
+ onChange={e => setSrcAmount(e.target.value.replace(/[^0-9.]/g, ""))}
193
+ placeholder="5"
194
+ 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"
195
+ style={{
196
+ width: `${Math.max(50, srcAmount.length * 34)}px`,
197
+ }}
198
+ />
199
+ </div>
200
+ </div>
201
+
202
+ {/* Quick Amount Buttons */}
203
+ <div className="mx-auto mb-6 inline-grid grid-cols-4 gap-2">
204
+ {["5", "10", "20", "25"].map(value => (
205
+ <button
206
+ key={value}
207
+ onClick={() => setSrcAmount(value)}
208
+ 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 ${
209
+ srcAmount === value
210
+ ? "border-as-border-secondary bg-as-surface-secondary"
211
+ : "bg-as-surface-secondary hover:bg-as-surface-secondary"
212
+ }`}
213
+ >
214
+ ${value}
215
+ </button>
216
+ ))}
217
+ </div>
218
+ </>
219
+ )}
220
+ </motion.div>
221
+ );
222
+ }
@@ -0,0 +1,58 @@
1
+ import { cn } from "@b3dotfun/sdk/shared/utils/cn";
2
+ import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
3
+ import { FiatPaymentMethod } from "./FiatPaymentMethod";
4
+
5
+ interface TabSectionProps {
6
+ activeTab: "crypto" | "fiat";
7
+ setActiveTab: (tab: "crypto" | "fiat") => void;
8
+ setSelectedCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
9
+ setSelectedFiatPaymentMethod: (method: FiatPaymentMethod) => void;
10
+ }
11
+
12
+ export function TabSection({
13
+ activeTab,
14
+ setActiveTab,
15
+ setSelectedCryptoPaymentMethod,
16
+ setSelectedFiatPaymentMethod,
17
+ }: TabSectionProps) {
18
+ return (
19
+ <div className="tab-section w-full">
20
+ <div className="bg-as-surface-secondary relative mb-4 grid h-10 grid-cols-2 rounded-xl">
21
+ <div
22
+ className={cn(
23
+ "bg-as-brand absolute bottom-0 left-0 top-0 z-0 rounded-xl transition-transform duration-100",
24
+ "h-full w-1/2",
25
+ activeTab === "fiat" ? "translate-x-full" : "translate-x-0",
26
+ )}
27
+ style={{ willChange: "transform" }}
28
+ />
29
+ <button
30
+ className={cn(
31
+ "relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100",
32
+ activeTab === "crypto" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent",
33
+ )}
34
+ onClick={() => {
35
+ setActiveTab("crypto");
36
+ setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset payment method when switching to crypto
37
+ setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE); // Reset fiat payment method when switching to crypto
38
+ }}
39
+ >
40
+ Pay with crypto
41
+ </button>
42
+ <button
43
+ className={cn(
44
+ "relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100",
45
+ activeTab === "fiat" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent",
46
+ )}
47
+ onClick={() => {
48
+ setActiveTab("fiat");
49
+ setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset crypto payment method when switching to fiat
50
+ setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE); // Reset fiat payment method when switching to fiat
51
+ }}
52
+ >
53
+ Pay with Fiat
54
+ </button>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
@@ -12,6 +12,7 @@ export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
12
12
 
13
13
  // Common Components
14
14
  export { ChainTokenIcon } from "./common/ChainTokenIcon";
15
+ export { CryptoReceiveSection } from "./common/CryptoReceiveSection";
15
16
  export { OrderDetails } from "./common/OrderDetails";
16
17
  export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
17
18
  export { OrderHistory } from "./common/OrderHistory";
@@ -19,6 +20,7 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem";
19
20
  export { OrderStatus } from "./common/OrderStatus";
20
21
  export { OrderToken } from "./common/OrderToken";
21
22
  export { OrderTokenAmount } from "./common/OrderTokenAmount";
23
+ export { PaySection } from "./common/PaySection";
22
24
  export { RecipientSelection } from "./common/RecipientSelection";
23
25
  export { StepProgress } from "./common/StepProgress";
24
26
  export { TokenBalance } from "./common/TokenBalance";
@@ -0,0 +1,226 @@
1
+ import { B3_TOKEN, getDefaultToken, USDC_BASE } from "@b3dotfun/sdk/anyspend";
2
+ import {
3
+ useAnyspendCreateOnrampOrder,
4
+ useAnyspendCreateOrder,
5
+ useAnyspendOrderAndTransactions,
6
+ useAnyspendQuote,
7
+ useGeoOnrampOptions,
8
+ } from "@b3dotfun/sdk/anyspend/react";
9
+ import { anyspendService } from "@b3dotfun/sdk/anyspend/services/anyspend";
10
+ import { useAccountWallet, useProfile } from "@b3dotfun/sdk/global-account/react";
11
+ import { formatTokenAmount, formatUnits } from "@b3dotfun/sdk/shared/utils/number";
12
+ import { useEffect, useState } from "react";
13
+ import { toast } from "sonner";
14
+ import { parseUnits } from "viem";
15
+ import { base, mainnet } from "viem/chains";
16
+ import { components } from "../../types/api";
17
+ import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
18
+ import { FiatPaymentMethod } from "../components/common/FiatPaymentMethod";
19
+
20
+ export enum PanelView {
21
+ MAIN,
22
+ CRYPTO_PAYMENT_METHOD,
23
+ FIAT_PAYMENT_METHOD,
24
+ RECIPIENT_SELECTION,
25
+ ORDER_DETAILS,
26
+ LOADING,
27
+ }
28
+
29
+ interface UseAnyspendFlowProps {
30
+ paymentType?: "crypto" | "fiat";
31
+ recipientAddress?: string;
32
+ loadOrder?: string;
33
+ isDepositMode?: boolean;
34
+ onOrderSuccess?: (orderId: string) => void;
35
+ onTransactionSuccess?: () => void;
36
+ sourceTokenAddress?: string;
37
+ sourceTokenChainId?: number;
38
+ }
39
+
40
+ export function useAnyspendFlow({
41
+ paymentType = "crypto",
42
+ recipientAddress,
43
+ loadOrder,
44
+ isDepositMode = false,
45
+ onOrderSuccess,
46
+ onTransactionSuccess,
47
+ sourceTokenAddress,
48
+ sourceTokenChainId,
49
+ }: UseAnyspendFlowProps) {
50
+ // Panel and order state
51
+ const [activePanel, setActivePanel] = useState<PanelView>(loadOrder ? PanelView.ORDER_DETAILS : PanelView.MAIN);
52
+ const [orderId, setOrderId] = useState<string | undefined>(loadOrder);
53
+ const { orderAndTransactions: oat } = useAnyspendOrderAndTransactions(orderId);
54
+
55
+ // Token selection state - use provided sourceTokenChainId if available
56
+ const [selectedSrcChainId, setSelectedSrcChainId] = useState<number>(
57
+ sourceTokenChainId || (paymentType === "fiat" ? base.id : mainnet.id),
58
+ );
59
+ const [selectedDstChainId, setSelectedDstChainId] = useState<number>(base.id); // Default to Base for cross-chain swaps
60
+ const defaultSrcToken = paymentType === "fiat" ? USDC_BASE : getDefaultToken(selectedSrcChainId);
61
+ const [selectedSrcToken, setSelectedSrcToken] = useState<components["schemas"]["Token"]>(defaultSrcToken);
62
+ const [srcAmount, setSrcAmount] = useState<string>(paymentType === "fiat" ? "5" : "0.1");
63
+ const [dstAmount, setDstAmount] = useState<string>("");
64
+ const [isSrcInputDirty, setIsSrcInputDirty] = useState(true);
65
+
66
+ // Payment method state
67
+ const [selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod] = useState<CryptoPaymentMethodType>(
68
+ CryptoPaymentMethodType.NONE,
69
+ );
70
+ const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(FiatPaymentMethod.NONE);
71
+
72
+ // Recipient state
73
+ const { address: globalAddress } = useAccountWallet();
74
+ const [selectedRecipientAddress, setSelectedRecipientAddress] = useState<string | undefined>(recipientAddress);
75
+ const recipientProfile = useProfile({ address: selectedRecipientAddress, fresh: true });
76
+ const recipientName = recipientProfile.data?.name;
77
+
78
+ // Set default recipient address when wallet changes
79
+ useEffect(() => {
80
+ if (!selectedRecipientAddress && globalAddress) {
81
+ setSelectedRecipientAddress(globalAddress);
82
+ }
83
+ }, [selectedRecipientAddress, globalAddress]);
84
+
85
+ // Fetch specific token when sourceTokenAddress and sourceTokenChainId are provided
86
+ useEffect(() => {
87
+ const fetchSourceToken = async () => {
88
+ if (sourceTokenAddress && sourceTokenChainId) {
89
+ try {
90
+ const token = await anyspendService.getToken(sourceTokenChainId, sourceTokenAddress);
91
+ setSelectedSrcToken(token);
92
+ } catch (error) {
93
+ console.error("Failed to fetch source token:", error);
94
+ toast.error(`Failed to load token ${sourceTokenAddress} on chain ${sourceTokenChainId}`);
95
+ // Keep the default token on error
96
+ }
97
+ }
98
+ };
99
+
100
+ fetchSourceToken();
101
+ }, [sourceTokenAddress, sourceTokenChainId]);
102
+
103
+ // Helper function for onramp vendor mapping
104
+ const getOnrampVendor = (paymentMethod: FiatPaymentMethod): "coinbase" | "stripe" | "stripe-web2" | undefined => {
105
+ switch (paymentMethod) {
106
+ case FiatPaymentMethod.COINBASE_PAY:
107
+ return "coinbase";
108
+ case FiatPaymentMethod.STRIPE:
109
+ return "stripe-web2";
110
+ default:
111
+ return undefined;
112
+ }
113
+ };
114
+
115
+ // Get quote
116
+ const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals).toString();
117
+ const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote({
118
+ srcChain: paymentType === "fiat" ? base.id : selectedSrcChainId,
119
+ dstChain: isDepositMode ? base.id : selectedDstChainId, // For deposits, always Base; for swaps, use selected destination
120
+ srcTokenAddress: paymentType === "fiat" ? USDC_BASE.address : selectedSrcToken.address,
121
+ dstTokenAddress: isDepositMode ? B3_TOKEN.address : selectedSrcToken.address, // For deposits, always B3
122
+ type: "swap",
123
+ tradeType: "EXACT_INPUT",
124
+ amount: activeInputAmountInWei,
125
+ onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
126
+ });
127
+
128
+ // Get geo options for fiat
129
+ const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(
130
+ paymentType === "fiat" ? formatUnits(activeInputAmountInWei, USDC_BASE.decimals) : "0",
131
+ );
132
+
133
+ // Update destination amount when quote changes
134
+ useEffect(() => {
135
+ if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
136
+ const amount = anyspendQuote.data.currencyOut.amount;
137
+ const decimals = anyspendQuote.data.currencyOut.currency.decimals;
138
+ const formattedAmount = formatTokenAmount(BigInt(amount), decimals, 6, false);
139
+ setDstAmount(formattedAmount);
140
+ } else {
141
+ setDstAmount("");
142
+ }
143
+ }, [anyspendQuote]);
144
+
145
+ // Order creation hooks
146
+ const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
147
+ onSuccess: data => {
148
+ const newOrderId = data.data.id;
149
+ setOrderId(newOrderId);
150
+ setActivePanel(PanelView.ORDER_DETAILS);
151
+ onOrderSuccess?.(newOrderId);
152
+ },
153
+ onError: error => {
154
+ console.error(error);
155
+ toast.error("Failed to create order: " + error.message);
156
+ },
157
+ });
158
+
159
+ const { createOrder: createOnrampOrder, isCreatingOrder: isCreatingOnrampOrder } = useAnyspendCreateOnrampOrder({
160
+ onSuccess: data => {
161
+ const newOrderId = data.data.id;
162
+ setOrderId(newOrderId);
163
+ setActivePanel(PanelView.ORDER_DETAILS);
164
+ onOrderSuccess?.(newOrderId);
165
+ },
166
+ onError: error => {
167
+ console.error(error);
168
+ toast.error("Failed to create order: " + error.message);
169
+ },
170
+ });
171
+
172
+ // Handle order completion
173
+ useEffect(() => {
174
+ if (oat?.data?.order.status === "executed") {
175
+ console.log("Order executed successfully");
176
+ onTransactionSuccess?.();
177
+ }
178
+ }, [oat?.data?.order.status, onTransactionSuccess]);
179
+
180
+ return {
181
+ // State
182
+ activePanel,
183
+ setActivePanel,
184
+ orderId,
185
+ setOrderId,
186
+ oat,
187
+ // Token state
188
+ selectedSrcChainId,
189
+ setSelectedSrcChainId,
190
+ selectedDstChainId,
191
+ setSelectedDstChainId,
192
+ selectedSrcToken,
193
+ setSelectedSrcToken,
194
+ srcAmount,
195
+ setSrcAmount,
196
+ dstAmount,
197
+ setDstAmount,
198
+ isSrcInputDirty,
199
+ setIsSrcInputDirty,
200
+ // Payment methods
201
+ selectedCryptoPaymentMethod,
202
+ setSelectedCryptoPaymentMethod,
203
+ selectedFiatPaymentMethod,
204
+ setSelectedFiatPaymentMethod,
205
+ // Recipient
206
+ selectedRecipientAddress,
207
+ setSelectedRecipientAddress,
208
+ recipientName,
209
+ globalAddress,
210
+ // Quote data
211
+ anyspendQuote,
212
+ isLoadingAnyspendQuote,
213
+ getAnyspendQuoteError,
214
+ activeInputAmountInWei,
215
+ // Geo/onramp data
216
+ geoData,
217
+ coinbaseAvailablePaymentMethods,
218
+ stripeWeb2Support,
219
+ getOnrampVendor,
220
+ // Order creation
221
+ createOrder,
222
+ isCreatingOrder,
223
+ createOnrampOrder,
224
+ isCreatingOnrampOrder,
225
+ };
226
+ }
@@ -8,6 +8,7 @@ import {
8
8
  AnySpendTournament,
9
9
  OrderHistory,
10
10
  } from "@b3dotfun/sdk/anyspend/react";
11
+ import { AnySpendDepositHype } from "@b3dotfun/sdk/anyspend/react/components/AnyspendDepositHype";
11
12
  import { useIsMobile, useModalStore } from "@b3dotfun/sdk/global-account/react";
12
13
  import { cn } from "@b3dotfun/sdk/shared/utils/cn";
13
14
  import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
@@ -107,6 +108,8 @@ export function B3DynamicModal() {
107
108
  return <AnySpendBondKit {...contentType} />;
108
109
  case "linkAccount":
109
110
  return <LinkAccount {...contentType} />;
111
+ case "anySpendDepositHype":
112
+ return <AnySpendDepositHype {...contentType} mode="modal" />;
110
113
  // Add other modal types here
111
114
  default:
112
115
  return null;
@@ -305,6 +305,23 @@ export interface LinkAccountModalProps extends BaseModalProps {
305
305
  chain: Chain;
306
306
  }
307
307
 
308
+ export interface AnySpendDepositHypeProps extends BaseModalProps {
309
+ /** Modal type identifier */
310
+ type: "anySpendDepositHype";
311
+ /** Recipient address to receive the tokens */
312
+ recipientAddress: string;
313
+ /** Destination token address */
314
+ sourceTokenAddress?: string;
315
+ /** Source token chain ID */
316
+ sourceTokenChainId?: number;
317
+ /** Payment type - crypto or fiat */
318
+ paymentType?: "crypto" | "fiat";
319
+ /** Deposit contract address */
320
+ depositContractAddress: string;
321
+ /** Callback function called when the deposit is successful */
322
+ onSuccess?: () => void;
323
+ }
324
+
308
325
  /**
309
326
  * Union type of all possible modal content types
310
327
  */
@@ -323,7 +340,8 @@ export type ModalContentType =
323
340
  | AnySpendBuySpinProps
324
341
  | AnySpendSignatureMintProps
325
342
  | AnySpendBondKitProps
326
- | LinkAccountModalProps;
343
+ | LinkAccountModalProps
344
+ | AnySpendDepositHypeProps;
327
345
  // Add other modal types here like: | OtherModalProps | AnotherModalProps
328
346
 
329
347
  /**