@b3dotfun/sdk 0.0.20 → 0.0.21-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 (152) hide show
  1. package/README.md +28 -0
  2. package/dist/cjs/anyspend/index.native.d.ts +0 -2
  3. package/dist/cjs/anyspend/index.native.js +0 -4
  4. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +3 -3
  5. package/dist/cjs/anyspend/react/components/AnySpend.js +43 -55
  6. package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +1 -1
  7. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +159 -84
  8. package/dist/cjs/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
  9. package/dist/cjs/anyspend/react/components/AnySpendFingerprintWrapper.js +2 -5
  10. package/dist/cjs/anyspend/react/components/AnySpendNFT.js +1 -1
  11. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +1 -1
  12. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
  13. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +50 -102
  14. package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +1 -1
  15. package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +2 -2
  16. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +7 -9
  17. package/dist/cjs/anyspend/react/components/common/OrderStatus.js +2 -2
  18. package/dist/cjs/anyspend/react/components/common/PaymentStripeWeb2.js +1 -3
  19. package/dist/cjs/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
  20. package/dist/cjs/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
  21. package/dist/cjs/anyspend/react/components/common/RecipientSelection.example.js +27 -0
  22. package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +36 -0
  23. package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
  24. package/dist/cjs/anyspend/react/components/index.d.ts +1 -0
  25. package/dist/cjs/anyspend/react/components/index.js +3 -1
  26. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  27. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  28. package/dist/cjs/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
  29. package/dist/cjs/anyspend/react/hooks/useConnectedUserProfile.js +25 -0
  30. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +5 -5
  31. package/dist/cjs/anyspend/react/index.d.ts +1 -1
  32. package/dist/cjs/anyspend/react/index.js +1 -1
  33. package/dist/cjs/anyspend/react/providers/index.d.ts +2 -0
  34. package/dist/cjs/anyspend/react/providers/index.js +18 -0
  35. package/dist/cjs/anyspend/types/api.d.ts +35 -56
  36. package/dist/cjs/anyspend/utils/chain.d.ts +1 -1
  37. package/dist/cjs/anyspend/utils/chain.js +122 -15
  38. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
  39. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -2
  40. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -0
  41. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -1
  42. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +3 -0
  43. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +4 -1
  44. package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
  45. package/dist/cjs/global-account/react/hooks/useAuthentication.js +4 -1
  46. package/dist/cjs/global-account/react/hooks/useProfile.d.ts +2 -1
  47. package/dist/cjs/global-account/react/hooks/useProfile.js +9 -7
  48. package/dist/cjs/shared/constants/index.js +5 -3
  49. package/dist/cjs/shared/utils/formatUsername.d.ts +1 -1
  50. package/dist/cjs/shared/utils/formatUsername.js +3 -1
  51. package/dist/esm/anyspend/index.native.d.ts +0 -2
  52. package/dist/esm/anyspend/index.native.js +0 -4
  53. package/dist/esm/anyspend/react/components/AnySpend.d.ts +3 -3
  54. package/dist/esm/anyspend/react/components/AnySpend.js +46 -58
  55. package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +1 -1
  56. package/dist/esm/anyspend/react/components/AnySpendCustom.js +163 -88
  57. package/dist/esm/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
  58. package/dist/esm/anyspend/react/components/AnySpendFingerprintWrapper.js +2 -5
  59. package/dist/esm/anyspend/react/components/AnySpendNFT.js +1 -1
  60. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +1 -1
  61. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
  62. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +52 -104
  63. package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +1 -1
  64. package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +2 -2
  65. package/dist/esm/anyspend/react/components/common/OrderDetails.js +8 -10
  66. package/dist/esm/anyspend/react/components/common/OrderStatus.js +2 -2
  67. package/dist/esm/anyspend/react/components/common/PaymentStripeWeb2.js +1 -3
  68. package/dist/esm/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
  69. package/dist/esm/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
  70. package/dist/esm/anyspend/react/components/common/RecipientSelection.example.js +22 -0
  71. package/dist/esm/anyspend/react/components/common/RecipientSelection.js +33 -0
  72. package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
  73. package/dist/esm/anyspend/react/components/index.d.ts +1 -0
  74. package/dist/esm/anyspend/react/components/index.js +1 -0
  75. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  76. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  77. package/dist/esm/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
  78. package/dist/esm/anyspend/react/hooks/useConnectedUserProfile.js +22 -0
  79. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +5 -5
  80. package/dist/esm/anyspend/react/index.d.ts +1 -1
  81. package/dist/esm/anyspend/react/index.js +1 -1
  82. package/dist/esm/anyspend/react/providers/index.d.ts +2 -0
  83. package/dist/esm/anyspend/react/providers/index.js +2 -0
  84. package/dist/esm/anyspend/types/api.d.ts +35 -56
  85. package/dist/esm/anyspend/utils/chain.d.ts +1 -1
  86. package/dist/esm/anyspend/utils/chain.js +122 -15
  87. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
  88. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
  89. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -0
  90. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +2 -2
  91. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +4 -1
  92. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +4 -1
  93. package/dist/esm/global-account/react/hooks/index.d.ts +1 -1
  94. package/dist/esm/global-account/react/hooks/useAuthentication.js +4 -1
  95. package/dist/esm/global-account/react/hooks/useProfile.d.ts +2 -1
  96. package/dist/esm/global-account/react/hooks/useProfile.js +9 -7
  97. package/dist/esm/shared/constants/index.js +5 -3
  98. package/dist/esm/shared/utils/formatUsername.d.ts +1 -1
  99. package/dist/esm/shared/utils/formatUsername.js +3 -1
  100. package/dist/styles/index.css +1 -1
  101. package/dist/types/anyspend/index.native.d.ts +0 -2
  102. package/dist/types/anyspend/react/components/AnySpend.d.ts +3 -3
  103. package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +1 -1
  104. package/dist/types/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
  105. package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
  106. package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +2 -2
  107. package/dist/types/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
  108. package/dist/types/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
  109. package/dist/types/anyspend/react/components/index.d.ts +1 -0
  110. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  111. package/dist/types/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
  112. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +5 -5
  113. package/dist/types/anyspend/react/index.d.ts +1 -1
  114. package/dist/types/anyspend/react/providers/index.d.ts +2 -0
  115. package/dist/types/anyspend/types/api.d.ts +35 -56
  116. package/dist/types/anyspend/utils/chain.d.ts +1 -1
  117. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
  118. package/dist/types/global-account/react/hooks/index.d.ts +1 -1
  119. package/dist/types/global-account/react/hooks/useProfile.d.ts +2 -1
  120. package/dist/types/shared/utils/formatUsername.d.ts +1 -1
  121. package/package.json +2 -2
  122. package/src/anyspend/index.native.ts +0 -6
  123. package/src/anyspend/react/components/AnySpend.tsx +110 -134
  124. package/src/anyspend/react/components/AnySpendCustom.tsx +488 -196
  125. package/src/anyspend/react/components/AnySpendFingerprintWrapper.tsx +4 -8
  126. package/src/anyspend/react/components/AnySpendNFT.tsx +1 -1
  127. package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +1 -1
  128. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +76 -108
  129. package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +1 -1
  130. package/src/anyspend/react/components/common/OrderDetails.tsx +12 -13
  131. package/src/anyspend/react/components/common/OrderStatus.tsx +2 -2
  132. package/src/anyspend/react/components/common/PaymentStripeWeb2.tsx +1 -3
  133. package/src/anyspend/react/components/common/RecipientSelection.example.tsx +52 -0
  134. package/src/anyspend/react/components/common/RecipientSelection.tsx +146 -0
  135. package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +1 -0
  136. package/src/anyspend/react/components/index.ts +1 -0
  137. package/src/anyspend/react/hooks/index.ts +1 -0
  138. package/src/anyspend/react/hooks/useConnectedUserProfile.ts +26 -0
  139. package/src/anyspend/react/index.ts +1 -1
  140. package/src/anyspend/react/providers/index.ts +2 -0
  141. package/src/anyspend/types/api.ts +37 -58
  142. package/src/anyspend/utils/chain.ts +126 -18
  143. package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -1
  144. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +2 -0
  145. package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +2 -2
  146. package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +4 -1
  147. package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +4 -1
  148. package/src/global-account/react/hooks/index.ts +1 -1
  149. package/src/global-account/react/hooks/useAuthentication.ts +4 -2
  150. package/src/global-account/react/hooks/useProfile.ts +10 -5
  151. package/src/shared/constants/index.ts +5 -3
  152. package/src/shared/utils/formatUsername.ts +3 -2
