@b3dotfun/sdk 0.0.62 → 0.0.63-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.
- package/dist/cjs/anyspend/react/components/AnySpend.js +61 -23
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +275 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +5 -4
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +288 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +33 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +4 -6
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +66 -147
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +39 -15
- package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/cjs/anyspend/react/components/common/TokenBalance.js +1 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/index.js +11 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +56 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +73 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.js +57 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.js +211 -0
- package/dist/cjs/anyspend/types/api.d.ts +665 -3
- package/dist/cjs/anyspend/utils/orderPayload.js +4 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +17 -4
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.js +141 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/cjs/global-account/react/components/index.d.ts +2 -0
- package/dist/cjs/global-account/react/components/index.js +7 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/index.js +5 -3
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.js +62 -0
- package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/cjs/global-account/react/utils/profileDisplay.js +60 -4
- package/dist/esm/anyspend/react/components/AnySpend.js +62 -24
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +269 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +7 -6
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +285 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +30 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +5 -7
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +67 -148
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +40 -16
- package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/esm/anyspend/react/components/common/TokenBalance.js +2 -2
- package/dist/esm/anyspend/react/components/index.d.ts +5 -1
- package/dist/esm/anyspend/react/components/index.js +5 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +53 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +70 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.js +54 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.js +208 -0
- package/dist/esm/anyspend/types/api.d.ts +665 -3
- package/dist/esm/anyspend/utils/orderPayload.js +4 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +18 -5
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.js +135 -0
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/esm/global-account/react/components/index.d.ts +2 -0
- package/dist/esm/global-account/react/components/index.js +3 -0
- package/dist/esm/global-account/react/hooks/index.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/index.js +2 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.js +59 -0
- package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/esm/global-account/react/utils/profileDisplay.js +59 -4
- package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/types/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/types/anyspend/react/components/index.d.ts +5 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/types/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/types/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/types/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/types/anyspend/types/api.d.ts +665 -3
- package/dist/types/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/types/global-account/react/components/index.d.ts +2 -0
- package/dist/types/global-account/react/hooks/index.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/package.json +4 -3
- package/src/anyspend/react/components/AnySpend.tsx +73 -22
- package/src/anyspend/react/components/AnySpendCustom.tsx +4 -0
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +595 -0
- package/src/anyspend/react/components/AnySpendStakeB3.tsx +8 -11
- package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +522 -0
- package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +73 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +7 -3
- package/src/anyspend/react/components/common/CryptoPaySection.tsx +5 -7
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +9 -18
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +22 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +76 -190
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +2 -3
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +48 -17
- package/src/anyspend/react/components/common/PaySection.tsx +1 -0
- package/src/anyspend/react/components/common/TokenBalance.tsx +2 -2
- package/src/anyspend/react/components/index.ts +5 -1
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +51 -18
- package/src/anyspend/react/hooks/useAnyspendQuote.ts +1 -1
- package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +72 -0
- package/src/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.ts +80 -0
- package/src/anyspend/react/hooks/useConnectedWalletDisplay.ts +69 -0
- package/src/anyspend/react/hooks/usePhantomTransfer.ts +301 -0
- package/src/anyspend/types/api.ts +669 -1
- package/src/anyspend/utils/orderPayload.ts +5 -1
- package/src/global-account/react/components/B3DynamicModal.tsx +18 -4
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +4 -4
- package/src/global-account/react/components/ProfileEditor/ProfileEditor.tsx +265 -0
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +3 -1
- package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +2 -2
- package/src/global-account/react/components/index.ts +4 -0
- package/src/global-account/react/hooks/index.ts +2 -1
- package/src/global-account/react/hooks/useAuthentication.ts +10 -2
- package/src/global-account/react/hooks/useSimBalance.ts +6 -5
- package/src/global-account/react/hooks/useTokenBalanceDirect.tsx +84 -0
- package/src/global-account/react/hooks/useTokenFromUrl.tsx +6 -5
- package/src/global-account/react/stores/useModalStore.ts +43 -1
- package/src/global-account/react/utils/profileDisplay.ts +67 -4
|
@@ -13,6 +13,7 @@ import { toast } from "sonner";
|
|
|
13
13
|
import { useActiveWallet, useSetActiveWallet, useWalletInfo } from "thirdweb/react";
|
|
14
14
|
import { WalletId, createWallet } from "thirdweb/wallets";
|
|
15
15
|
import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
|
|
16
|
+
import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
|
|
16
17
|
|
|
17
18
|
export enum CryptoPaymentMethodType {
|
|
18
19
|
NONE = "none",
|
|
@@ -47,7 +48,7 @@ export function CryptoPaymentMethod({
|
|
|
47
48
|
connectedEOAWallet: connectedEOAWallet,
|
|
48
49
|
connectedSmartWallet: connectedSmartWallet,
|
|
49
50
|
} = useAccountWallet();
|
|
50
|
-
const { connector, address
|
|
51
|
+
const { connector, address } = useAccount();
|
|
51
52
|
const { connect, connectors, isPending } = useConnect();
|
|
52
53
|
const { disconnect } = useDisconnect();
|
|
53
54
|
const { data: walletClient } = useWalletClient();
|
|
@@ -61,20 +62,8 @@ export function CryptoPaymentMethod({
|
|
|
61
62
|
const isConnected = !!connectedEOAWallet;
|
|
62
63
|
const globalAddress = connectedSmartWallet?.getAccount()?.address;
|
|
63
64
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
if (!addr1 || !addr2) return false;
|
|
67
|
-
return addr1.toLowerCase() === addr2.toLowerCase();
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Check if connectedEOAWallet and wagmi wallet represent the same wallet
|
|
71
|
-
const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
|
|
72
|
-
const wagmiAddress = address;
|
|
73
|
-
const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
|
|
74
|
-
|
|
75
|
-
// Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
|
|
76
|
-
const shouldShowConnectedEOA = !!connectedEOAWallet;
|
|
77
|
-
const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
|
|
65
|
+
// Use custom hook to determine wallet display logic
|
|
66
|
+
const { shouldShowConnectedEOA, shouldShowWagmiWallet } = useConnectedWalletDisplay(selectedPaymentMethod);
|
|
78
67
|
|
|
79
68
|
// Map wagmi connector names to thirdweb wallet IDs
|
|
80
69
|
const getThirdwebWalletId = (connectorName: string): WalletId | null => {
|
|
@@ -237,11 +226,13 @@ export function CryptoPaymentMethod({
|
|
|
237
226
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
238
227
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
239
228
|
setGlobalAccountWallet(activeWallet);
|
|
240
|
-
|
|
229
|
+
if (connectedEOAWallet) {
|
|
230
|
+
setActiveWallet(connectedEOAWallet);
|
|
231
|
+
}
|
|
241
232
|
toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
|
|
242
233
|
}}
|
|
243
234
|
className={cn(
|
|
244
|
-
"crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
235
|
+
"crypto-payment-method-connect-wallet eoa-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
245
236
|
selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
246
237
|
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
247
238
|
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
|
|
@@ -300,7 +291,7 @@ export function CryptoPaymentMethod({
|
|
|
300
291
|
toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
301
292
|
}}
|
|
302
293
|
className={cn(
|
|
303
|
-
"crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
294
|
+
"crypto-payment-method-connect-wallet wagmi-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
304
295
|
selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
305
296
|
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
306
297
|
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
|
|
@@ -4,8 +4,11 @@ import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
|
4
4
|
import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
|
|
5
5
|
import { ChevronRight, Info } from "lucide-react";
|
|
6
6
|
import { motion } from "motion/react";
|
|
7
|
+
import { useEffect } from "react";
|
|
7
8
|
import { components } from "../../../types/api";
|
|
8
9
|
import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
|
|
10
|
+
import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
|
|
11
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
9
12
|
import { OrderTokenAmount } from "./OrderTokenAmount";
|
|
10
13
|
import { PointsBadge } from "./PointsBadge";
|
|
11
14
|
|
|
@@ -16,6 +19,9 @@ interface CryptoReceiveSectionProps {
|
|
|
16
19
|
selectedRecipientAddress?: string;
|
|
17
20
|
recipientName?: string;
|
|
18
21
|
onSelectRecipient: () => void;
|
|
22
|
+
setRecipientAddress?: (address: string | undefined) => void;
|
|
23
|
+
recipientAddressFromProps?: string;
|
|
24
|
+
globalAddress?: string;
|
|
19
25
|
// Token data
|
|
20
26
|
dstAmount: string;
|
|
21
27
|
dstToken: components["schemas"]["Token"];
|
|
@@ -34,6 +40,8 @@ interface CryptoReceiveSectionProps {
|
|
|
34
40
|
onShowPointsDetail?: () => void;
|
|
35
41
|
// Fee detail navigation
|
|
36
42
|
onShowFeeDetail?: () => void;
|
|
43
|
+
// Payment method for wallet tracking
|
|
44
|
+
selectedCryptoPaymentMethod?: CryptoPaymentMethodType;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
export function CryptoReceiveSection({
|
|
@@ -42,6 +50,9 @@ export function CryptoReceiveSection({
|
|
|
42
50
|
selectedRecipientAddress,
|
|
43
51
|
recipientName,
|
|
44
52
|
onSelectRecipient,
|
|
53
|
+
setRecipientAddress,
|
|
54
|
+
recipientAddressFromProps,
|
|
55
|
+
globalAddress,
|
|
45
56
|
dstAmount,
|
|
46
57
|
dstToken,
|
|
47
58
|
selectedDstChainId,
|
|
@@ -54,9 +65,20 @@ export function CryptoReceiveSection({
|
|
|
54
65
|
dstTokenLogoURI,
|
|
55
66
|
onShowPointsDetail,
|
|
56
67
|
onShowFeeDetail,
|
|
68
|
+
selectedCryptoPaymentMethod,
|
|
57
69
|
}: CryptoReceiveSectionProps) {
|
|
58
70
|
const featureFlags = useFeatureFlags();
|
|
59
71
|
|
|
72
|
+
// Get wallet address based on selected payment method
|
|
73
|
+
const { walletAddress } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
|
|
74
|
+
|
|
75
|
+
// Set default recipient address when wallet changes
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (setRecipientAddress) {
|
|
78
|
+
setRecipientAddress(recipientAddressFromProps || walletAddress || globalAddress);
|
|
79
|
+
}
|
|
80
|
+
}, [recipientAddressFromProps, walletAddress, globalAddress, setRecipientAddress]);
|
|
81
|
+
|
|
60
82
|
return (
|
|
61
83
|
<motion.div
|
|
62
84
|
initial={{ opacity: 0, y: 20, filter: "blur(10px)" }}
|
|
@@ -31,22 +31,17 @@ import { cn } from "@b3dotfun/sdk/shared/utils";
|
|
|
31
31
|
import centerTruncate from "@b3dotfun/sdk/shared/utils/centerTruncate";
|
|
32
32
|
import { formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
|
|
33
33
|
|
|
34
|
-
import {
|
|
35
|
-
createAssociatedTokenAccountInstruction,
|
|
36
|
-
createTransferCheckedInstruction,
|
|
37
|
-
getAssociatedTokenAddressSync,
|
|
38
|
-
} from "@solana/spl-token";
|
|
39
|
-
import { ComputeBudgetProgram, Connection, PublicKey, SystemProgram, Transaction } from "@solana/web3.js";
|
|
40
34
|
import { WalletCoinbase, WalletMetamask, WalletPhantom, WalletTrust, WalletWalletConnect } from "@web3icons/react";
|
|
41
35
|
import { CheckIcon, ChevronRight, Copy, ExternalLink, Home, Loader2, RefreshCcw } from "lucide-react";
|
|
42
36
|
import { motion } from "motion/react";
|
|
43
37
|
import { QRCodeSVG } from "qrcode.react";
|
|
44
|
-
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
38
|
+
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
45
39
|
import TimeAgo from "react-timeago";
|
|
46
40
|
import { toast } from "sonner";
|
|
47
41
|
import { encodeFunctionData, erc20Abi } from "viem";
|
|
48
42
|
import { b3 } from "viem/chains";
|
|
49
43
|
import { useWaitForTransactionReceipt, useWalletClient } from "wagmi";
|
|
44
|
+
import { usePhantomTransfer } from "../../hooks/usePhantomTransfer";
|
|
50
45
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./Accordion";
|
|
51
46
|
import ConnectWalletPayment from "./ConnectWalletPayment";
|
|
52
47
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
@@ -111,6 +106,12 @@ function getOrderSuccessText({
|
|
|
111
106
|
case "custom":
|
|
112
107
|
actionText = order.metadata.action || `executed contract`;
|
|
113
108
|
return `Successfully ${actionText}`;
|
|
109
|
+
case "x402_swap":
|
|
110
|
+
actionText = `sent ${formattedActualDstAmount || "--"} ${dstToken.symbol}`;
|
|
111
|
+
return `Successfully ${actionText} to ${recipient}`;
|
|
112
|
+
case "custom_exact_in":
|
|
113
|
+
actionText = `executed contract`;
|
|
114
|
+
return `Successfully ${actionText}`;
|
|
114
115
|
default:
|
|
115
116
|
throw new Error("Invalid order type");
|
|
116
117
|
}
|
|
@@ -250,6 +251,11 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
250
251
|
const { switchChainAndExecuteWithEOA, switchChainAndExecute, isSwitchingOrExecuting } =
|
|
251
252
|
useUnifiedChainSwitchAndExecute();
|
|
252
253
|
|
|
254
|
+
// Track if auto-payment was attempted to avoid re-triggering
|
|
255
|
+
const autoPaymentAttempted = useRef(false);
|
|
256
|
+
// Track if component is ready for auto-payment (all data loaded)
|
|
257
|
+
const [isComponentReady, setIsComponentReady] = useState(false);
|
|
258
|
+
|
|
253
259
|
const roundedUpSrcAmount = useMemo(() => {
|
|
254
260
|
// Display the full transfer amount without rounding since users need to see the exact value they're transferring.
|
|
255
261
|
// Use 21 significant digits (max allowed by Intl.NumberFormat)
|
|
@@ -314,18 +320,25 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
314
320
|
}
|
|
315
321
|
}, [order, switchChainAndExecuteWithEOA, switchChainAndExecute, depositDeficit, effectiveCryptoPaymentMethod]);
|
|
316
322
|
|
|
323
|
+
// Use Phantom transfer hook for Solana payments
|
|
324
|
+
const { initiateTransfer: initiatePhantomTransfer, getConnectedAddress: getPhantomAddress } = usePhantomTransfer();
|
|
325
|
+
|
|
317
326
|
// Main payment handler that triggers chain switch and payment
|
|
318
|
-
const handlePayment = async () => {
|
|
327
|
+
const handlePayment = useCallback(async () => {
|
|
319
328
|
console.log("Initiating payment process. Target chain:", order.srcChain, "Current chain:", walletClient?.chain?.id);
|
|
320
329
|
if (order.srcChain === RELAY_SOLANA_MAINNET_CHAIN_ID) {
|
|
321
330
|
// Use the existing depositDeficit calculation to determine amount to send
|
|
322
331
|
const amountToSend = depositDeficit > BigInt(0) ? depositDeficit.toString() : order.srcAmount;
|
|
323
|
-
await initiatePhantomTransfer(
|
|
332
|
+
await initiatePhantomTransfer({
|
|
333
|
+
amountLamports: amountToSend,
|
|
334
|
+
tokenAddress: order.srcTokenAddress,
|
|
335
|
+
recipientAddress: order.globalAddress,
|
|
336
|
+
});
|
|
324
337
|
} else {
|
|
325
338
|
// Use unified payment process for both EOA and AA wallets
|
|
326
339
|
await handleUnifiedPaymentProcess();
|
|
327
340
|
}
|
|
328
|
-
};
|
|
341
|
+
}, [order, walletClient?.chain?.id, depositDeficit, handleUnifiedPaymentProcess, initiatePhantomTransfer]);
|
|
329
342
|
|
|
330
343
|
// When waitingForDeposit is true, we show a message to the user to wait for the deposit to be processed.
|
|
331
344
|
const setWaitingForDeposit = useCallback(() => {
|
|
@@ -368,17 +381,57 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
368
381
|
}
|
|
369
382
|
}, [setWaitingForDeposit, txSuccess]);
|
|
370
383
|
|
|
371
|
-
const isPhantomMobile = useMemo(() => navigator.userAgent.includes("Phantom"), []);
|
|
372
|
-
const isPhantomBrowser = useMemo(() => (window as any).phantom?.solana?.isPhantom, []);
|
|
373
|
-
|
|
374
384
|
// Get connected Phantom wallet address if available
|
|
375
|
-
const phantomWalletAddress = useMemo(() =>
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
385
|
+
const phantomWalletAddress = useMemo(() => getPhantomAddress(), [getPhantomAddress]);
|
|
386
|
+
|
|
387
|
+
// Calculate status display before using it
|
|
388
|
+
const { text: statusText, status: statusDisplay } = getStatusDisplay(order);
|
|
389
|
+
|
|
390
|
+
// Memoize the payable state calculation to avoid recalculating on every render
|
|
391
|
+
const isPayableState = useMemo(() => {
|
|
392
|
+
const waitingForDeposit = new URLSearchParams(window.location.search).get("waitingForDeposit") === "true";
|
|
393
|
+
|
|
394
|
+
return (
|
|
395
|
+
refundTxs.length === 0 &&
|
|
396
|
+
!executeTx &&
|
|
397
|
+
!(relayTxs.length > 0 && relayTxs.every(tx => tx.status === "success")) &&
|
|
398
|
+
!depositTxs?.length &&
|
|
399
|
+
!waitingForDeposit &&
|
|
400
|
+
statusDisplay === "processing" &&
|
|
401
|
+
!order.onrampMetadata &&
|
|
402
|
+
(effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
403
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET)
|
|
404
|
+
);
|
|
405
|
+
}, [
|
|
406
|
+
refundTxs.length,
|
|
407
|
+
executeTx,
|
|
408
|
+
relayTxs,
|
|
409
|
+
depositTxs?.length,
|
|
410
|
+
statusDisplay,
|
|
411
|
+
order.onrampMetadata,
|
|
412
|
+
effectiveCryptoPaymentMethod,
|
|
413
|
+
]);
|
|
414
|
+
|
|
415
|
+
// Mark component as ready once all critical data is available
|
|
416
|
+
// This ensures we don't trigger payment before the component has fully initialized
|
|
417
|
+
useEffect(() => {
|
|
418
|
+
if (!isComponentReady && srcToken && dstToken && statusDisplay) {
|
|
419
|
+
setIsComponentReady(true);
|
|
420
|
+
}
|
|
421
|
+
}, [isComponentReady, srcToken, dstToken, statusDisplay]);
|
|
422
|
+
|
|
423
|
+
// Auto-trigger payment when component is ready and order is in payable state
|
|
424
|
+
// This effect only runs when isPayableState or isComponentReady changes
|
|
425
|
+
useEffect(() => {
|
|
426
|
+
// Only trigger payment if:
|
|
427
|
+
// 1. We haven't attempted payment yet
|
|
428
|
+
// 2. Component is fully ready (all data loaded)
|
|
429
|
+
// 3. Order is in a payable state
|
|
430
|
+
if (!autoPaymentAttempted.current && isComponentReady && isPayableState) {
|
|
431
|
+
autoPaymentAttempted.current = true;
|
|
432
|
+
handlePayment();
|
|
379
433
|
}
|
|
380
|
-
|
|
381
|
-
}, []);
|
|
434
|
+
}, [isPayableState, isComponentReady, handlePayment]);
|
|
382
435
|
|
|
383
436
|
if (!srcToken || !dstToken) {
|
|
384
437
|
return <div>Loading...</div>;
|
|
@@ -398,175 +451,6 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
398
451
|
? formatTokenAmount(BigInt(actualDstAmount), dstToken.decimals)
|
|
399
452
|
: undefined;
|
|
400
453
|
|
|
401
|
-
const { text: statusText, status: statusDisplay } = getStatusDisplay(order);
|
|
402
|
-
|
|
403
|
-
const initiatePhantomTransfer = async (amountLamports: string, tokenAddress: string, recipientAddress: string) => {
|
|
404
|
-
try {
|
|
405
|
-
if (!isPhantomBrowser && !isPhantomMobile) {
|
|
406
|
-
toast.error("Phantom wallet not installed. Please install Phantom wallet to continue.");
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Step 2: Ensure Phantom is connected/unlocked
|
|
411
|
-
const phantom = (window as any).phantom?.solana;
|
|
412
|
-
if (!phantom) {
|
|
413
|
-
toast.error("Phantom wallet not accessible");
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Connect and unlock wallet if needed
|
|
418
|
-
let publicKey;
|
|
419
|
-
try {
|
|
420
|
-
const connection = await phantom.connect();
|
|
421
|
-
publicKey = connection.publicKey;
|
|
422
|
-
} catch (connectError) {
|
|
423
|
-
toast.error("Failed to connect to Phantom wallet");
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Step 3: Create transaction with priority fees
|
|
428
|
-
const connection = new Connection("https://mainnet.helius-rpc.com/?api-key=efafd9b3-1807-4cf8-8aa4-3d984f56d8fb");
|
|
429
|
-
|
|
430
|
-
const fromPubkey = new PublicKey(publicKey.toString());
|
|
431
|
-
const toPubkey = new PublicKey(recipientAddress);
|
|
432
|
-
const amount = BigInt(amountLamports);
|
|
433
|
-
|
|
434
|
-
// Step 4: Get recent priority fees to determine optimal pricing
|
|
435
|
-
let priorityFee = 10000; // Default fallback (10,000 micro-lamports)
|
|
436
|
-
try {
|
|
437
|
-
const recentFees = await connection.getRecentPrioritizationFees({
|
|
438
|
-
lockedWritableAccounts: [fromPubkey],
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
if (recentFees && recentFees.length > 0) {
|
|
442
|
-
// Use 75th percentile of recent fees for good priority
|
|
443
|
-
const sortedFees = recentFees.map(fee => fee.prioritizationFee).sort((a, b) => a - b);
|
|
444
|
-
const percentile75Index = Math.floor(sortedFees.length * 0.75);
|
|
445
|
-
priorityFee = Math.max(sortedFees[percentile75Index] || 10000, 10000);
|
|
446
|
-
}
|
|
447
|
-
} catch (feeError) {
|
|
448
|
-
console.warn("Failed to fetch recent priority fees, using default:", feeError);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
let transaction: any;
|
|
452
|
-
|
|
453
|
-
// Check if this is native SOL transfer
|
|
454
|
-
if (tokenAddress === "11111111111111111111111111111111") {
|
|
455
|
-
// Native SOL transfer with priority fees
|
|
456
|
-
const computeUnitLimit = 1000; // SOL transfer + compute budget instructions need ~600-800 CU
|
|
457
|
-
const computeUnitPrice = Math.min(priorityFee, 100000); // Cap at 100k micro-lamports for safety
|
|
458
|
-
|
|
459
|
-
transaction = new Transaction()
|
|
460
|
-
.add(
|
|
461
|
-
// Set compute unit limit first (must come before other instructions)
|
|
462
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
463
|
-
units: computeUnitLimit,
|
|
464
|
-
}),
|
|
465
|
-
)
|
|
466
|
-
.add(
|
|
467
|
-
// Set priority fee
|
|
468
|
-
ComputeBudgetProgram.setComputeUnitPrice({
|
|
469
|
-
microLamports: computeUnitPrice,
|
|
470
|
-
}),
|
|
471
|
-
)
|
|
472
|
-
.add(
|
|
473
|
-
// Actual transfer instruction
|
|
474
|
-
SystemProgram.transfer({
|
|
475
|
-
fromPubkey,
|
|
476
|
-
toPubkey,
|
|
477
|
-
lamports: Number(amount),
|
|
478
|
-
}),
|
|
479
|
-
);
|
|
480
|
-
|
|
481
|
-
console.log(`Using priority fee: ${computeUnitPrice} micro-lamports per CU, limit: ${computeUnitLimit} CU`);
|
|
482
|
-
} else {
|
|
483
|
-
// SPL Token transfer with priority fees
|
|
484
|
-
const mintPubkey = new PublicKey(tokenAddress);
|
|
485
|
-
|
|
486
|
-
// Get associated token accounts
|
|
487
|
-
const fromTokenAccount = getAssociatedTokenAddressSync(mintPubkey, fromPubkey);
|
|
488
|
-
const toTokenAccount = getAssociatedTokenAddressSync(mintPubkey, toPubkey);
|
|
489
|
-
|
|
490
|
-
// Check if destination token account exists
|
|
491
|
-
const toTokenAccountInfo = await connection.getAccountInfo(toTokenAccount);
|
|
492
|
-
const needsDestinationAccount = !toTokenAccountInfo;
|
|
493
|
-
|
|
494
|
-
// Get mint info to determine decimals
|
|
495
|
-
const mintInfo = await connection.getParsedAccountInfo(mintPubkey);
|
|
496
|
-
const decimals = (mintInfo.value?.data as any)?.parsed?.info?.decimals || 9;
|
|
497
|
-
|
|
498
|
-
// SPL transfers need more compute units than SOL transfers
|
|
499
|
-
// Add extra CU if we need to create destination account
|
|
500
|
-
const computeUnitLimit = needsDestinationAccount ? 40000 : 20000;
|
|
501
|
-
const computeUnitPrice = Math.min(priorityFee, 100000);
|
|
502
|
-
|
|
503
|
-
// Create transfer instruction
|
|
504
|
-
const transferInstruction = createTransferCheckedInstruction(
|
|
505
|
-
fromTokenAccount,
|
|
506
|
-
mintPubkey,
|
|
507
|
-
toTokenAccount,
|
|
508
|
-
fromPubkey,
|
|
509
|
-
Number(amount),
|
|
510
|
-
decimals,
|
|
511
|
-
);
|
|
512
|
-
|
|
513
|
-
transaction = new Transaction()
|
|
514
|
-
.add(
|
|
515
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
516
|
-
units: computeUnitLimit,
|
|
517
|
-
}),
|
|
518
|
-
)
|
|
519
|
-
.add(
|
|
520
|
-
ComputeBudgetProgram.setComputeUnitPrice({
|
|
521
|
-
microLamports: computeUnitPrice,
|
|
522
|
-
}),
|
|
523
|
-
);
|
|
524
|
-
|
|
525
|
-
// Add create destination account instruction if needed
|
|
526
|
-
if (needsDestinationAccount) {
|
|
527
|
-
transaction.add(
|
|
528
|
-
createAssociatedTokenAccountInstruction(
|
|
529
|
-
fromPubkey, // payer
|
|
530
|
-
toTokenAccount, // ata
|
|
531
|
-
toPubkey, // owner
|
|
532
|
-
mintPubkey, // mint
|
|
533
|
-
),
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// Add the transfer instruction
|
|
538
|
-
transaction.add(transferInstruction);
|
|
539
|
-
|
|
540
|
-
console.log(
|
|
541
|
-
`SPL Token transfer: ${computeUnitPrice} micro-lamports per CU, limit: ${computeUnitLimit} CU, creating destination: ${needsDestinationAccount}`,
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// Step 5: Get latest blockhash and simulate transaction to verify
|
|
546
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
547
|
-
transaction.recentBlockhash = blockhash;
|
|
548
|
-
transaction.feePayer = fromPubkey;
|
|
549
|
-
|
|
550
|
-
// Step 6: Sign and send transaction with priority fees
|
|
551
|
-
const signedTransaction = await phantom.signAndSendTransaction(transaction);
|
|
552
|
-
|
|
553
|
-
toast.success(`Transaction successful! Signature: ${signedTransaction.signature}`);
|
|
554
|
-
console.log("Transaction sent with priority fees. Signature:", signedTransaction.signature);
|
|
555
|
-
} catch (error: unknown) {
|
|
556
|
-
console.error("Transfer error:", error);
|
|
557
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
558
|
-
if (errorMessage.includes("User rejected")) {
|
|
559
|
-
toast.error("Transaction was cancelled by user");
|
|
560
|
-
} else if (errorMessage.includes("insufficient")) {
|
|
561
|
-
toast.error("Insufficient balance for this transaction");
|
|
562
|
-
} else if (errorMessage.includes("blockhash not found")) {
|
|
563
|
-
toast.error("Network congestion detected. Please try again in a moment.");
|
|
564
|
-
} else {
|
|
565
|
-
toast.error(`Transfer failed: ${errorMessage}`);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
|
|
570
454
|
if (refundTxs.length > 0) {
|
|
571
455
|
return (
|
|
572
456
|
<>
|
|
@@ -827,7 +711,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
827
711
|
{order.status === "executing" && (
|
|
828
712
|
<TransactionDetails
|
|
829
713
|
title={
|
|
830
|
-
order.type === "swap"
|
|
714
|
+
order.type === "swap" || order.type === "x402_swap"
|
|
831
715
|
? "Processing Swap"
|
|
832
716
|
: order.type === "mint_nft"
|
|
833
717
|
? "Minting NFT"
|
|
@@ -837,7 +721,9 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
837
721
|
? "Funding Tournament"
|
|
838
722
|
: order.type === "hype_duel"
|
|
839
723
|
? "Depositing Hype Duel"
|
|
840
|
-
: "
|
|
724
|
+
: order.type === "custom" || order.type === "custom_exact_in"
|
|
725
|
+
? "Executing Contract"
|
|
726
|
+
: "Processing Bridge"
|
|
841
727
|
}
|
|
842
728
|
chainId={order.dstChain}
|
|
843
729
|
isProcessing={true}
|
|
@@ -50,8 +50,7 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({
|
|
|
50
50
|
order.type === "mint_nft" ||
|
|
51
51
|
order.type === "join_tournament" ||
|
|
52
52
|
order.type === "fund_tournament" ||
|
|
53
|
-
order.type === "custom"
|
|
54
|
-
order.type === "hype_duel"
|
|
53
|
+
order.type === "custom"
|
|
55
54
|
? "0"
|
|
56
55
|
: order.payload.expectedDstAmount.toString();
|
|
57
56
|
|
|
@@ -104,7 +103,7 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({
|
|
|
104
103
|
? "Join tournament"
|
|
105
104
|
: order.type === "fund_tournament"
|
|
106
105
|
? "Fund tournament"
|
|
107
|
-
: order.type === "custom"
|
|
106
|
+
: order.type === "custom" || order.type === "custom_exact_in"
|
|
108
107
|
? order.metadata.action
|
|
109
108
|
? capitalizeFirstLetter(order.metadata.action)
|
|
110
109
|
: "Contract execution"
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
import { ChevronsUpDown } from "lucide-react";
|
|
4
4
|
import { useEffect, useRef } from "react";
|
|
5
5
|
import { NumericFormat } from "react-number-format";
|
|
6
|
+
import { formatUnits } from "viem";
|
|
6
7
|
|
|
7
8
|
import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend";
|
|
8
9
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
9
|
-
import {
|
|
10
|
+
import { getNativeRequired } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
11
|
+
import { isNativeToken } from "@b3dotfun/sdk/anyspend/utils/token";
|
|
12
|
+
import { Button, useTokenBalance } from "@b3dotfun/sdk/global-account/react";
|
|
10
13
|
import { cn } from "@b3dotfun/sdk/shared/utils";
|
|
11
14
|
import { TokenSelector } from "@relayprotocol/relay-kit-ui";
|
|
12
15
|
import { ChainTokenIcon } from "./ChainTokenIcon";
|
|
@@ -28,6 +31,7 @@ export function OrderTokenAmount({
|
|
|
28
31
|
amountClassName,
|
|
29
32
|
tokenSelectClassName,
|
|
30
33
|
onTokenSelect,
|
|
34
|
+
walletAddress,
|
|
31
35
|
}: {
|
|
32
36
|
disabled?: boolean;
|
|
33
37
|
inputValue: string;
|
|
@@ -45,25 +49,57 @@ export function OrderTokenAmount({
|
|
|
45
49
|
amountClassName?: string;
|
|
46
50
|
tokenSelectClassName?: string;
|
|
47
51
|
onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
|
|
52
|
+
walletAddress?: string | undefined;
|
|
48
53
|
}) {
|
|
49
54
|
// Track previous token to detect changes
|
|
50
55
|
const prevTokenRef = useRef<string>(token.address);
|
|
56
|
+
// Track if initial balance has been set
|
|
57
|
+
const initialBalanceSetRef = useRef(false);
|
|
58
|
+
|
|
59
|
+
// Only get token balance when context is "from" (for setting max amount)
|
|
60
|
+
const { rawBalance } = useTokenBalance({
|
|
61
|
+
token,
|
|
62
|
+
address: context === "from" && walletAddress ? walletAddress : undefined,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Reset balance ref when token address or chain changes
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
initialBalanceSetRef.current = false;
|
|
68
|
+
}, [token.address, token.chainId]);
|
|
51
69
|
|
|
52
70
|
useEffect(() => {
|
|
53
|
-
// Only
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
71
|
+
// Only handle "from" context
|
|
72
|
+
if (context !== "from") return;
|
|
73
|
+
|
|
74
|
+
// Check if token changed or if this is the initial load with balance
|
|
75
|
+
const isTokenChanged = prevTokenRef.current !== token.address;
|
|
76
|
+
const isInitialLoad = !initialBalanceSetRef.current && rawBalance;
|
|
77
|
+
|
|
78
|
+
if ((isTokenChanged || isInitialLoad) && rawBalance) {
|
|
79
|
+
console.log(
|
|
80
|
+
`Setting max balance - Token: ${token.address}, Changed: ${isTokenChanged}, Initial: ${isInitialLoad}`,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Calculate max amount with gas reserve for native tokens
|
|
84
|
+
let maxAmount: bigint;
|
|
85
|
+
|
|
86
|
+
if (isNativeToken(token.address)) {
|
|
87
|
+
const gasReserve = getNativeRequired(token.chainId);
|
|
88
|
+
// Ensure we don't go negative
|
|
89
|
+
maxAmount = rawBalance > gasReserve ? rawBalance - gasReserve : BigInt(0);
|
|
90
|
+
} else {
|
|
91
|
+
// For ERC20 tokens, use full balance
|
|
92
|
+
maxAmount = rawBalance;
|
|
61
93
|
}
|
|
62
94
|
|
|
63
|
-
//
|
|
95
|
+
// Set the max amount as input value
|
|
96
|
+
onChangeInput(formatUnits(maxAmount, token.decimals));
|
|
97
|
+
|
|
98
|
+
// Update refs
|
|
64
99
|
prevTokenRef.current = token.address;
|
|
100
|
+
initialBalanceSetRef.current = true;
|
|
65
101
|
}
|
|
66
|
-
}, [token.address, chainId, context, onChangeInput]);
|
|
102
|
+
}, [token.address, token.chainId, token.decimals, chainId, context, onChangeInput, rawBalance]);
|
|
67
103
|
|
|
68
104
|
const handleTokenSelect = (newToken: any) => {
|
|
69
105
|
const token: components["schemas"]["Token"] = {
|
|
@@ -97,13 +133,8 @@ export function OrderTokenAmount({
|
|
|
97
133
|
// Set the chain ID first
|
|
98
134
|
setChainId(newToken.chainId);
|
|
99
135
|
|
|
100
|
-
// Then set the new token
|
|
136
|
+
// Then set the new token - the useEffect will handle setting the max balance
|
|
101
137
|
setToken(token);
|
|
102
|
-
|
|
103
|
-
// If this is the source token, reset the amount immediately
|
|
104
|
-
if (context === "from") {
|
|
105
|
-
onChangeInput("0.01");
|
|
106
|
-
}
|
|
107
138
|
};
|
|
108
139
|
|
|
109
140
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
2
|
import { getNativeRequired } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
3
3
|
import { isNativeToken } from "@b3dotfun/sdk/anyspend/utils/token";
|
|
4
|
-
import {
|
|
4
|
+
import { useTokenBalanceDirect } from "@b3dotfun/sdk/global-account/react";
|
|
5
5
|
import { formatUnits } from "viem";
|
|
6
6
|
|
|
7
7
|
export function TokenBalance({
|
|
@@ -13,7 +13,7 @@ export function TokenBalance({
|
|
|
13
13
|
walletAddress: string | undefined;
|
|
14
14
|
onChangeInput: (value: string) => void;
|
|
15
15
|
}) {
|
|
16
|
-
const { rawBalance, formattedBalance, isLoading } =
|
|
16
|
+
const { rawBalance, formattedBalance, isLoading } = useTokenBalanceDirect({
|
|
17
17
|
token,
|
|
18
18
|
address: walletAddress,
|
|
19
19
|
});
|
|
@@ -3,11 +3,15 @@ export { AnySpend } from "./AnySpend";
|
|
|
3
3
|
export { AnySpendBondKit } from "./AnySpendBondKit";
|
|
4
4
|
export { AnySpendBuySpin } from "./AnySpendBuySpin";
|
|
5
5
|
export { AnySpendCustom } from "./AnySpendCustom";
|
|
6
|
+
export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn";
|
|
6
7
|
export * from "./AnySpendFingerprintWrapper";
|
|
7
8
|
export { AnySpendNFT } from "./AnySpendNFT";
|
|
9
|
+
export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
|
|
8
10
|
export { AnySpendStakeB3 } from "./AnySpendStakeB3";
|
|
11
|
+
export { AnySpendStakeB3ExactIn } from "./AnySpendStakeB3ExactIn";
|
|
12
|
+
export { AnySpendStakeUpside } from "./AnySpendStakeUpside";
|
|
13
|
+
export { AnySpendStakeUpsideExactIn } from "./AnySpendStakeUpsideExactIn";
|
|
9
14
|
export { AnySpendTournament } from "./AnySpendTournament";
|
|
10
|
-
export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
|
|
11
15
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
|
|
12
16
|
|
|
13
17
|
// Common Components
|