@b3dotfun/sdk 0.0.35 → 0.0.36
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 +5 -3
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +2 -2
- package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +5 -2
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +58 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +22 -15
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +12 -4
- package/dist/cjs/anyspend/react/components/common/PaySection.d.ts +2 -6
- package/dist/cjs/anyspend/react/components/common/PaySection.js +10 -15
- package/dist/cjs/anyspend/react/components/index.d.ts +2 -2
- package/dist/cjs/anyspend/react/components/index.js +5 -5
- package/dist/cjs/global-account/bsmnt.d.ts +2 -0
- package/dist/cjs/global-account/bsmnt.js +42 -1
- package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.js +55 -0
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +108 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +9 -1
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +21 -11
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +19 -5
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +6 -6
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3.js +2 -2
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -13
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -3
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +0 -3
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +0 -3
- package/dist/cjs/global-account/react/components/icons/AppleIcon.d.ts +9 -0
- package/dist/cjs/global-account/react/components/icons/AppleIcon.js +8 -0
- package/dist/cjs/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
- package/dist/cjs/global-account/react/components/icons/DiscordIcon.js +8 -0
- package/dist/cjs/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
- package/dist/cjs/global-account/react/components/icons/FarcasterIcon.js +8 -0
- package/dist/cjs/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
- package/dist/cjs/global-account/react/components/icons/GoogleIcon.js +8 -0
- package/dist/cjs/global-account/react/components/icons/XIcon.d.ts +9 -0
- package/dist/cjs/global-account/react/components/icons/XIcon.js +8 -0
- package/dist/cjs/global-account/react/hooks/useAccountWallet.js +3 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +1 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +16 -15
- package/dist/cjs/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/cjs/global-account/react/hooks/useRPMToken.js +11 -0
- package/dist/cjs/global-account/react/stores/useAuthStore.d.ts +2 -4
- package/dist/cjs/global-account/react/stores/useAuthStore.js +2 -4
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +11 -1
- package/dist/cjs/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/dist/cjs/global-account/react/utils/updateAvatar.js +54 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +5 -3
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +2 -2
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +5 -2
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +55 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +22 -15
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +12 -4
- package/dist/esm/anyspend/react/components/common/PaySection.d.ts +2 -6
- package/dist/esm/anyspend/react/components/common/PaySection.js +10 -15
- package/dist/esm/anyspend/react/components/index.d.ts +2 -2
- package/dist/esm/anyspend/react/components/index.js +2 -2
- package/dist/esm/global-account/bsmnt.d.ts +2 -0
- package/dist/esm/global-account/bsmnt.js +39 -0
- package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.js +52 -0
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +102 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +9 -1
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +22 -12
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +20 -6
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +6 -6
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3.js +2 -2
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -13
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -3
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +0 -3
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +0 -3
- package/dist/esm/global-account/react/components/icons/AppleIcon.d.ts +9 -0
- package/dist/esm/global-account/react/components/icons/AppleIcon.js +5 -0
- package/dist/esm/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
- package/dist/esm/global-account/react/components/icons/DiscordIcon.js +5 -0
- package/dist/esm/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
- package/dist/esm/global-account/react/components/icons/FarcasterIcon.js +5 -0
- package/dist/esm/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
- package/dist/esm/global-account/react/components/icons/GoogleIcon.js +5 -0
- package/dist/esm/global-account/react/components/icons/XIcon.d.ts +9 -0
- package/dist/esm/global-account/react/components/icons/XIcon.js +5 -0
- package/dist/esm/global-account/react/hooks/useAccountWallet.js +3 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +1 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +16 -15
- package/dist/esm/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/esm/global-account/react/hooks/useRPMToken.js +8 -0
- package/dist/esm/global-account/react/stores/useAuthStore.d.ts +2 -4
- package/dist/esm/global-account/react/stores/useAuthStore.js +2 -4
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +11 -1
- package/dist/esm/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/dist/esm/global-account/react/utils/updateAvatar.js +18 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
- package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
- package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
- package/dist/types/anyspend/react/components/common/PaySection.d.ts +2 -6
- package/dist/types/anyspend/react/components/index.d.ts +2 -2
- package/dist/types/global-account/bsmnt.d.ts +2 -0
- package/dist/types/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
- package/dist/types/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
- package/dist/types/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
- package/dist/types/global-account/react/components/icons/AppleIcon.d.ts +9 -0
- package/dist/types/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
- package/dist/types/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
- package/dist/types/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
- package/dist/types/global-account/react/components/icons/XIcon.d.ts +9 -0
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +1 -2
- package/dist/types/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/types/global-account/react/stores/useAuthStore.d.ts +2 -4
- package/dist/types/global-account/react/stores/useModalStore.d.ts +11 -1
- package/dist/types/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/package.json +8 -7
- package/src/anyspend/react/components/AnySpend.tsx +7 -6
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +2 -5
- package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +6 -1
- package/src/anyspend/react/components/common/CryptoPaySection.tsx +153 -0
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +80 -43
- package/src/anyspend/react/components/common/OrderDetails.tsx +13 -4
- package/src/anyspend/react/components/common/PaySection.tsx +64 -140
- package/src/anyspend/react/components/index.ts +2 -2
- package/src/global-account/bsmnt.ts +47 -0
- package/src/global-account/react/components/AvatarCreator/AvatarCreator.tsx +90 -0
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +233 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +27 -2
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +40 -18
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +63 -35
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +106 -78
- package/src/global-account/react/components/SignInWithB3/SignInWithB3.tsx +2 -2
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +1 -13
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +1 -3
- package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +0 -3
- package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +0 -3
- package/src/global-account/react/components/icons/AppleIcon.tsx +33 -0
- package/src/global-account/react/components/icons/DiscordIcon.tsx +32 -0
- package/src/global-account/react/components/icons/FarcasterIcon.tsx +37 -0
- package/src/global-account/react/components/icons/GoogleIcon.tsx +40 -0
- package/src/global-account/react/components/icons/XIcon.tsx +28 -0
- package/src/global-account/react/hooks/useAccountWallet.tsx +3 -2
- package/src/global-account/react/hooks/useAuthentication.ts +18 -15
- package/src/global-account/react/hooks/useProfile.ts +1 -1
- package/src/global-account/react/hooks/useRPMToken.ts +17 -0
- package/src/global-account/react/stores/useAuthStore.ts +4 -8
- package/src/global-account/react/stores/useModalStore.ts +13 -1
- package/src/global-account/react/utils/updateAvatar.ts +21 -0
|
@@ -7,8 +7,9 @@ import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
|
7
7
|
import { motion } from "framer-motion";
|
|
8
8
|
import { ChevronRight, Loader2 } from "lucide-react";
|
|
9
9
|
import { useAccount } from "wagmi";
|
|
10
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
10
11
|
import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible.js";
|
|
11
|
-
export default function ConnectWalletPayment({ order, onPayment, txLoading, isSwitchingOrExecuting, phantomWalletAddress, tournament, nft, }) {
|
|
12
|
+
export default function ConnectWalletPayment({ order, onPayment, txLoading, isSwitchingOrExecuting, phantomWalletAddress, tournament, nft, cryptoPaymentMethod, }) {
|
|
12
13
|
const profile = useProfile({ address: order.recipientAddress });
|
|
13
14
|
const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
14
15
|
const { address: connectedAddress } = useAccount();
|
|
@@ -26,7 +27,9 @@ export default function ConnectWalletPayment({ order, onPayment, txLoading, isSw
|
|
|
26
27
|
}
|
|
27
28
|
return (_jsx("div", { className: "flex w-full flex-col items-center gap-6", children: _jsxs(motion.div, { initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.5 }, className: "flex w-full flex-col items-center gap-2", children: [_jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "flex w-5/6 max-w-[400px] items-center gap-2 sm:px-0", disabled: txLoading || isSwitchingOrExecuting, onClick: onPayment, children: txLoading ? (_jsxs(_Fragment, { children: ["Transaction Pending", _jsx(Loader2, { className: "ml-2 h-5 w-5 animate-spin" })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "whitespace-nowrap pl-4 text-lg md:text-sm", children: order.srcChain === RELAY_SOLANA_MAINNET_CHAIN_ID && phantomWalletAddress
|
|
28
29
|
? "Pay from Phantom Wallet"
|
|
29
|
-
:
|
|
30
|
+
: cryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
31
|
+
? "Pay from Global Account"
|
|
32
|
+
: "Pay from Connected Wallet" }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) }), _jsxs("span", { className: "label-style text-as-primary/50 text-xs", children: ["Connected to:", " ", order.srcChain === RELAY_SOLANA_MAINNET_CHAIN_ID && phantomWalletAddress
|
|
30
33
|
? centerTruncate(phantomWalletAddress, 6)
|
|
31
34
|
: centerTruncate(connectedAddress || "")] }), _jsx("div", { className: "mt-4", children: _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }) })] }) }));
|
|
32
35
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { components } from "../../../types/api";
|
|
2
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
3
|
+
interface CryptoPaySectionProps {
|
|
4
|
+
selectedSrcChainId: number;
|
|
5
|
+
setSelectedSrcChainId: (chainId: number) => void;
|
|
6
|
+
selectedSrcToken: components["schemas"]["Token"];
|
|
7
|
+
setSelectedSrcToken: (token: components["schemas"]["Token"]) => void;
|
|
8
|
+
srcAmount: string;
|
|
9
|
+
setSrcAmount: (amount: string) => void;
|
|
10
|
+
setIsSrcInputDirty: (dirty: boolean) => void;
|
|
11
|
+
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
12
|
+
onSelectCryptoPaymentMethod: () => void;
|
|
13
|
+
anyspendQuote?: any;
|
|
14
|
+
}
|
|
15
|
+
export declare function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, }: CryptoPaySectionProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAccountWallet, useProfile, useTokenData } from "../../../../global-account/react/index.js";
|
|
3
|
+
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
4
|
+
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
5
|
+
import { formatDisplayNumber } from "../../../../shared/utils/number.js";
|
|
6
|
+
import { ChevronRight } from "lucide-react";
|
|
7
|
+
import { motion } from "motion/react";
|
|
8
|
+
import { useEffect, useRef } from "react";
|
|
9
|
+
import { useAccount } from "wagmi";
|
|
10
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
11
|
+
import { OrderTokenAmount } from "./OrderTokenAmount.js";
|
|
12
|
+
import { TokenBalance } from "./TokenBalance.js";
|
|
13
|
+
export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, }) {
|
|
14
|
+
const { address: connectedAddress, isConnected } = useAccount();
|
|
15
|
+
const { data: profileData } = useProfile({ address: connectedAddress });
|
|
16
|
+
const connectedName = profileData?.displayName;
|
|
17
|
+
const { address: globalAddress } = useAccountWallet();
|
|
18
|
+
const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
|
|
19
|
+
// Determine which address to use based on payment method
|
|
20
|
+
const walletAddress = selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? globalAddress : connectedAddress;
|
|
21
|
+
// Add ref to track if we've applied metadata
|
|
22
|
+
const appliedSrcMetadataRef = useRef(false);
|
|
23
|
+
// Update source token with metadata
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (selectedSrcToken && srcTokenMetadata && !appliedSrcMetadataRef.current) {
|
|
26
|
+
// Mark as applied
|
|
27
|
+
appliedSrcMetadataRef.current = true;
|
|
28
|
+
const enhancedToken = {
|
|
29
|
+
...selectedSrcToken,
|
|
30
|
+
decimals: srcTokenMetadata.decimals || selectedSrcToken.decimals,
|
|
31
|
+
symbol: srcTokenMetadata.symbol || selectedSrcToken.symbol,
|
|
32
|
+
name: srcTokenMetadata.name || selectedSrcToken.name,
|
|
33
|
+
metadata: {
|
|
34
|
+
...selectedSrcToken.metadata,
|
|
35
|
+
logoURI: srcTokenMetadata?.logoURI || selectedSrcToken.metadata.logoURI,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
setSelectedSrcToken(enhancedToken);
|
|
39
|
+
}
|
|
40
|
+
}, [srcTokenMetadata, selectedSrcToken, setSelectedSrcToken]);
|
|
41
|
+
// Reset source token ref when address/chain changes
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
appliedSrcMetadataRef.current = false;
|
|
44
|
+
}, [selectedSrcToken.address, selectedSrcToken.chainId]);
|
|
45
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (_jsxs(_Fragment, { children: [isConnected ? (_jsx("div", { className: "flex items-center gap-1", children: connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "") })) : ("Connect wallet"), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsxs(_Fragment, { children: ["Global Account", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (_jsxs(_Fragment, { children: ["Transfer crypto", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx(OrderTokenAmount, { address: walletAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
|
|
46
|
+
setIsSrcInputDirty(true);
|
|
47
|
+
setSrcAmount(value);
|
|
48
|
+
}, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
|
|
49
|
+
style: "currency",
|
|
50
|
+
fallback: "",
|
|
51
|
+
}) }), _jsx(TokenBalance, { token: selectedSrcToken, walletAddress: walletAddress, onChangeInput: value => {
|
|
52
|
+
setIsSrcInputDirty(true);
|
|
53
|
+
setSrcAmount(value);
|
|
54
|
+
} })] })] }));
|
|
55
|
+
}
|
|
@@ -13,10 +13,11 @@ export var CryptoPaymentMethodType;
|
|
|
13
13
|
(function (CryptoPaymentMethodType) {
|
|
14
14
|
CryptoPaymentMethodType["NONE"] = "none";
|
|
15
15
|
CryptoPaymentMethodType["CONNECT_WALLET"] = "connect_wallet";
|
|
16
|
+
CryptoPaymentMethodType["GLOBAL_WALLET"] = "global_wallet";
|
|
16
17
|
CryptoPaymentMethodType["TRANSFER_CRYPTO"] = "transfer_crypto";
|
|
17
18
|
})(CryptoPaymentMethodType || (CryptoPaymentMethodType = {}));
|
|
18
19
|
export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentMethod, isCreatingOrder, onBack, onSelectPaymentMethod, }) {
|
|
19
|
-
const { wallet: globalWallet } = useAccountWallet();
|
|
20
|
+
const { wallet: globalWallet, address: globalAddress } = useAccountWallet();
|
|
20
21
|
const { address, isConnected, connector } = useAccount();
|
|
21
22
|
const { connect, connectors, isPending } = useConnect();
|
|
22
23
|
const { disconnect } = useDisconnect();
|
|
@@ -122,20 +123,26 @@ export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentM
|
|
|
122
123
|
}, className: "crypto-payment-method-connect-wallet 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-blue-100", children: _jsx(Wallet, { className: "h-4 w-4 text-blue-600" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Connect wallet" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), _jsxs("button", { onClick: () => {
|
|
123
124
|
setSelectedPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
124
125
|
onSelectPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
125
|
-
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: _jsx(ZapIcon, { className: "h-4 w-4" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), isConnected && (_jsxs("div", { className: "installed-wallets", children: [_jsx("h3", { className: "text-as-primary/80 mb-3 text-sm font-medium", children: "Connected wallets" }),
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
126
|
+
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: _jsx(ZapIcon, { className: "h-4 w-4" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (isConnected || globalAddress) && (_jsxs("div", { className: "installed-wallets", children: [_jsx("h3", { className: "text-as-primary/80 mb-3 text-sm font-medium", children: "Connected wallets" }), _jsxs("div", { className: "space-y-2", children: [isConnected && (_jsx("button", { onClick: () => {
|
|
127
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
128
|
+
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
129
|
+
toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
130
|
+
}, className: cn("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
131
|
+
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
132
|
+
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80"), children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-blue-100", children: _jsx(Wallet, { className: "h-5 w-5 text-blue-600" }) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-as-primary font-semibold", children: connector?.name || "Connected Wallet" }), _jsx("span", { className: "text-as-primary/60 text-sm", children: shortenAddress(address || "") })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET && (_jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" })), _jsx("button", { onClick: e => {
|
|
133
|
+
e.stopPropagation();
|
|
134
|
+
disconnect();
|
|
135
|
+
toast.success("Wallet disconnected");
|
|
136
|
+
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
137
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
138
|
+
}
|
|
139
|
+
}, className: "text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors", children: _jsx(X, { className: "h-4 w-4" }) })] })] }) })), globalAddress && (_jsx("button", { onClick: () => {
|
|
140
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.GLOBAL_WALLET);
|
|
141
|
+
onSelectPaymentMethod(CryptoPaymentMethodType.GLOBAL_WALLET);
|
|
142
|
+
toast.success("Selected B3 Account");
|
|
143
|
+
}, className: cn("crypto-payment-method-global-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
144
|
+
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
145
|
+
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80"), children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [globalWallet?.meta?.icon ? (_jsx("img", { src: globalWallet.meta.icon, alt: "Global Account", className: "h-10 w-10 rounded-full" })) : (_jsx("div", { className: "wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-purple-100", children: _jsx(Wallet, { className: "h-5 w-5 text-purple-600" }) })), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-as-primary font-semibold", children: "Global Account" }), _jsx("span", { className: "text-as-primary/60 text-sm", children: shortenAddress(globalAddress || "") })] })] }), _jsx("div", { className: "flex items-center gap-2", children: selectedPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET && (_jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" })) })] }) }))] })] }))] })] }), showWalletModal &&
|
|
139
146
|
createPortal(_jsx("div", { className: "wallet-connection-modal pointer-events-auto fixed inset-0 z-[9999] flex items-center justify-center bg-black/50", children: _jsxs("div", { className: "max-h-[80vh] w-[400px] max-w-[90vw] overflow-auto rounded-xl bg-white p-6 dark:bg-gray-900", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: isConnected ? "Switch wallet or account" : "Choose wallet to connect" }), _jsx("button", { onClick: handleCloseModal, className: "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx("div", { className: "space-y-4", children: _jsx("div", { className: "space-y-3", children: walletOptions.map(walletOption => {
|
|
140
147
|
const isCurrentWallet = isConnected && connector?.name === walletOption.connector?.name;
|
|
141
148
|
return (_jsx("button", { onClick: async () => {
|
|
@@ -148,7 +148,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
148
148
|
const [txHash, setTxHash] = useState();
|
|
149
149
|
const [showQRCode, setShowQRCode] = useState(false);
|
|
150
150
|
const { isLoading: txLoading, isSuccess: txSuccess } = useWaitForTransactionReceipt({ hash: txHash });
|
|
151
|
-
const { switchChainAndExecuteWithEOA, isSwitchingOrExecuting } = useUnifiedChainSwitchAndExecute();
|
|
151
|
+
const { switchChainAndExecuteWithEOA, switchChainAndExecute, isSwitchingOrExecuting } = useUnifiedChainSwitchAndExecute();
|
|
152
152
|
const roundedUpSrcAmount = useMemo(() => {
|
|
153
153
|
// Display the full transfer amount without rounding since users need to see the exact value they're transferring.
|
|
154
154
|
// Use 21 significant digits (max allowed by Intl.NumberFormat)
|
|
@@ -192,11 +192,18 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
192
192
|
to = order.srcTokenAddress;
|
|
193
193
|
value = BigInt(0);
|
|
194
194
|
}
|
|
195
|
-
|
|
195
|
+
// Use appropriate execution method based on payment method
|
|
196
|
+
let txHash;
|
|
197
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET) {
|
|
198
|
+
txHash = await switchChainAndExecute(order.srcChain, { to, data: txData, value });
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
txHash = await switchChainAndExecuteWithEOA(order.srcChain, { to, data: txData, value });
|
|
202
|
+
}
|
|
196
203
|
if (txHash) {
|
|
197
204
|
setTxHash(txHash);
|
|
198
205
|
}
|
|
199
|
-
}, [order, switchChainAndExecuteWithEOA, depositDeficit]);
|
|
206
|
+
}, [order, switchChainAndExecuteWithEOA, switchChainAndExecute, depositDeficit, effectiveCryptoPaymentMethod]);
|
|
200
207
|
// Main payment handler that triggers chain switch and payment
|
|
201
208
|
const handlePayment = async () => {
|
|
202
209
|
console.log("Initiating payment process. Target chain:", order.srcChain, "Current chain:", walletClient?.chain?.id);
|
|
@@ -475,7 +482,8 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
475
482
|
? `Waiting for payment`
|
|
476
483
|
: `Waiting for deposit ${formattedDepositDeficit} ${srcToken.symbol}`, chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 }))] }) })] }) }), !depositEnoughAmount && order.status !== "expired" && (_jsx(InsufficientDepositPayment, { order: order, srcToken: srcToken, depositDeficit: depositDeficit, phantomWalletAddress: phantomWalletAddress, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, onPayment: handlePayment }))] }));
|
|
477
484
|
}
|
|
478
|
-
return (_jsxs(_Fragment, { children: [statusDisplay === "processing" && (_jsx(_Fragment, { children: order.onrampMetadata ? (_jsx(PaymentVendorUI, { order: order, dstTokenSymbol: dstToken.symbol })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
485
|
+
return (_jsxs(_Fragment, { children: [statusDisplay === "processing" && (_jsx(_Fragment, { children: order.onrampMetadata ? (_jsx(PaymentVendorUI, { order: order, dstTokenSymbol: dstToken.symbol })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
486
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsx(ConnectWalletPayment, { order: order, onPayment: handlePayment, onCancel: handleBack, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, phantomWalletAddress: phantomWalletAddress, tournament: tournament, nft: nft, cryptoPaymentMethod: effectiveCryptoPaymentMethod })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
|
|
479
487
|
// Transfer Crypto Payment Method - Show new card-based UI
|
|
480
488
|
_jsx(TransferCryptoDetails, { order: order, recipientName: recipientName, srcToken: srcToken, dstToken: dstToken, tournament: tournament, nft: nft, onBack: handleBack })) : (_jsxs("div", { className: "relative flex w-full flex-1 flex-col", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-as-primary/50", children: "Please send" }), _jsxs("div", { className: "flex w-full flex-wrap items-center gap-6 sm:justify-between sm:gap-0", children: [_jsx(CopyToClipboard, { text: roundedUpSrcAmount, onCopy: () => {
|
|
481
489
|
toast.success("Copied to clipboard");
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { components } from "../../../types/api";
|
|
2
2
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
3
|
-
|
|
4
|
-
interface PaySectionProps {
|
|
5
|
-
paymentType: "crypto" | "fiat";
|
|
3
|
+
interface CryptoPaySectionProps {
|
|
6
4
|
selectedSrcChainId: number;
|
|
7
5
|
setSelectedSrcChainId: (chainId: number) => void;
|
|
8
6
|
selectedSrcToken: components["schemas"]["Token"];
|
|
@@ -11,10 +9,8 @@ interface PaySectionProps {
|
|
|
11
9
|
setSrcAmount: (amount: string) => void;
|
|
12
10
|
setIsSrcInputDirty: (dirty: boolean) => void;
|
|
13
11
|
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
14
|
-
selectedFiatPaymentMethod: FiatPaymentMethod;
|
|
15
12
|
onSelectCryptoPaymentMethod: () => void;
|
|
16
|
-
onSelectFiatPaymentMethod: () => void;
|
|
17
13
|
anyspendQuote?: any;
|
|
18
14
|
}
|
|
19
|
-
export declare function
|
|
15
|
+
export declare function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, }: CryptoPaySectionProps): import("react/jsx-runtime").JSX.Element;
|
|
20
16
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useProfile, useTokenData } from "../../../../global-account/react/index.js";
|
|
3
3
|
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
4
4
|
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
5
5
|
import { formatDisplayNumber } from "../../../../shared/utils/number.js";
|
|
@@ -8,10 +8,9 @@ import { motion } from "motion/react";
|
|
|
8
8
|
import { useEffect, useRef } from "react";
|
|
9
9
|
import { useAccount } from "wagmi";
|
|
10
10
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
11
|
-
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
12
11
|
import { OrderTokenAmount } from "./OrderTokenAmount.js";
|
|
13
12
|
import { TokenBalance } from "./TokenBalance.js";
|
|
14
|
-
export function
|
|
13
|
+
export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, }) {
|
|
15
14
|
const { address: connectedAddress, isConnected } = useAccount();
|
|
16
15
|
const { data: profileData } = useProfile({ address: connectedAddress });
|
|
17
16
|
const connectedName = profileData?.displayName;
|
|
@@ -40,18 +39,14 @@ export function PaySection({ paymentType, selectedSrcChainId, setSelectedSrcChai
|
|
|
40
39
|
useEffect(() => {
|
|
41
40
|
appliedSrcMetadataRef.current = false;
|
|
42
41
|
}, [selectedSrcToken.address, selectedSrcToken.chainId]);
|
|
43
|
-
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }),
|
|
42
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (_jsxs(_Fragment, { children: [isConnected ? (_jsx("div", { className: "flex items-center gap-1", children: connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "") })) : ("Connect wallet"), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsxs(_Fragment, { children: ["Global Account", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (_jsxs(_Fragment, { children: ["Transfer crypto", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx(OrderTokenAmount, { address: connectedAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
|
|
43
|
+
setIsSrcInputDirty(true);
|
|
44
|
+
setSrcAmount(value);
|
|
45
|
+
}, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
|
|
46
|
+
style: "currency",
|
|
47
|
+
fallback: "",
|
|
48
|
+
}) }), _jsx(TokenBalance, { token: selectedSrcToken, walletAddress: connectedAddress, onChangeInput: value => {
|
|
44
49
|
setIsSrcInputDirty(true);
|
|
45
50
|
setSrcAmount(value);
|
|
46
|
-
}
|
|
47
|
-
style: "currency",
|
|
48
|
-
fallback: "",
|
|
49
|
-
}) }), _jsx(TokenBalance, { token: selectedSrcToken, walletAddress: connectedAddress, onChangeInput: value => {
|
|
50
|
-
setIsSrcInputDirty(true);
|
|
51
|
-
setSrcAmount(value);
|
|
52
|
-
} })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { type: "text", value: srcAmount, onChange: e => setSrcAmount(e.target.value.replace(/[^0-9.]/g, "")), placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
|
|
53
|
-
width: `${Math.max(50, srcAmount.length * 34)}px`,
|
|
54
|
-
} })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "20", "25"].map(value => (_jsxs("button", { onClick: () => setSrcAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmount === value
|
|
55
|
-
? "border-as-border-secondary bg-as-surface-secondary"
|
|
56
|
-
: "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) })] }))] }));
|
|
51
|
+
} })] })] }));
|
|
57
52
|
}
|
|
@@ -4,11 +4,12 @@ export { AnySpendBuySpin } from "./AnySpendBuySpin";
|
|
|
4
4
|
export { AnySpendCustom } from "./AnySpendCustom";
|
|
5
5
|
export * from "./AnySpendFingerprintWrapper";
|
|
6
6
|
export { AnySpendNFT } from "./AnySpendNFT";
|
|
7
|
-
export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
|
|
8
7
|
export { AnySpendStakeB3 } from "./AnySpendStakeB3";
|
|
9
8
|
export { AnySpendTournament } from "./AnySpendTournament";
|
|
9
|
+
export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
|
|
10
10
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
|
|
11
11
|
export { ChainTokenIcon } from "./common/ChainTokenIcon";
|
|
12
|
+
export { CryptoPaySection } from "./common/CryptoPaySection";
|
|
12
13
|
export { CryptoReceiveSection } from "./common/CryptoReceiveSection";
|
|
13
14
|
export { OrderDetails } from "./common/OrderDetails";
|
|
14
15
|
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
|
|
@@ -17,7 +18,6 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem";
|
|
|
17
18
|
export { OrderStatus } from "./common/OrderStatus";
|
|
18
19
|
export { OrderToken } from "./common/OrderToken";
|
|
19
20
|
export { OrderTokenAmount } from "./common/OrderTokenAmount";
|
|
20
|
-
export { PaySection } from "./common/PaySection";
|
|
21
21
|
export { RecipientSelection } from "./common/RecipientSelection";
|
|
22
22
|
export { StepProgress } from "./common/StepProgress";
|
|
23
23
|
export { TokenBalance } from "./common/TokenBalance";
|
|
@@ -5,12 +5,13 @@ export { AnySpendBuySpin } from "./AnySpendBuySpin.js";
|
|
|
5
5
|
export { AnySpendCustom } from "./AnySpendCustom.js";
|
|
6
6
|
export * from "./AnySpendFingerprintWrapper.js";
|
|
7
7
|
export { AnySpendNFT } from "./AnySpendNFT.js";
|
|
8
|
-
export { AnyspendSignatureMint } from "./AnyspendSignatureMint.js";
|
|
9
8
|
export { AnySpendStakeB3 } from "./AnySpendStakeB3.js";
|
|
10
9
|
export { AnySpendTournament } from "./AnySpendTournament.js";
|
|
10
|
+
export { AnyspendSignatureMint } from "./AnyspendSignatureMint.js";
|
|
11
11
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton.js";
|
|
12
12
|
// Common Components
|
|
13
13
|
export { ChainTokenIcon } from "./common/ChainTokenIcon.js";
|
|
14
|
+
export { CryptoPaySection } from "./common/CryptoPaySection.js";
|
|
14
15
|
export { CryptoReceiveSection } from "./common/CryptoReceiveSection.js";
|
|
15
16
|
export { OrderDetails } from "./common/OrderDetails.js";
|
|
16
17
|
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible.js";
|
|
@@ -19,7 +20,6 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem.js";
|
|
|
19
20
|
export { OrderStatus } from "./common/OrderStatus.js";
|
|
20
21
|
export { OrderToken } from "./common/OrderToken.js";
|
|
21
22
|
export { OrderTokenAmount } from "./common/OrderTokenAmount.js";
|
|
22
|
-
export { PaySection } from "./common/PaySection.js";
|
|
23
23
|
export { RecipientSelection } from "./common/RecipientSelection.js";
|
|
24
24
|
export { StepProgress } from "./common/StepProgress.js";
|
|
25
25
|
export { TokenBalance } from "./common/TokenBalance.js";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
declare const app: import("@b3dotfun/basement-api").ClientApplication;
|
|
2
2
|
export declare const authenticate: (accessToken: string, identityToken: string, params?: Record<string, any>) => Promise<import("@feathersjs/authentication").AuthenticationResult | null>;
|
|
3
3
|
export declare const resetSocket: () => void;
|
|
4
|
+
export declare function extractAvatarIdFromUrl(url: string): string | null;
|
|
5
|
+
export declare const authenticateWithB3JWT: (fullToken: string, params?: Record<string, any>) => Promise<import("@feathersjs/authentication").AuthenticationResult | null>;
|
|
4
6
|
export default app;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createClient } from "@b3dotfun/basement-api";
|
|
2
|
+
import { debugB3React } from "../shared/utils/debug.js";
|
|
2
3
|
import { AuthenticationClient } from "@feathersjs/authentication-client";
|
|
3
4
|
import socketio from "@feathersjs/socketio-client";
|
|
4
5
|
import Cookies from "js-cookie";
|
|
5
6
|
import io from "socket.io-client";
|
|
7
|
+
const debug = debugB3React("bsmnt");
|
|
6
8
|
// Also use b3 auth token since we are using b3-jwt strategy
|
|
7
9
|
const BSMNT_AUTH_COOKIE_NAME = "b3-auth";
|
|
8
10
|
const BSMNT_API_URL = process.env.EXPO_PUBLIC_BSMNT_API ||
|
|
@@ -58,4 +60,41 @@ export const resetSocket = () => {
|
|
|
58
60
|
socket.connect();
|
|
59
61
|
// reset the socket connection
|
|
60
62
|
};
|
|
63
|
+
export function extractAvatarIdFromUrl(url) {
|
|
64
|
+
const regex = /https:\/\/models\.readyplayer\.me\/([a-f0-9]{24})\.[a-zA-Z0-9]+/;
|
|
65
|
+
const match = url.match(regex);
|
|
66
|
+
return match ? match[1] : null;
|
|
67
|
+
}
|
|
68
|
+
export const authenticateWithB3JWT = async (fullToken, params) => {
|
|
69
|
+
// Do not authenticate if there is no token
|
|
70
|
+
if (!fullToken) {
|
|
71
|
+
console.log("No token found, not authenticating");
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
debug("Authenticating with token:12", fullToken);
|
|
75
|
+
try {
|
|
76
|
+
const response = await app.authenticate({
|
|
77
|
+
strategy: "b3-jwt",
|
|
78
|
+
accessToken: fullToken,
|
|
79
|
+
}, {
|
|
80
|
+
query: params || {},
|
|
81
|
+
});
|
|
82
|
+
debug("Authenticated", response);
|
|
83
|
+
// Store streamToken if it exists in the response
|
|
84
|
+
if (response?.streamToken) {
|
|
85
|
+
Cookies.set("stream-token", response.streamToken, {
|
|
86
|
+
expires: new Date(response.authExpires),
|
|
87
|
+
secure: process.env.NODE_ENV === "production",
|
|
88
|
+
sameSite: "strict",
|
|
89
|
+
});
|
|
90
|
+
debug("Stream token stored in cookies");
|
|
91
|
+
}
|
|
92
|
+
return response;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
debug(`Authentication error:5`, error);
|
|
96
|
+
debug("Authentication JWT", fullToken);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
61
100
|
export default app;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useProfile } from "../../../../global-account/react/index.js";
|
|
4
|
+
import { useRPMToken } from "../../../../global-account/react/hooks/useRPMToken.js";
|
|
5
|
+
import { updateAvatar } from "../../../../global-account/react/utils/updateAvatar.js";
|
|
6
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
7
|
+
import { debugB3React } from "../../../../shared/utils/debug.js";
|
|
8
|
+
import { AvatarCreator as AvatarCreatorRPM, } from "@readyplayerme/react-avatar-creator";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { toast } from "sonner";
|
|
11
|
+
import { useActiveAccount } from "thirdweb/react";
|
|
12
|
+
const debug = debugB3React("AvatarCreator");
|
|
13
|
+
const config = {
|
|
14
|
+
clearCache: true,
|
|
15
|
+
bodyType: "fullbody",
|
|
16
|
+
quickStart: true,
|
|
17
|
+
language: "en",
|
|
18
|
+
};
|
|
19
|
+
export function AvatarCreator({ onSetAvatar, className }) {
|
|
20
|
+
const { token, refetch: refetchRPMToken } = useRPMToken();
|
|
21
|
+
const [loading, setIsLoading] = useState(false);
|
|
22
|
+
const account = useActiveAccount();
|
|
23
|
+
const { data: profile, refetch: refreshProfile } = useProfile({
|
|
24
|
+
address: account?.address,
|
|
25
|
+
fresh: true,
|
|
26
|
+
});
|
|
27
|
+
const hasAvatar = profile?.avatar;
|
|
28
|
+
const handleOnAvatarExported = async (event) => {
|
|
29
|
+
setIsLoading(true);
|
|
30
|
+
debug("@@AvatarExportedEvent", event);
|
|
31
|
+
try {
|
|
32
|
+
const avatarUpload = await updateAvatar(event.data.url);
|
|
33
|
+
debug("@@avatarUpload", avatarUpload);
|
|
34
|
+
await refreshProfile();
|
|
35
|
+
toast.success(hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!");
|
|
36
|
+
onSetAvatar?.();
|
|
37
|
+
await refetchRPMToken(undefined);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
debug("@@error:AvatarCreator", e);
|
|
41
|
+
toast.error("Failed to update avatar. Please try again.");
|
|
42
|
+
}
|
|
43
|
+
setIsLoading(false);
|
|
44
|
+
};
|
|
45
|
+
if (loading) {
|
|
46
|
+
return (_jsxs("div", { className: "flex h-[80vh] w-full flex-col items-center justify-center gap-4", children: [_jsx("div", { className: "border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: "Saving your avatar" })] }));
|
|
47
|
+
}
|
|
48
|
+
if (!token) {
|
|
49
|
+
return (_jsxs("div", { className: "flex h-[80vh] w-full flex-col items-center justify-center gap-4", children: [_jsx("div", { className: "border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: "Loading avatar creator" })] }));
|
|
50
|
+
}
|
|
51
|
+
return (_jsx("div", { className: cn("h-[calc(90vh-2px)] w-full", className), children: _jsx(AvatarCreatorRPM, { className: "h-full w-full", subdomain: "b3", config: { ...config, token }, onAvatarExported: handleOnAvatarExported }) }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import app from "../../../../global-account/app.js";
|
|
4
|
+
import { Button, useB3, useProfile } from "../../../../global-account/react/index.js";
|
|
5
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
6
|
+
import { debugB3React } from "../../../../shared/utils/debug.js";
|
|
7
|
+
import { client } from "../../../../shared/utils/thirdweb.js";
|
|
8
|
+
import { Check, Loader2, Upload, X } from "lucide-react";
|
|
9
|
+
import { useRef, useState } from "react";
|
|
10
|
+
import { toast } from "sonner";
|
|
11
|
+
import { useActiveAccount } from "thirdweb/react";
|
|
12
|
+
import { upload } from "thirdweb/storage";
|
|
13
|
+
const debug = debugB3React("AvatarEditor");
|
|
14
|
+
export function AvatarEditor({ onSetAvatar, className }) {
|
|
15
|
+
const [selectedFile, setSelectedFile] = useState(null);
|
|
16
|
+
const [previewUrl, setPreviewUrl] = useState(null);
|
|
17
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
18
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
19
|
+
const fileInputRef = useRef(null);
|
|
20
|
+
const { setUser } = useB3();
|
|
21
|
+
const account = useActiveAccount();
|
|
22
|
+
const { data: profile, refetch: refreshProfile } = useProfile({
|
|
23
|
+
address: account?.address,
|
|
24
|
+
fresh: true,
|
|
25
|
+
});
|
|
26
|
+
// Thirdweb upload function
|
|
27
|
+
const hasAvatar = profile?.avatar;
|
|
28
|
+
const handleFileSelect = (event) => {
|
|
29
|
+
const file = event.target.files?.[0];
|
|
30
|
+
if (file) {
|
|
31
|
+
// Validate file type
|
|
32
|
+
if (!file.type.startsWith("image/")) {
|
|
33
|
+
toast.error("Please select an image file");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Validate file size (max 5MB)
|
|
37
|
+
if (file.size > 5 * 1024 * 1024) {
|
|
38
|
+
toast.error("File size must be less than 5MB");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setSelectedFile(file);
|
|
42
|
+
// Create preview URL
|
|
43
|
+
const url = URL.createObjectURL(file);
|
|
44
|
+
setPreviewUrl(url);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const handleRemoveFile = () => {
|
|
48
|
+
setSelectedFile(null);
|
|
49
|
+
if (previewUrl) {
|
|
50
|
+
URL.revokeObjectURL(previewUrl);
|
|
51
|
+
setPreviewUrl(null);
|
|
52
|
+
}
|
|
53
|
+
if (fileInputRef.current) {
|
|
54
|
+
fileInputRef.current.value = "";
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleUpload = async () => {
|
|
58
|
+
if (!selectedFile) {
|
|
59
|
+
toast.error("Please select an image first");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setIsUploading(true);
|
|
63
|
+
try {
|
|
64
|
+
debug("Starting upload to IPFS", selectedFile);
|
|
65
|
+
// Upload to IPFS using Thirdweb
|
|
66
|
+
const ipfsUrl = await upload({
|
|
67
|
+
client,
|
|
68
|
+
files: [selectedFile],
|
|
69
|
+
});
|
|
70
|
+
debug("Upload successful", ipfsUrl);
|
|
71
|
+
// Save avatar URL using profiles service
|
|
72
|
+
setIsSaving(true);
|
|
73
|
+
const user = await app.service("users").setAvatar({
|
|
74
|
+
avatar: ipfsUrl,
|
|
75
|
+
},
|
|
76
|
+
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
77
|
+
{});
|
|
78
|
+
// update user
|
|
79
|
+
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
80
|
+
setUser(user);
|
|
81
|
+
// Refresh profile to get updated avatar
|
|
82
|
+
await refreshProfile();
|
|
83
|
+
toast.success(hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!");
|
|
84
|
+
onSetAvatar?.();
|
|
85
|
+
// Clean up
|
|
86
|
+
handleRemoveFile();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
debug("Error uploading avatar:", error);
|
|
90
|
+
toast.error("Failed to upload avatar. Please try again.");
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
setIsUploading(false);
|
|
94
|
+
setIsSaving(false);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const handleFileInputClick = () => {
|
|
98
|
+
fileInputRef.current?.click();
|
|
99
|
+
};
|
|
100
|
+
const isLoading = isUploading || isSaving;
|
|
101
|
+
return (_jsxs("div", { className: cn("flex flex-col items-center justify-center space-y-6 p-8", className), children: [_jsxs("div", { className: "space-y-2 text-center", children: [_jsx("h2", { className: "font-neue-montreal-semibold text-b3-grey text-2xl", children: hasAvatar ? "Update Your Avatar" : "Set Your Avatar" }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium", children: "Upload an image to personalize your profile" })] }), hasAvatar && !previewUrl && (_jsx("div", { className: "relative", children: _jsx("div", { className: "border-b3-primary-blue h-32 w-32 overflow-hidden rounded-full border-4", children: _jsx("img", { src: profile.avatar, alt: "Current avatar", className: "h-full w-full object-cover" }) }) })), _jsxs("div", { className: "w-full max-w-md", children: [!selectedFile ? (_jsxs("div", { onClick: handleFileInputClick, className: "border-b3-line hover:border-b3-primary-blue hover:bg-b3-primary-wash/20 cursor-pointer rounded-xl border-2 border-dashed p-8 text-center transition-colors", children: [_jsx(Upload, { className: "text-b3-grey mx-auto mb-4 h-12 w-12" }), _jsx("p", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "Click to select an image" }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "PNG, JPG, or GIF up to 5MB" })] })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "border-b3-primary-blue mx-auto h-32 w-32 overflow-hidden rounded-full border-4", children: previewUrl ? (_jsx("img", { src: previewUrl, alt: "Preview", className: "h-full w-full object-cover" })) : (_jsx("div", { className: "bg-b3-primary-wash flex h-full w-full items-center justify-center rounded-full", children: _jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "No file selected" }) })) }), _jsx("button", { onClick: handleRemoveFile, className: "bg-b3-negative absolute -right-2 -top-2 flex h-8 w-8 items-center justify-center rounded-full text-white transition-colors hover:bg-red-600", disabled: isLoading, children: _jsx(X, { size: 16 }) })] }), _jsxs("div", { className: "space-y-1 text-center", children: [_jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: selectedFile.name }), _jsxs("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-xs", children: [(selectedFile.size / 1024 / 1024).toFixed(2), " MB"] })] })] })), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden" })] }), _jsxs("div", { className: "flex w-full max-w-md gap-3", children: [selectedFile && (_jsx(Button, { onClick: handleUpload, disabled: isLoading, className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white", children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isUploading ? "Uploading..." : "Saving..."] })) : (_jsxs(_Fragment, { children: [_jsx(Check, { className: "mr-2 h-4 w-4" }), hasAvatar ? "Update Avatar" : "Set Avatar"] })) })), _jsxs(Button, { variant: "outline", onClick: handleFileInputClick, disabled: isLoading, className: "flex-1", children: [_jsx(Upload, { className: "mr-2 h-4 w-4" }), selectedFile ? "Change Image" : "Select Image"] })] }), _jsx("div", { className: "text-b3-foreground-muted font-neue-montreal-medium max-w-md text-center text-xs", children: _jsx("p", { children: "Your avatar will be uploaded to IPFS and stored securely. Make sure you have the rights to use this image." }) })] }));
|
|
102
|
+
}
|