@@ -44,16 +44,12 @@ export function AnySpendFingerprintWrapper({ children, fingerprint }: AnySpendFi
44
44
  );
45
45
  }
46
46
 
47
- // Helper function to get fingerprint config from environment variables
48
- export function getFingerprintConfig(): FingerprintConfig | undefined {
49
- const apiKey = process.env.NEXT_PUBLIC_FINGERPRINT_API_KEY;
50
-
51
- if (!apiKey) {
52
- return undefined;
53
- }
47
+ const defaultApiKey = "80EnsS6POsxPAR9xGxmN";
54
48
 
49
+ // Helper function to get fingerprint config from environment variables
50
+ export function getFingerprintConfig(): FingerprintConfig {
55
51
  return {
56
- apiKey,
52
+ apiKey: process.env.NEXT_PUBLIC_FINGERPRINT_API_KEY || defaultApiKey,
57
53
  endpoint: process.env.NEXT_PUBLIC_FINGERPRINT_ENDPOINT,
58
54
  scriptUrlPattern: process.env.NEXT_PUBLIC_FINGERPRINT_SCRIPT_URL,
59
55
  };
@@ -123,7 +123,7 @@ export function AnySpendNFT({
123
123
 
124
124
  <DropdownMenu nftContract={nftContract} />
125
125
  </div>
126
- <div className="from-b3-react-background to-as-on-surface-1 mt-[-100px] w-full rounded-t-lg bg-gradient-to-t">
126
+ <div className="from-b3-react-background to-as-on-surface-1 -mb-5 mt-[-100px] w-full rounded-t-lg bg-gradient-to-t">
127
127
  <div className="h-[100px] w-full" />
128
128
  <div className="mb-1 flex w-full flex-col items-center gap-2 p-5">
129
129
  <span className="font-sf-rounded text-2xl font-semibold">{nftContract.name}</span>
@@ -87,7 +87,7 @@ export default function ConnectWalletPayment({
87
87
  <ShinyButton
88
88
  accentColor={"hsl(var(--as-brand))"}
89
89
  textColor="text-white"
90
- className="flex w-5/6 items-center gap-2 sm:px-0"
90
+ className="flex w-5/6 max-w-[400px] items-center gap-2 sm:px-0"
91
91
  disabled={txLoading || isSwitchingOrExecuting}
92
92
  onClick={onPayment}
93
93
  >
@@ -1,15 +1,19 @@
1
1
  "use client";
2
2
 
3
3
  import { useAccountWallet } from "@b3dotfun/sdk/global-account/react";
4
+ import { thirdwebB3Mainnet } from "@b3dotfun/sdk/shared/constants/chains/b3Chain";
4
5
  import { cn } from "@b3dotfun/sdk/shared/utils/cn";
5
6
  import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
7
+ import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
6
8
  import { ChevronLeft, ChevronRightCircle, Wallet, X } from "lucide-react";
7
- import { useEffect, useRef } from "react";
9
+ import { useState } from "react";
10
+ import { createPortal } from "react-dom";
8
11
  import { toast } from "sonner";
9
- import { useSetActiveWallet } from "thirdweb/react";
10
- import { useAccount, useConnect, useDisconnect } from "wagmi";
12
+ import { ConnectEmbed, lightTheme, useActiveWallet } from "thirdweb/react";
13
+ import { createWallet } from "thirdweb/wallets";
14
+ import { useDisconnect } from "wagmi";
11
15
 
12
- export enum PaymentMethod {
16
+ export enum CryptoPaymentMethodType {
13
17
  NONE = "none",
14
18
  CONNECT_WALLET = "connect_wallet",
15
19
  TRANSFER_CRYPTO = "transfer_crypto",
@@ -22,11 +26,11 @@ interface CryptoPaymentMethodProps {
22
26
  icon?: string;
23
27
  };
24
28
  };
25
- selectedPaymentMethod: PaymentMethod;
26
- setSelectedPaymentMethod: (method: PaymentMethod) => void;
29
+ selectedPaymentMethod: CryptoPaymentMethodType;
30
+ setSelectedPaymentMethod: (method: CryptoPaymentMethodType) => void;
27
31
  isCreatingOrder: boolean;
28
32
  onBack: () => void;
29
- onSelectPaymentMethod: (method: PaymentMethod) => void;
33
+ onSelectPaymentMethod: (method: CryptoPaymentMethodType) => void;
30
34
  }
31
35
 
32
36
  export function CryptoPaymentMethod({
@@ -36,59 +40,23 @@ export function CryptoPaymentMethod({
36
40
  onBack,
37
41
  onSelectPaymentMethod,
38
42
  }: CryptoPaymentMethodProps) {
39
- const { connect, connectors, isPending: isConnecting, error: connectError } = useConnect();
40
- const wagmiAccount = useAccount();
41
- const { address: globalAddress, connectedEOAWallet, isActiveEOAWallet, wallet: globalWallet } = useAccountWallet();
43
+ const { wallet: globalWallet } = useAccountWallet();
44
+ const activeWallet = useActiveWallet();
42
45
  const { disconnect } = useDisconnect();
43
- const previousAddress = useRef<string | undefined>(globalAddress);
46
+ const [showWalletModal, setShowWalletModal] = useState(false);
44
47
 
45
- const setActiveWallet = useSetActiveWallet();
46
-
47
- // Automatically set EOA wallet as active when available
48
- useEffect(() => {
49
- if (connectedEOAWallet) {
50
- console.log("Setting active wallet", connectedEOAWallet);
51
- setActiveWallet(connectedEOAWallet);
52
- }
53
- }, [connectedEOAWallet, isActiveEOAWallet, setActiveWallet]);
54
-
55
- // Handle wallet connection success
56
- useEffect(() => {
57
- if (globalAddress && previousAddress.current !== globalAddress) {
58
- previousAddress.current = globalAddress;
59
- toast.success("Wallet connected successfully");
60
- // Automatically select connect wallet method and go back to main view
61
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
62
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
63
- }
64
- }, [globalAddress, setSelectedPaymentMethod, onSelectPaymentMethod]);
65
-
66
- // Handle connection errors
67
- useEffect(() => {
68
- if (connectError) {
69
- // Handle specific error cases
70
- if (connectError.message.includes("Connector already connected")) {
71
- // If connector is already connected, just proceed with the flow
72
- console.log("Connector already connected, proceeding with selection");
73
- // Use wagmi account address or global address
74
- if (wagmiAccount.address || globalAddress) {
75
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
76
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
77
- } else {
78
- // Fallback: proceed anyway as the connector reports it's connected
79
- setTimeout(() => {
80
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
81
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
82
- }, 100);
83
- }
84
- } else {
85
- toast.error(`Failed to connect wallet: ${connectError.message}`);
86
- }
87
- }
88
- }, [connectError, globalAddress, wagmiAccount.address, setSelectedPaymentMethod, onSelectPaymentMethod]);
48
+ // Define available wallets for the modal
49
+ const availableWallets = [
50
+ createWallet("io.metamask"),
51
+ // createWallet("com.coinbase.wallet"),
52
+ createWallet("me.rainbow"),
53
+ createWallet("walletConnect"),
54
+ createWallet("io.rabby"),
55
+ createWallet("app.phantom"),
56
+ ];
89
57
 
90
58
  return (
91
- <div className="mx-auto w-[460px] max-w-full">
59
+ <div className="mx-auto h-fit w-[460px] max-w-full">
92
60
  <div className={cn("relative flex flex-col gap-10")}>
93
61
  {/* Header */}
94
62
  <button
@@ -106,46 +74,11 @@ export function CryptoPaymentMethod({
106
74
  {/* Payment Methods */}
107
75
  <div className="flex flex-col gap-3">
108
76
  {/* Connect Wallet Option */}
109
- {!globalAddress ? (
77
+ {!activeWallet ? (
110
78
  // Not connected - show single connect button
111
79
  <button
112
- onClick={() => {
113
- // Prevent connecting if already connecting or if there's already a connection
114
- if (isConnecting) return;
115
-
116
- try {
117
- // Check if wagmi already has a connection
118
- if (wagmiAccount.isConnected && wagmiAccount.address) {
119
- // Already connected via wagmi, just proceed with selection
120
- console.log("Wagmi already connected, proceeding with selection");
121
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
122
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
123
- return;
124
- }
125
-
126
- // Check if global address exists (b3 account system)
127
- if (globalAddress) {
128
- // Already connected via global account, just proceed with selection
129
- console.log("Global address already exists, proceeding with selection");
130
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
131
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
132
- return;
133
- }
134
-
135
- // Use the first available connector or a preferred one
136
- const preferredConnector =
137
- connectors.find(c => c.name.toLowerCase().includes("metamask")) || connectors[0];
138
-
139
- if (preferredConnector) {
140
- connect({ connector: preferredConnector });
141
- }
142
- } catch (error) {
143
- console.error("Connection error:", error);
144
- toast.error("Failed to connect wallet. Please try again.");
145
- }
146
- }}
147
- disabled={isConnecting}
148
- className="bg-as-surface-primary border-as-border-secondary hover:border-as-secondary/80 group flex w-full items-center justify-between gap-4 rounded-xl border px-4 py-3.5 transition-all duration-200 hover:shadow-md disabled:cursor-not-allowed disabled:opacity-50"
80
+ onClick={() => setShowWalletModal(true)}
81
+ className="bg-as-surface-primary border-as-border-secondary hover:border-as-secondary/80 group flex w-full items-center justify-between gap-4 rounded-xl border px-4 py-3.5 transition-all duration-200 hover:shadow-md"
149
82
  >
150
83
  <div className="flex items-center gap-3">
151
84
  <div className="flex h-8 w-8 items-center justify-center rounded-full bg-blue-100">
@@ -153,14 +86,10 @@ export function CryptoPaymentMethod({
153
86
  </div>
154
87
  <div className="flex flex-col items-start text-left">
155
88
  <h4 className="text-as-primary font-semibold">Connect wallet</h4>
156
- <p className="text-as-primary/60 text-sm">Connect your wallet to continue</p>
89
+ <p className="text-as-primary/60 text-sm">Choose from multiple wallet options</p>
157
90
  </div>
158
91
  </div>
159
- {isConnecting ? (
160
- <div className="border-as-primary/20 border-t-as-primary h-5 w-5 animate-spin rounded-full border-2"></div>
161
- ) : (
162
- <ChevronRightCircle className="text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" />
163
- )}
92
+ <ChevronRightCircle className="text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" />
164
93
  </button>
165
94
  ) : (
166
95
  // Connected - show wallet info
@@ -176,25 +105,27 @@ export function CryptoPaymentMethod({
176
105
  )}
177
106
  <div className="flex flex-col">
178
107
  <span className="text-as-primary font-semibold">Connected Wallet</span>
179
- <span className="text-as-primary/60 text-sm">{shortenAddress(globalAddress)}</span>
108
+ <span className="text-as-primary/60 text-sm">
109
+ {shortenAddress(activeWallet.getAccount()?.address || "")}
110
+ </span>
180
111
  </div>
181
112
  </div>
182
113
  <div className="flex items-center gap-2">
183
114
  <button
184
115
  onClick={() => {
185
- setSelectedPaymentMethod(PaymentMethod.CONNECT_WALLET);
186
- onSelectPaymentMethod(PaymentMethod.CONNECT_WALLET);
116
+ setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
117
+ onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
187
118
  }}
188
119
  className="bg-as-brand hover:bg-as-brand/90 rounded-lg px-3 py-1.5 text-sm font-medium text-white transition-colors"
189
120
  >
190
121
  Use Wallet
191
122
  </button>
192
123
  <button
193
- onClick={() => {
124
+ onClick={async () => {
194
125
  disconnect();
195
126
  toast.success("Wallet disconnected");
196
- if (selectedPaymentMethod === PaymentMethod.CONNECT_WALLET) {
197
- setSelectedPaymentMethod(PaymentMethod.NONE);
127
+ if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
128
+ setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
198
129
  }
199
130
  }}
200
131
  className="text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors"
@@ -209,8 +140,8 @@ export function CryptoPaymentMethod({
209
140
  {/* Transfer Crypto Option */}
210
141
  <button
211
142
  onClick={() => {
212
- setSelectedPaymentMethod(PaymentMethod.TRANSFER_CRYPTO);
213
- onSelectPaymentMethod(PaymentMethod.TRANSFER_CRYPTO);
143
+ setSelectedPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
144
+ onSelectPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
214
145
  }}
215
146
  disabled={isCreatingOrder}
216
147
  className="bg-as-surface-primary border-as-border-secondary hover:border-as-secondary/80 group flex w-full items-center justify-between gap-4 rounded-xl border px-4 py-3.5 transition-all duration-200 hover:shadow-md"
@@ -222,6 +153,43 @@ export function CryptoPaymentMethod({
222
153
  </button>
223
154
  </div>
224
155
  </div>
156
+
157
+ {/* Wallet Connection Modal */}
158
+ {showWalletModal &&
159
+ createPortal(
160
+ <div className="pointer-events-auto fixed inset-0 z-[9999] flex items-center justify-center bg-black/50">
161
+ <div className="max-h-[80vh] w-[400px] max-w-[90vw] overflow-auto rounded-xl bg-white p-6 dark:bg-gray-900">
162
+ <div className="mb-4 flex items-center justify-between">
163
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white">Connect Wallet</h3>
164
+ <button
165
+ onClick={() => setShowWalletModal(false)}
166
+ className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
167
+ >
168
+ <X className="h-5 w-5" />
169
+ </button>
170
+ </div>
171
+ <ConnectEmbed
172
+ client={client}
173
+ chain={thirdwebB3Mainnet}
174
+ wallets={availableWallets}
175
+ showThirdwebBranding={false}
176
+ theme={lightTheme()}
177
+ onConnect={async wallet => {
178
+ console.log("Wallet connected:", wallet);
179
+ // setShowWalletModal(false);
180
+ setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
181
+ onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
182
+ setShowWalletModal(false);
183
+ }}
184
+ style={{
185
+ width: "100%",
186
+ minHeight: "300px",
187
+ }}
188
+ />
189
+ </div>
190
+ </div>,
191
+ typeof window !== "undefined" ? document.getElementById("b3-root") || document.body : document.body,
192
+ )}
225
193
  </div>
226
194
  );
227
195
  }
@@ -75,7 +75,7 @@ export function FiatPaymentMethodComponent({
75
75
  id: FiatPaymentMethod.STRIPE,
76
76
  name: "Stripe",
77
77
  description: "Credit or debit card payment",
78
- badge: stripeFee ? `$${stripeFee} fee` : "Standard Fee",
78
+ badge: stripeFee ? `$${Number(stripeFee).toFixed(2)} fee` : "Standard Fee",
79
79
  badgeColor: "bg-yellow-100 text-yellow-800",
80
80
  available: true,
81
81
  });
@@ -49,7 +49,7 @@ import { erc20Abi, WalletClient } from "viem";
49
49
  import { b3 } from "viem/chains";
50
50
  import { useWaitForTransactionReceipt, useWalletClient } from "wagmi";
51
51
  import ConnectWalletPayment from "./ConnectWalletPayment";
52
- import { PaymentMethod } from "./CryptoPaymentMethod";
52
+ import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
53
53
  import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible";
54
54
  import PaymentVendorUI from "./PaymentVendorUI";
55
55
  import { TransferCryptoDetails } from "./TransferCryptoDetails";
@@ -62,7 +62,7 @@ interface OrderDetailsProps {
62
62
  relayTx: components["schemas"]["RelayTx"] | null;
63
63
  executeTx: components["schemas"]["ExecuteTx"] | null;
64
64
  refundTxs: components["schemas"]["RefundTx"][] | null;
65
- paymentMethod?: PaymentMethod; // Now optional since we read from URL
65
+ cryptoPaymentMethod?: CryptoPaymentMethodType; // Now optional since we read from URL
66
66
  onBack?: () => void;
67
67
  }
68
68
 
@@ -199,15 +199,16 @@ export const OrderDetails = memo(function OrderDetails({
199
199
  relayTx,
200
200
  executeTx,
201
201
  refundTxs,
202
- paymentMethod = PaymentMethod.NONE,
202
+ cryptoPaymentMethod,
203
203
  onBack,
204
204
  }: OrderDetailsProps) {
205
205
  const router = useRouter();
206
206
  const searchParams = useSearchParams();
207
207
 
208
- // Read payment method from URL parameters
209
- const paymentMethodFromUrl = searchParams.get("paymentMethod") as PaymentMethod | null;
210
- const effectivePaymentMethod = paymentMethodFromUrl || paymentMethod || PaymentMethod.NONE;
208
+ // Read crypto payment method from URL parameters
209
+ const cryptoPaymentMethodFromUrl = searchParams.get("cryptoPaymentMethod") as CryptoPaymentMethodType | null;
210
+ const effectiveCryptoPaymentMethod =
211
+ cryptoPaymentMethod || cryptoPaymentMethodFromUrl || CryptoPaymentMethodType.NONE;
211
212
 
212
213
  const setB3ModalOpen = useModalStore((state: any) => state.setB3ModalOpen);
213
214
 
@@ -931,7 +932,7 @@ export const OrderDetails = memo(function OrderDetails({
931
932
  <>
932
933
  {order.onrampMetadata ? (
933
934
  <PaymentVendorUI isMainnet={isMainnet} order={order} dstTokenSymbol={dstToken.symbol} />
934
- ) : effectivePaymentMethod === PaymentMethod.CONNECT_WALLET ? (
935
+ ) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
935
936
  <ConnectWalletPayment
936
937
  order={order}
937
938
  onPayment={handlePayment}
@@ -942,7 +943,7 @@ export const OrderDetails = memo(function OrderDetails({
942
943
  tournament={tournament}
943
944
  nft={nft}
944
945
  />
945
- ) : effectivePaymentMethod === PaymentMethod.TRANSFER_CRYPTO ? (
946
+ ) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
946
947
  // Transfer Crypto Payment Method - Show new card-based UI
947
948
  <TransferCryptoDetails
948
949
  order={order}
@@ -1067,8 +1068,9 @@ export const OrderDetails = memo(function OrderDetails({
1067
1068
  value={getPaymentUrl(
1068
1069
  order.globalAddress,
1069
1070
  BigInt(order.srcAmount),
1070
- order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress,
1071
+ order.srcTokenAddress === RELAY_ETH_ADDRESS ? srcToken?.symbol || "ETH" : order.srcTokenAddress,
1071
1072
  order.srcChain,
1073
+ srcToken?.decimals,
1072
1074
  )}
1073
1075
  className="max-w-[200px]"
1074
1076
  />
@@ -1153,10 +1155,7 @@ function TransactionDetails({
1153
1155
  initial={{ opacity: 0, scale: 0.3 }}
1154
1156
  animate={{ opacity: 1, scale: 1 }}
1155
1157
  transition={{ duration: 0.5, ease: "easeOut", delay }}
1156
- className="bg-as-brand/70 absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border border-white/30 shadow-lg shadow-purple-500/30 backdrop-blur-sm"
1157
- style={{
1158
- boxShadow: "0 0 15px 5px rgba(138, 43, 226, 0.2)",
1159
- }}
1158
+ className="bg-as-brand/70 absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border border-white/30 shadow-lg backdrop-blur-sm"
1160
1159
  >
1161
1160
  <CheckIcon className="text-as-primary h-3 w-3" />
1162
1161
  </motion.div>
@@ -24,11 +24,11 @@ export const OrderStatus = memo(function OrderStatus({ order }: { order: compone
24
24
  },
25
25
  ];
26
26
 
27
- if (order.status === "waiting_stripe_payment") {
27
+ if (["waiting_stripe_payment"].includes(order.status)) {
28
28
  return <StepProgress steps={paymentSteps} currentStepIndex={0} />;
29
29
  }
30
30
 
31
- if (order.status === "relay") {
31
+ if (["relay", "sending_token_from_vault"].includes(order.status)) {
32
32
  return <StepProgress steps={paymentSteps} currentStepIndex={1} />;
33
33
  }
34
34
 
@@ -147,9 +147,7 @@ function StripePaymentForm({
147
147
  try {
148
148
  const result = (await stripe.confirmPayment({
149
149
  elements,
150
- confirmParams: {
151
- return_url: `${window.location.origin}/?orderId=${order.id}&waitingForDeposit=true&fromStripe=true`,
152
- },
150
+ redirect: "if_required",
153
151
  })) as PaymentIntentResult;
154
152
 
155
153
  if (result.error) {
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Example usage of the RecipientSelection component
3
+ * This file demonstrates various ways to use the component with different props
4
+ */
5
+
6
+ import { isAddress } from "viem";
7
+ import { RecipientSelection } from "./RecipientSelection";
8
+
9
+ // Basic usage example
10
+ export function BasicRecipientSelection() {
11
+ return (
12
+ <RecipientSelection
13
+ onBack={() => console.log("Back clicked")}
14
+ onConfirm={address => console.log("Address confirmed:", address)}
15
+ />
16
+ );
17
+ }
18
+
19
+ // Custom styling and validation example
20
+ export function CustomRecipientSelection() {
21
+ const validateEthereumAddress = (address: string): boolean => {
22
+ return isAddress(address);
23
+ };
24
+
25
+ return (
26
+ <RecipientSelection
27
+ initialValue="0x..."
28
+ placeholder="Enter Ethereum address"
29
+ title="Send to Ethereum Address"
30
+ description="Enter a valid Ethereum address to send tokens"
31
+ confirmText="Confirm Ethereum Address"
32
+ validateAddress={validateEthereumAddress}
33
+ autoFocus={false}
34
+ onBack={() => console.log("Going back")}
35
+ onConfirm={address => console.log("Valid Ethereum address:", address)}
36
+ />
37
+ );
38
+ }
39
+
40
+ // ENS-focused example
41
+ export function ENSRecipientSelection() {
42
+ return (
43
+ <RecipientSelection
44
+ placeholder="Enter ENS name (e.g., vitalik.eth)"
45
+ title="Send to ENS Address"
46
+ description="Enter an ENS name or Ethereum address"
47
+ confirmText="Confirm ENS Address"
48
+ onBack={() => console.log("Back to previous view")}
49
+ onConfirm={address => console.log("ENS or address:", address)}
50
+ />
51
+ );
52
+ }
@@ -0,0 +1,146 @@
1
+ "use client";
2
+
3
+ import { ChevronLeft } from "lucide-react";
4
+ import { useEffect, useState } from "react";
5
+
6
+ export interface RecipientSelectionProps {
7
+ /**
8
+ * Initial recipient address value
9
+ */
10
+ initialValue?: string;
11
+ /**
12
+ * Placeholder text for the input field
13
+ */
14
+ placeholder?: string;
15
+ /**
16
+ * Title text displayed in the header
17
+ */
18
+ title?: string;
19
+ /**
20
+ * Description text displayed below the title
21
+ */
22
+ description?: string;
23
+ /**
24
+ * Text for the confirm button
25
+ */
26
+ confirmText?: string;
27
+ /**
28
+ * Callback when back button is clicked
29
+ */
30
+ onBack: () => void;
31
+ /**
32
+ * Callback when recipient address is confirmed
33
+ * @param address - The recipient address entered by the user
34
+ */
35
+ onConfirm: (address: string) => void;
36
+ /**
37
+ * Whether the component should auto-focus the input
38
+ */
39
+ autoFocus?: boolean;
40
+ /**
41
+ * Custom validation function for the address
42
+ * @param address - The address to validate
43
+ * @returns true if valid, false otherwise
44
+ */
45
+ validateAddress?: (address: string) => boolean;
46
+ }
47
+
48
+ export function RecipientSelection({
49
+ initialValue = "",
50
+ placeholder = "Enter recipient address",
51
+ title = "Add recipient address or ENS",
52
+ description = "Swap and send tokens to another address",
53
+ confirmText = "Confirm recipient address",
54
+ onBack,
55
+ onConfirm,
56
+ autoFocus = true,
57
+ validateAddress,
58
+ }: RecipientSelectionProps) {
59
+ const [recipientAddress, setRecipientAddress] = useState<string>(initialValue);
60
+
61
+ // Update internal state when initialValue changes
62
+ useEffect(() => {
63
+ setRecipientAddress(initialValue);
64
+ }, [initialValue]);
65
+
66
+ const handlePaste = async () => {
67
+ try {
68
+ const text = await navigator.clipboard.readText();
69
+ setRecipientAddress(text);
70
+ } catch (err) {
71
+ console.error("Failed to read clipboard:", err);
72
+ }
73
+ };
74
+
75
+ const handleConfirm = () => {
76
+ if (recipientAddress && (!validateAddress || validateAddress(recipientAddress))) {
77
+ onConfirm(recipientAddress);
78
+ }
79
+ };
80
+
81
+ const handleKeyDown = (e: React.KeyboardEvent) => {
82
+ if (e.key === "Enter" && recipientAddress) {
83
+ handleConfirm();
84
+ }
85
+ };
86
+
87
+ const isAddressValid = !validateAddress || !recipientAddress || validateAddress(recipientAddress);
88
+ const canConfirm = recipientAddress && isAddressValid;
89
+
90
+ return (
91
+ <div className="mx-auto w-[460px] max-w-full">
92
+ <div className="flex flex-col gap-6">
93
+ {/* Header */}
94
+ <div className="flex justify-around">
95
+ <button
96
+ onClick={onBack}
97
+ className="text-as-quaternary hover:text-as-primary flex h-8 w-8 items-center justify-center rounded-lg transition-colors"
98
+ >
99
+ <ChevronLeft className="h-6 w-6" />
100
+ </button>
101
+ <div className="flex-1 text-center">
102
+ <h2 className="text-as-primary text-lg font-semibold">{title}</h2>
103
+ <p className="text-as-primary/60 text-sm">{description}</p>
104
+ </div>
105
+ </div>
106
+
107
+ {/* Address Input */}
108
+ <div className="flex flex-col gap-4">
109
+ <div className="bg-as-surface-secondary border-as-border-secondary flex h-12 w-full overflow-hidden rounded-xl border">
110
+ <input
111
+ type="text"
112
+ placeholder={placeholder}
113
+ value={recipientAddress}
114
+ onChange={e => setRecipientAddress(e.target.value)}
115
+ onKeyDown={handleKeyDown}
116
+ className="text-as-primary placeholder:text-as-primary/50 flex-1 bg-transparent px-4 text-base focus:outline-none"
117
+ autoFocus={autoFocus}
118
+ />
119
+ <div className="border-as-border-secondary border-l">
120
+ <button
121
+ onClick={handlePaste}
122
+ className="text-as-primary/70 hover:text-as-primary hover:bg-as-surface-primary h-full px-4 font-semibold transition-colors"
123
+ >
124
+ Paste
125
+ </button>
126
+ </div>
127
+ </div>
128
+
129
+ {/* Validation Error */}
130
+ {recipientAddress && !isAddressValid && (
131
+ <div className="text-as-red text-sm">Please enter a valid address</div>
132
+ )}
133
+
134
+ {/* Confirm Button */}
135
+ <button
136
+ onClick={handleConfirm}
137
+ disabled={!canConfirm}
138
+ className="bg-as-brand hover:bg-as-brand/90 disabled:bg-as-on-surface-2 disabled:text-as-secondary h-12 w-full rounded-xl font-medium text-white transition-colors disabled:cursor-not-allowed"
139
+ >
140
+ {confirmText}
141
+ </button>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ );
146
+ }
@@ -195,6 +195,7 @@ export const TransferCryptoDetails = memo(function TransferCryptoDetails({
195
195
  BigInt(order.srcAmount),
196
196
  order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress,
197
197
  order.srcChain,
198
+ srcToken?.decimals,
198
199
  )}
199
200
  className="bg-as-surface-secondary max-h-48 max-w-48"
200
201
  />
@@ -19,6 +19,7 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem";
19
19
  export { OrderStatus } from "./common/OrderStatus";
20
20
  export { OrderToken } from "./common/OrderToken";
21
21
  export { OrderTokenAmount } from "./common/OrderTokenAmount";
22
+ export { RecipientSelection } from "./common/RecipientSelection";
22
23
  export { StepProgress } from "./common/StepProgress";
23
24
  export { TokenBalance } from "./common/TokenBalance";
24
25
  export { TransferCryptoDetails } from "./common/TransferCryptoDetails";
@@ -5,6 +5,7 @@ export * from "./useAnyspendOrderHistory";
5
5
  export * from "./useAnyspendQuote";
6
6
  export * from "./useAnyspendTokens";
7
7
  export * from "./useCoinbaseOnrampOptions";
8
+ export * from "./useConnectedUserProfile";
8
9
  export * from "./useGeoOnrampOptions";
9
10
  export * from "./useGetGeo";
10
11
  export * from "./useSigMint";