@b3dotfun/sdk 0.0.62-alpha.2 → 0.0.62-alpha.3
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/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 +56 -145
- 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/hooks/useAnyspendFlow.js +12 -11
- 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/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/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/esm/anyspend/react/components/AnySpend.js +62 -24
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -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 +57 -146
- 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/hooks/useAnyspendFlow.js +12 -11
- 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/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/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/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/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/global-account/react/hooks/index.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +73 -22
- package/src/anyspend/react/components/AnySpendCustom.tsx +4 -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 +66 -188
- 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/hooks/useAnyspendFlow.ts +13 -10
- 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/global-account/react/hooks/index.ts +2 -1
- package/src/global-account/react/hooks/useTokenBalanceDirect.tsx +84 -0
- package/src/global-account/react/hooks/useTokenFromUrl.tsx +6 -5
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { components } from "../../../types/api";
|
|
2
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
2
3
|
interface CryptoReceiveSectionProps {
|
|
3
4
|
isDepositMode?: boolean;
|
|
4
5
|
isBuyMode?: boolean;
|
|
5
6
|
selectedRecipientAddress?: string;
|
|
6
7
|
recipientName?: string;
|
|
7
8
|
onSelectRecipient: () => void;
|
|
9
|
+
setRecipientAddress?: (address: string | undefined) => void;
|
|
10
|
+
recipientAddressFromProps?: string;
|
|
11
|
+
globalAddress?: string;
|
|
8
12
|
dstAmount: string;
|
|
9
13
|
dstToken: components["schemas"]["Token"];
|
|
10
14
|
selectedDstChainId?: number;
|
|
@@ -17,6 +21,7 @@ interface CryptoReceiveSectionProps {
|
|
|
17
21
|
dstTokenLogoURI?: string;
|
|
18
22
|
onShowPointsDetail?: () => void;
|
|
19
23
|
onShowFeeDetail?: () => void;
|
|
24
|
+
selectedCryptoPaymentMethod?: CryptoPaymentMethodType;
|
|
20
25
|
}
|
|
21
|
-
export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, selectedRecipientAddress, recipientName, onSelectRecipient, setRecipientAddress, recipientAddressFromProps, globalAddress, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, selectedCryptoPaymentMethod, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
22
27
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
|
-
export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect, canEditAmount, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, }: {
|
|
2
|
+
export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect, canEditAmount, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, walletAddress, }: {
|
|
3
3
|
disabled?: boolean;
|
|
4
4
|
inputValue: string;
|
|
5
5
|
onChangeInput: (value: string) => void;
|
|
@@ -18,4 +18,5 @@ export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput,
|
|
|
18
18
|
onTokenSelect?: (token: components["schemas"]["Token"], event: {
|
|
19
19
|
preventDefault: () => void;
|
|
20
20
|
}) => void;
|
|
21
|
+
walletAddress?: string | undefined;
|
|
21
22
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
|
|
2
|
+
interface UseAutoSelectCryptoPaymentMethodParams {
|
|
3
|
+
/** Current payment type (crypto or fiat) */
|
|
4
|
+
paymentType?: "crypto" | "fiat";
|
|
5
|
+
/** Currently selected payment method */
|
|
6
|
+
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
7
|
+
/** Function to update the selected payment method */
|
|
8
|
+
setSelectedCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
|
|
9
|
+
/** Whether user has enough balance to pay */
|
|
10
|
+
hasEnoughBalance: boolean;
|
|
11
|
+
/** Whether balance is still loading */
|
|
12
|
+
isBalanceLoading: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Custom hook to automatically select appropriate crypto payment method
|
|
16
|
+
* based on available wallets and balance.
|
|
17
|
+
*
|
|
18
|
+
* Auto-selection logic:
|
|
19
|
+
* - Only auto-selects when payment method is NONE (doesn't override user choices)
|
|
20
|
+
* - If EOA/Wagmi wallet connected + has balance → CONNECT_WALLET
|
|
21
|
+
* - If EOA/Wagmi wallet connected + insufficient balance → TRANSFER_CRYPTO
|
|
22
|
+
* - If only Global wallet available → GLOBAL_WALLET
|
|
23
|
+
* - If no wallets → remains NONE
|
|
24
|
+
*/
|
|
25
|
+
export declare function useAutoSelectCryptoPaymentMethod({ paymentType, selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod, hasEnoughBalance, isBalanceLoading, }: UseAutoSelectCryptoPaymentMethodParams): void;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook that automatically sets the active thirdweb wallet when a wagmi wallet connects.
|
|
3
|
+
*
|
|
4
|
+
* This is useful for syncing wagmi wallet connections with thirdweb's wallet system,
|
|
5
|
+
* ensuring that when users connect via wagmi, the active wallet is properly set.
|
|
6
|
+
*
|
|
7
|
+
* Place this hook in components that stay mounted throughout the user flow
|
|
8
|
+
* (not in components that unmount during navigation).
|
|
9
|
+
*/
|
|
10
|
+
export declare function useAutoSetActiveWalletFromWagmi(): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
|
|
2
|
+
interface UseConnectedWalletDisplayResult {
|
|
3
|
+
walletAddress: string | undefined;
|
|
4
|
+
shouldShowConnectedEOA: boolean;
|
|
5
|
+
shouldShowWagmiWallet: boolean;
|
|
6
|
+
isWalletDuplicated: boolean;
|
|
7
|
+
suggestedPaymentMethod: CryptoPaymentMethodType;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Custom hook to determine which wallet to display and its address
|
|
11
|
+
* Handles logic for showing EOA wallet, wagmi wallet, or global wallet based on payment method
|
|
12
|
+
*/
|
|
13
|
+
export declare function useConnectedWalletDisplay(selectedCryptoPaymentMethod?: CryptoPaymentMethodType): UseConnectedWalletDisplayResult;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
interface UsePhantomTransferParams {
|
|
2
|
+
/** RPC endpoint URL for Solana network */
|
|
3
|
+
rpcEndpoint?: string;
|
|
4
|
+
}
|
|
5
|
+
interface PhantomTransferParams {
|
|
6
|
+
/** Amount in lamports (for SOL) or smallest token unit (for SPL tokens) */
|
|
7
|
+
amountLamports: string;
|
|
8
|
+
/** Token address (use "11111111111111111111111111111111" for native SOL) */
|
|
9
|
+
tokenAddress: string;
|
|
10
|
+
/** Recipient address */
|
|
11
|
+
recipientAddress: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Custom hook for handling Phantom wallet transfers on Solana.
|
|
15
|
+
* Supports both native SOL and SPL token transfers with automatic priority fee calculation.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* const { initiateTransfer, isPhantomAvailable } = usePhantomTransfer();
|
|
20
|
+
*
|
|
21
|
+
* await initiateTransfer({
|
|
22
|
+
* amountLamports: "1000000000", // 1 SOL
|
|
23
|
+
* tokenAddress: "11111111111111111111111111111111",
|
|
24
|
+
* recipientAddress: "..."
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function usePhantomTransfer({ rpcEndpoint }?: UsePhantomTransferParams): {
|
|
29
|
+
/** Function to initiate a transfer */
|
|
30
|
+
initiateTransfer: ({ amountLamports, tokenAddress, recipientAddress }: PhantomTransferParams) => Promise<void>;
|
|
31
|
+
/** Whether Phantom wallet is available (installed) */
|
|
32
|
+
isPhantomAvailable: any;
|
|
33
|
+
/** Get the currently connected Phantom wallet address */
|
|
34
|
+
getConnectedAddress: () => any;
|
|
35
|
+
};
|
|
36
|
+
export {};
|
|
@@ -32,11 +32,12 @@ export { useSearchParamsSSR } from "./useSearchParamsSSR";
|
|
|
32
32
|
export { useSimBalance } from "./useSimBalance";
|
|
33
33
|
export { useSiwe } from "./useSiwe";
|
|
34
34
|
export { useTokenBalance } from "./useTokenBalance";
|
|
35
|
+
export { useTokenBalanceDirect } from "./useTokenBalanceDirect";
|
|
35
36
|
export { useTokenBalancesByChain } from "./useTokenBalancesByChain";
|
|
36
37
|
export { useTokenData } from "./useTokenData";
|
|
37
38
|
export { useTokenFromUrl } from "./useTokenFromUrl";
|
|
38
39
|
export { useTokenPrice } from "./useTokenPrice";
|
|
39
40
|
export { useTokenPriceWithFallback } from "./useTokenPriceWithFallback";
|
|
40
41
|
export { useTokensFromAddress } from "./useTokensFromAddress";
|
|
41
|
-
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute";
|
|
42
42
|
export { useURLParams } from "./useURLParams";
|
|
43
|
+
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
|
+
interface UseTokenBalanceProps {
|
|
3
|
+
token: components["schemas"]["Token"];
|
|
4
|
+
address?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TokenBalanceResult {
|
|
7
|
+
rawBalance: bigint | null;
|
|
8
|
+
formattedBalance: string;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function useTokenBalanceDirect({ token, address }: UseTokenBalanceProps): TokenBalanceResult;
|
|
12
|
+
export {};
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
useProfile,
|
|
18
18
|
useRouter,
|
|
19
19
|
useSearchParamsSSR,
|
|
20
|
+
useTokenBalanceDirect,
|
|
20
21
|
useTokenData,
|
|
21
22
|
useTokenFromUrl,
|
|
22
23
|
} from "@b3dotfun/sdk/global-account/react";
|
|
@@ -30,17 +31,19 @@ import { toast } from "sonner";
|
|
|
30
31
|
import { parseUnits } from "viem";
|
|
31
32
|
import { base, mainnet } from "viem/chains";
|
|
32
33
|
import { components } from "../../types/api";
|
|
34
|
+
import { useAutoSelectCryptoPaymentMethod } from "../hooks/useAutoSelectCryptoPaymentMethod";
|
|
35
|
+
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
|
|
33
36
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
34
37
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
|
|
35
38
|
import { CryptoPaySection } from "./common/CryptoPaySection";
|
|
36
39
|
import { CryptoReceiveSection } from "./common/CryptoReceiveSection";
|
|
40
|
+
import { FeeDetailPanel } from "./common/FeeDetailPanel";
|
|
37
41
|
import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod";
|
|
38
42
|
import { OrderDetails, OrderDetailsLoadingView } from "./common/OrderDetails";
|
|
39
43
|
import { OrderHistory } from "./common/OrderHistory";
|
|
40
44
|
import { PanelOnramp } from "./common/PanelOnramp";
|
|
41
45
|
import { PanelOnrampPayment } from "./common/PanelOnrampPayment";
|
|
42
46
|
import { PointsDetailPanel } from "./common/PointsDetailPanel";
|
|
43
|
-
import { FeeDetailPanel } from "./common/FeeDetailPanel";
|
|
44
47
|
import { RecipientSelection } from "./common/RecipientSelection";
|
|
45
48
|
import { TabSection } from "./common/TabSection";
|
|
46
49
|
|
|
@@ -437,14 +440,38 @@ function AnySpendInner({
|
|
|
437
440
|
// State for recipient selection
|
|
438
441
|
const [recipientAddress, setRecipientAddress] = useState<string | undefined>();
|
|
439
442
|
|
|
440
|
-
const { address: globalAddress, wallet: globalWallet } = useAccountWallet();
|
|
443
|
+
const { address: globalAddress, wallet: globalWallet, connectedEOAWallet } = useAccountWallet();
|
|
441
444
|
const recipientProfile = useProfile({ address: recipientAddress, fresh: true });
|
|
442
445
|
const recipientName = recipientProfile.data?.name;
|
|
443
446
|
|
|
444
|
-
//
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
447
|
+
// Auto-set active wallet from wagmi
|
|
448
|
+
useAutoSetActiveWalletFromWagmi();
|
|
449
|
+
|
|
450
|
+
// Check token balance for crypto payments
|
|
451
|
+
const { rawBalance, isLoading: isBalanceLoading } = useTokenBalanceDirect({
|
|
452
|
+
token: selectedSrcToken,
|
|
453
|
+
address: connectedEOAWallet?.getAccount()?.address,
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Check if user has enough balanceuseAutoSetActiveWalletFromWagmi
|
|
457
|
+
const hasEnoughBalance = useMemo(() => {
|
|
458
|
+
if (!rawBalance || isBalanceLoading || activeTab !== "crypto") return false;
|
|
459
|
+
try {
|
|
460
|
+
const requiredAmount = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals);
|
|
461
|
+
return rawBalance >= requiredAmount;
|
|
462
|
+
} catch {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
}, [rawBalance, srcAmount, selectedSrcToken.decimals, isBalanceLoading, activeTab]);
|
|
466
|
+
|
|
467
|
+
// Auto-select crypto payment method based on available wallets and balance
|
|
468
|
+
useAutoSelectCryptoPaymentMethod({
|
|
469
|
+
paymentType: activeTab,
|
|
470
|
+
selectedCryptoPaymentMethod,
|
|
471
|
+
setSelectedCryptoPaymentMethod,
|
|
472
|
+
hasEnoughBalance,
|
|
473
|
+
isBalanceLoading,
|
|
474
|
+
});
|
|
448
475
|
|
|
449
476
|
// Get geo-based onramp options for fiat payments
|
|
450
477
|
const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
|
|
@@ -624,17 +651,34 @@ function AnySpendInner({
|
|
|
624
651
|
if (isSameChainSameToken)
|
|
625
652
|
return { text: "Select a different token or chain", disable: true, error: false, loading: false };
|
|
626
653
|
if (isLoadingAnyspendQuote) return { text: "Loading quote...", disable: true, error: false, loading: true };
|
|
627
|
-
if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
628
654
|
if (isCreatingOrder || isCreatingOnrampOrder)
|
|
629
655
|
return { text: "Creating order...", disable: true, error: false, loading: true };
|
|
630
656
|
if (!anyspendQuote || !anyspendQuote.success)
|
|
631
657
|
return { text: "No quote found", disable: true, error: false, loading: false };
|
|
632
658
|
|
|
659
|
+
if (activeTab === "fiat") {
|
|
660
|
+
// For fiat: check recipient first, then payment method
|
|
661
|
+
if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
662
|
+
|
|
663
|
+
// If no fiat payment method selected, show "Select payment method"
|
|
664
|
+
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
665
|
+
return { text: "Select payment method", disable: false, error: false, loading: false };
|
|
666
|
+
}
|
|
667
|
+
// If payment method is selected, show "Buy"
|
|
668
|
+
return { text: "Buy", disable: false, error: false, loading: false };
|
|
669
|
+
}
|
|
670
|
+
|
|
633
671
|
if (activeTab === "crypto") {
|
|
672
|
+
// For crypto: check payment method first, then recipient
|
|
673
|
+
|
|
634
674
|
// If no payment method selected, show "Choose payment method"
|
|
635
675
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
636
676
|
return { text: "Choose payment method", disable: false, error: false, loading: false };
|
|
637
677
|
}
|
|
678
|
+
|
|
679
|
+
// Check recipient after payment method
|
|
680
|
+
if (!recipientAddress) return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
681
|
+
|
|
638
682
|
// If payment method selected, show appropriate action
|
|
639
683
|
if (
|
|
640
684
|
selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
@@ -647,15 +691,6 @@ function AnySpendInner({
|
|
|
647
691
|
}
|
|
648
692
|
}
|
|
649
693
|
|
|
650
|
-
if (activeTab === "fiat") {
|
|
651
|
-
// If no fiat payment method selected, show "Select payment method"
|
|
652
|
-
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
653
|
-
return { text: "Select payment method", disable: false, error: false, loading: false };
|
|
654
|
-
}
|
|
655
|
-
// If payment method is selected, show "Buy"
|
|
656
|
-
return { text: "Buy", disable: false, error: false, loading: false };
|
|
657
|
-
}
|
|
658
|
-
|
|
659
694
|
return { text: "Buy", disable: false, error: false, loading: false };
|
|
660
695
|
}, [
|
|
661
696
|
activeInputAmountInWei,
|
|
@@ -674,16 +709,18 @@ function AnySpendInner({
|
|
|
674
709
|
const onMainButtonClick = async () => {
|
|
675
710
|
if (btnInfo.disable) return;
|
|
676
711
|
|
|
677
|
-
if (!recipientAddress) {
|
|
678
|
-
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
712
|
try {
|
|
683
713
|
invariant(anyspendQuote, "Relay price is not found");
|
|
684
|
-
invariant(recipientAddress, "Recipient address is not found");
|
|
685
714
|
|
|
686
715
|
if (activeTab === "fiat") {
|
|
716
|
+
// For fiat: check recipient first
|
|
717
|
+
if (!recipientAddress) {
|
|
718
|
+
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
invariant(recipientAddress, "Recipient address is not found");
|
|
723
|
+
|
|
687
724
|
// If no fiat payment method selected, show payment method selection
|
|
688
725
|
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
689
726
|
navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
|
|
@@ -695,6 +732,8 @@ function AnySpendInner({
|
|
|
695
732
|
}
|
|
696
733
|
|
|
697
734
|
if (activeTab === "crypto") {
|
|
735
|
+
// For crypto: check payment method first, then recipient
|
|
736
|
+
|
|
698
737
|
// If no payment method selected, show payment method selection
|
|
699
738
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
700
739
|
console.log("No payment method selected, showing selection panel");
|
|
@@ -702,6 +741,14 @@ function AnySpendInner({
|
|
|
702
741
|
return;
|
|
703
742
|
}
|
|
704
743
|
|
|
744
|
+
// Check recipient after payment method
|
|
745
|
+
if (!recipientAddress) {
|
|
746
|
+
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
invariant(recipientAddress, "Recipient address is not found");
|
|
751
|
+
|
|
705
752
|
// If payment method is selected, create order with payment method info
|
|
706
753
|
if (
|
|
707
754
|
selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
@@ -1057,6 +1104,9 @@ function AnySpendInner({
|
|
|
1057
1104
|
selectedRecipientAddress={recipientAddress}
|
|
1058
1105
|
recipientName={recipientName || undefined}
|
|
1059
1106
|
onSelectRecipient={() => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward")}
|
|
1107
|
+
setRecipientAddress={setRecipientAddress}
|
|
1108
|
+
recipientAddressFromProps={recipientAddressFromProps}
|
|
1109
|
+
globalAddress={globalAddress}
|
|
1060
1110
|
dstAmount={dstAmount}
|
|
1061
1111
|
dstToken={selectedDstToken}
|
|
1062
1112
|
selectedDstChainId={selectedDstChainId}
|
|
@@ -1070,6 +1120,7 @@ function AnySpendInner({
|
|
|
1070
1120
|
anyspendQuote={anyspendQuote}
|
|
1071
1121
|
onShowPointsDetail={() => navigateToPanel(PanelView.POINTS_DETAIL, "forward")}
|
|
1072
1122
|
onShowFeeDetail={() => navigateToPanel(PanelView.FEE_DETAIL, "forward")}
|
|
1123
|
+
selectedCryptoPaymentMethod={selectedCryptoPaymentMethod}
|
|
1073
1124
|
/>
|
|
1074
1125
|
)}
|
|
1075
1126
|
</div>
|
|
@@ -44,6 +44,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
44
44
|
import { toast } from "sonner";
|
|
45
45
|
import { base } from "viem/chains";
|
|
46
46
|
import { useFeatureFlags } from "../contexts/FeatureFlagsContext";
|
|
47
|
+
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
|
|
47
48
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
48
49
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
|
|
49
50
|
import { FeeBreakDown } from "./common/FeeBreakDown";
|
|
@@ -241,6 +242,9 @@ function AnySpendCustomInner({
|
|
|
241
242
|
const searchParams = useSearchParamsSSR();
|
|
242
243
|
const router = useRouter();
|
|
243
244
|
|
|
245
|
+
// Auto-set active wallet from wagmi
|
|
246
|
+
useAutoSetActiveWalletFromWagmi();
|
|
247
|
+
|
|
244
248
|
const [activePanel, setActivePanel] = useState<PanelView>(
|
|
245
249
|
loadOrder ? PanelView.ORDER_DETAILS : PanelView.CONFIRM_ORDER,
|
|
246
250
|
);
|
|
@@ -6,6 +6,7 @@ import invariant from "invariant";
|
|
|
6
6
|
import { motion } from "motion/react";
|
|
7
7
|
import { useEffect, useMemo, useRef } from "react";
|
|
8
8
|
import { toast } from "sonner";
|
|
9
|
+
import { useActiveWallet, useSetActiveWallet } from "thirdweb/react";
|
|
9
10
|
import { base } from "viem/chains";
|
|
10
11
|
import { PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow";
|
|
11
12
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
@@ -17,11 +18,10 @@ import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaym
|
|
|
17
18
|
import { OrderDetails } from "./common/OrderDetails";
|
|
18
19
|
import { PointsDetailPanel } from "./common/PointsDetailPanel";
|
|
19
20
|
import { RecipientSelection } from "./common/RecipientSelection";
|
|
20
|
-
import { useActiveWallet, useSetActiveWallet } from "thirdweb/react";
|
|
21
21
|
|
|
22
22
|
import { ArrowDown, Loader2 } from "lucide-react";
|
|
23
|
-
import { PanelOnramp } from "./common/PanelOnramp";
|
|
24
23
|
import { useGlobalWalletState } from "../../utils";
|
|
24
|
+
import { PanelOnramp } from "./common/PanelOnramp";
|
|
25
25
|
|
|
26
26
|
const SLIPPAGE_PERCENT = 3;
|
|
27
27
|
|
|
@@ -286,9 +286,12 @@ function AnySpendDepositHypeInner({
|
|
|
286
286
|
<CryptoReceiveSection
|
|
287
287
|
isDepositMode={false}
|
|
288
288
|
isBuyMode={true}
|
|
289
|
-
selectedRecipientAddress={
|
|
289
|
+
selectedRecipientAddress={selectedRecipientAddress}
|
|
290
290
|
recipientName={recipientName || undefined}
|
|
291
291
|
onSelectRecipient={() => setActivePanel(PanelView.RECIPIENT_SELECTION)}
|
|
292
|
+
setRecipientAddress={setSelectedRecipientAddress}
|
|
293
|
+
recipientAddressFromProps={recipientAddress}
|
|
294
|
+
globalAddress={globalAddress}
|
|
292
295
|
dstAmount={dstAmount}
|
|
293
296
|
dstToken={B3_TOKEN}
|
|
294
297
|
dstTokenSymbol={HYPE_TOKEN_DETAILS.SYMBOL}
|
|
@@ -304,6 +307,7 @@ function AnySpendDepositHypeInner({
|
|
|
304
307
|
anyspendQuote={anyspendQuote}
|
|
305
308
|
onShowPointsDetail={() => setActivePanel(PanelView.POINTS_DETAIL)}
|
|
306
309
|
onShowFeeDetail={() => setActivePanel(PanelView.FEE_DETAIL)}
|
|
310
|
+
selectedCryptoPaymentMethod={selectedCryptoPaymentMethod}
|
|
307
311
|
/>
|
|
308
312
|
)}
|
|
309
313
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useProfile, useTokenData } from "@b3dotfun/sdk/global-account/react";
|
|
2
2
|
import { formatUsername } from "@b3dotfun/sdk/shared/utils";
|
|
3
3
|
import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
4
4
|
import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
|
|
@@ -6,6 +6,7 @@ import { ChevronRight, Info } from "lucide-react";
|
|
|
6
6
|
import { motion } from "motion/react";
|
|
7
7
|
import { useEffect, useRef } from "react";
|
|
8
8
|
import { components } from "../../../types/api";
|
|
9
|
+
import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
|
|
9
10
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
10
11
|
import { OrderTokenAmount } from "./OrderTokenAmount";
|
|
11
12
|
import { TokenBalance } from "./TokenBalance";
|
|
@@ -46,14 +47,10 @@ export function CryptoPaySection({
|
|
|
46
47
|
onTokenSelect,
|
|
47
48
|
onShowFeeDetail,
|
|
48
49
|
}: CryptoPaySectionProps) {
|
|
49
|
-
const { connectedSmartWallet, connectedEOAWallet } = useAccountWallet();
|
|
50
50
|
const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
|
|
51
51
|
|
|
52
|
-
//
|
|
53
|
-
const walletAddress =
|
|
54
|
-
selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
55
|
-
? connectedSmartWallet?.getAccount()?.address
|
|
56
|
-
: connectedEOAWallet?.getAccount()?.address;
|
|
52
|
+
// Use custom hook to determine wallet address based on payment method
|
|
53
|
+
const { walletAddress } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
|
|
57
54
|
|
|
58
55
|
const { data: profileData } = useProfile({ address: walletAddress });
|
|
59
56
|
const connectedName = profileData?.displayName;
|
|
@@ -137,6 +134,7 @@ export function CryptoPaySection({
|
|
|
137
134
|
</div>
|
|
138
135
|
<OrderTokenAmount
|
|
139
136
|
address={walletAddress}
|
|
137
|
+
walletAddress={walletAddress}
|
|
140
138
|
context="from"
|
|
141
139
|
inputValue={srcAmount}
|
|
142
140
|
onChangeInput={value => {
|
|
@@ -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)" }}
|