@b3dotfun/sdk 0.0.65-test.1 → 0.0.65
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 +33 -73
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +1 -1
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +1 -1
- package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderHistory.js +3 -7
- package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
- package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/cjs/global-account/react/components/AccountAssets/AccountAssets.js +2 -38
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +33 -139
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +6 -25
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +279 -113
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +2 -2
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +193 -24
- package/dist/cjs/global-account/react/components/index.d.ts +2 -4
- package/dist/cjs/global-account/react/components/index.js +4 -11
- package/dist/cjs/global-account/react/components/ui/Tabs.js +2 -2
- package/dist/cjs/global-account/react/components/ui/dialog.js +2 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/index.js +1 -3
- package/dist/cjs/global-account/react/hooks/useB3BalanceFromAddresses.js +0 -1
- package/dist/cjs/global-account/react/stores/index.d.ts +0 -1
- package/dist/cjs/global-account/react/stores/index.js +1 -3
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +3 -34
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/cjs/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/cjs/shared/constants/chains/supported.d.ts +2 -2
- package/dist/cjs/shared/utils/ipfs.js +1 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +34 -74
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +1 -1
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +1 -1
- package/dist/esm/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/esm/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/esm/anyspend/react/components/common/OrderHistory.js +5 -6
- package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
- package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/esm/global-account/react/components/AccountAssets/AccountAssets.js +2 -38
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +34 -140
- package/dist/esm/global-account/react/components/B3DynamicModal.js +6 -25
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +280 -113
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +2 -2
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +195 -26
- package/dist/esm/global-account/react/components/index.d.ts +2 -4
- package/dist/esm/global-account/react/components/index.js +2 -7
- package/dist/esm/global-account/react/components/ui/Tabs.js +2 -2
- package/dist/esm/global-account/react/components/ui/dialog.js +2 -2
- package/dist/esm/global-account/react/hooks/index.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/index.js +1 -1
- package/dist/esm/global-account/react/hooks/useB3BalanceFromAddresses.js +0 -1
- package/dist/esm/global-account/react/stores/index.d.ts +0 -1
- package/dist/esm/global-account/react/stores/index.js +0 -1
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +3 -34
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/esm/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/esm/shared/constants/chains/supported.d.ts +2 -2
- package/dist/esm/shared/utils/ipfs.js +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/types/global-account/react/components/index.d.ts +2 -4
- package/dist/types/global-account/react/hooks/index.d.ts +1 -1
- package/dist/types/global-account/react/stores/index.d.ts +0 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +3 -34
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/types/shared/constants/chains/supported.d.ts +2 -2
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +167 -225
- package/src/anyspend/react/components/AnySpendCustom.tsx +1 -1
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +1 -1
- package/src/anyspend/react/components/common/FeeDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +2 -2
- package/src/anyspend/react/components/common/OrderHistory.tsx +13 -8
- package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +1 -1
- package/src/anyspend/react/components/common/PointsDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/RecipientSelection.tsx +1 -1
- package/src/global-account/react/components/AccountAssets/AccountAssets.tsx +25 -115
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +126 -303
- package/src/global-account/react/components/B3DynamicModal.tsx +6 -28
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +433 -332
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +3 -2
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +589 -73
- package/src/global-account/react/components/index.ts +2 -9
- package/src/global-account/react/components/ui/Tabs.tsx +13 -5
- package/src/global-account/react/components/ui/dialog.tsx +14 -32
- package/src/global-account/react/hooks/index.ts +0 -3
- package/src/global-account/react/hooks/useB3BalanceFromAddresses.ts +0 -1
- package/src/global-account/react/stores/index.ts +0 -1
- package/src/global-account/react/stores/useModalStore.ts +2 -39
- package/src/global-account/react/utils/profileDisplay.ts +2 -4
- package/src/shared/utils/ipfs.ts +1 -1
- package/src/styles/index.css +1 -6
- package/dist/cjs/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/cjs/global-account/react/components/Deposit/Deposit.js +0 -65
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.js +0 -331
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.js +0 -34
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +0 -23
- package/dist/cjs/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/cjs/global-account/react/components/ManageAccount/Header.js +0 -120
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.js +0 -43
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.js +0 -16
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +0 -15
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +0 -44
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +0 -50
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.js +0 -8
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +0 -38
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +0 -22
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -10
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.js +0 -12
- package/dist/cjs/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/cjs/global-account/react/components/Send/Send.js +0 -187
- package/dist/cjs/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/BellIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.js +0 -7
- package/dist/cjs/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/CopyIcon.js +0 -7
- package/dist/cjs/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/LinkIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/LockIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/WalletIcon.js +0 -7
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.js +0 -36
- package/dist/esm/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/esm/global-account/react/components/Deposit/Deposit.js +0 -59
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.js +0 -325
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.js +0 -32
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +0 -21
- package/dist/esm/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/esm/global-account/react/components/ManageAccount/Header.js +0 -81
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.js +0 -41
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.js +0 -10
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +0 -13
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +0 -42
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +0 -45
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.js +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +0 -36
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +0 -20
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -10
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.js +0 -10
- package/dist/esm/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/esm/global-account/react/components/Send/Send.js +0 -181
- package/dist/esm/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/BellIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.js +0 -4
- package/dist/esm/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/CopyIcon.js +0 -4
- package/dist/esm/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/LinkIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/LockIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/WalletIcon.js +0 -4
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.js +0 -33
- package/dist/types/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/types/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/types/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/types/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/types/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/types/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/types/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/types/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/types/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/types/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -10
- package/dist/types/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/types/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/types/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/types/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/types/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/src/global-account/react/components/Deposit/Deposit.tsx +0 -211
- package/src/global-account/react/components/LinkAccount/LinkNewAccount.tsx +0 -490
- package/src/global-account/react/components/ManageAccount/AppsContent.tsx +0 -79
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +0 -83
- package/src/global-account/react/components/ManageAccount/Header.tsx +0 -230
- package/src/global-account/react/components/ManageAccount/HomeActions.tsx +0 -118
- package/src/global-account/react/components/ManageAccount/HomeContent.tsx +0 -42
- package/src/global-account/react/components/ManageAccount/NFTContent.tsx +0 -24
- package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +0 -74
- package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +0 -87
- package/src/global-account/react/components/ManageAccount/SettingsMenuItem.tsx +0 -31
- package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +0 -74
- package/src/global-account/react/components/ManageAccount/TokenContent.tsx +0 -41
- package/src/global-account/react/components/ModalHeader/ModalHeader.tsx +0 -50
- package/src/global-account/react/components/Send/Send.tsx +0 -585
- package/src/global-account/react/components/icons/BellIcon.tsx +0 -15
- package/src/global-account/react/components/icons/ChevronDownIcon.tsx +0 -17
- package/src/global-account/react/components/icons/CopyIcon.tsx +0 -22
- package/src/global-account/react/components/icons/LinkIcon.tsx +0 -15
- package/src/global-account/react/components/icons/LockIcon.tsx +0 -15
- package/src/global-account/react/components/icons/WalletIcon.tsx +0 -21
- package/src/global-account/react/stores/useRecentAddressesStore.ts +0 -55
|
@@ -1,69 +1,138 @@
|
|
|
1
1
|
import app from "@b3dotfun/sdk/global-account/app";
|
|
2
|
-
import {
|
|
2
|
+
import { ecosystemWalletId } from "@b3dotfun/sdk/shared/constants";
|
|
3
|
+
import { thirdwebB3Mainnet } from "@b3dotfun/sdk/shared/constants/chains/b3Chain";
|
|
3
4
|
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useRef, useState } from "react";
|
|
5
|
+
import { Loader2, Mail, Phone, WalletIcon } from "lucide-react";
|
|
6
|
+
import { useCallback, useEffect, useState } from "react";
|
|
7
7
|
import { toast } from "sonner";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import {
|
|
8
|
+
import { useLinkProfile, useProfiles } from "thirdweb/react";
|
|
9
|
+
import { createWallet, preAuthenticate, WalletId } from "thirdweb/wallets";
|
|
10
|
+
import { WalletRow } from "../..";
|
|
11
|
+
import { LinkAccountModalProps, useModalStore } from "../../stores/useModalStore";
|
|
11
12
|
import { getProfileDisplayInfo } from "../../utils/profileDisplay";
|
|
13
|
+
import { useB3 } from "../B3Provider/useB3";
|
|
14
|
+
import { AppleIcon } from "../icons/AppleIcon";
|
|
15
|
+
import { DiscordIcon } from "../icons/DiscordIcon";
|
|
16
|
+
import { FarcasterIcon } from "../icons/FarcasterIcon";
|
|
17
|
+
import { GoogleIcon } from "../icons/GoogleIcon";
|
|
18
|
+
import { XIcon } from "../icons/XIcon";
|
|
19
|
+
import { Button } from "../ui/button";
|
|
20
|
+
type OTPStrategy = "email" | "phone";
|
|
21
|
+
type SocialStrategy = "google" | "x" | "discord" | "apple" | "farcaster";
|
|
22
|
+
type Strategy = OTPStrategy | SocialStrategy | "wallet";
|
|
12
23
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
24
|
+
interface AuthMethod {
|
|
25
|
+
id: Strategy;
|
|
26
|
+
label: string;
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
icon: React.ReactNode;
|
|
29
|
+
walletType?: WalletId;
|
|
30
|
+
}
|
|
17
31
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
32
|
+
const AUTH_METHODS: AuthMethod[] = [
|
|
33
|
+
{ id: "email", label: "Email", enabled: true, icon: <Mail className="text-b3-primary-blue size-6" /> },
|
|
34
|
+
{ id: "phone", label: "Phone", enabled: true, icon: <Phone className="text-b3-primary-blue size-6" /> },
|
|
35
|
+
{ id: "google", label: "Google", enabled: true, icon: <GoogleIcon className="size-6" /> },
|
|
36
|
+
{ id: "x", label: "X (Twitter)", enabled: true, icon: <XIcon className="size-6" /> },
|
|
37
|
+
{ id: "discord", label: "Discord", enabled: true, icon: <DiscordIcon className="size-6" /> },
|
|
38
|
+
{ id: "apple", label: "Apple", enabled: true, icon: <AppleIcon className="size-6" /> },
|
|
39
|
+
{
|
|
40
|
+
id: "farcaster",
|
|
41
|
+
label: "Farcaster",
|
|
42
|
+
enabled: true,
|
|
43
|
+
icon: <FarcasterIcon className="size-6" />,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
24
46
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
const WALLET_METHODS: AuthMethod[] = [
|
|
48
|
+
{
|
|
49
|
+
id: "wallet",
|
|
50
|
+
label: "Wallet",
|
|
51
|
+
enabled: true,
|
|
52
|
+
icon: <WalletIcon className="size-6" />,
|
|
53
|
+
walletType: "com.coinbase.wallet",
|
|
54
|
+
},
|
|
55
|
+
{ id: "wallet", label: "Wallet", enabled: true, icon: <WalletIcon className="size-6" />, walletType: "io.metamask" },
|
|
56
|
+
{
|
|
57
|
+
id: "wallet",
|
|
58
|
+
label: "Wallet",
|
|
59
|
+
enabled: true,
|
|
60
|
+
icon: <WalletIcon className="size-6" />,
|
|
61
|
+
walletType: "me.rainbow",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "wallet",
|
|
65
|
+
label: "Wallet",
|
|
66
|
+
enabled: true,
|
|
67
|
+
icon: <WalletIcon className="size-6" />,
|
|
68
|
+
walletType: "app.phantom",
|
|
69
|
+
},
|
|
70
|
+
{ id: "wallet", label: "Wallet", enabled: true, icon: <WalletIcon className="size-6" />, walletType: "io.rabby" },
|
|
71
|
+
{
|
|
72
|
+
id: "wallet",
|
|
73
|
+
label: "Wallet",
|
|
74
|
+
enabled: true,
|
|
75
|
+
icon: <WalletIcon className="size-6" />,
|
|
76
|
+
walletType: "walletConnect",
|
|
77
|
+
},
|
|
78
|
+
];
|
|
30
79
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
partnerId,
|
|
36
|
-
onLogout,
|
|
80
|
+
export function LinkAccount({
|
|
81
|
+
onSuccess: onSuccessCallback,
|
|
82
|
+
onError,
|
|
83
|
+
onClose,
|
|
37
84
|
chain,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const [
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{ query: { referrerId: user?.userId } },
|
|
59
|
-
!!user?.userId,
|
|
85
|
+
partnerId,
|
|
86
|
+
className,
|
|
87
|
+
}: LinkAccountModalProps & { className?: string }) {
|
|
88
|
+
const { isLinking, linkingMethod, setLinkingState, navigateBack, setB3ModalContentType } = useModalStore();
|
|
89
|
+
const [selectedMethod, setSelectedMethod] = useState<Strategy | null>(null);
|
|
90
|
+
const [email, setEmail] = useState("");
|
|
91
|
+
const [phone, setPhone] = useState("");
|
|
92
|
+
const [otp, setOtp] = useState("");
|
|
93
|
+
const [otpSent, setOtpSent] = useState(false);
|
|
94
|
+
const [error, setError] = useState<string | null>(null);
|
|
95
|
+
const { data: profilesRaw = [] } = useProfiles({ client });
|
|
96
|
+
|
|
97
|
+
// Get connected auth methods
|
|
98
|
+
const connectedAuthMethods = profilesRaw
|
|
99
|
+
.filter((profile: any) => !["custom_auth_endpoint"].includes(profile.type))
|
|
100
|
+
.map((profile: any) => profile.type as Strategy);
|
|
101
|
+
|
|
102
|
+
// Filter available auth methods
|
|
103
|
+
const availableAuthMethods = AUTH_METHODS.filter(
|
|
104
|
+
method => !connectedAuthMethods.includes(method.id) && method.enabled,
|
|
60
105
|
);
|
|
61
|
-
|
|
106
|
+
|
|
107
|
+
const profiles = profilesRaw
|
|
108
|
+
.filter((profile: any) => !["custom_auth_endpoint"].includes(profile.type))
|
|
109
|
+
.map((profile: any) => ({
|
|
110
|
+
...getProfileDisplayInfo(profile),
|
|
111
|
+
originalProfile: profile,
|
|
112
|
+
}));
|
|
113
|
+
|
|
114
|
+
const { account } = useB3();
|
|
115
|
+
const { mutate: linkProfile } = useLinkProfile();
|
|
116
|
+
|
|
117
|
+
const onSuccess = useCallback(async () => {
|
|
118
|
+
await onSuccessCallback?.();
|
|
119
|
+
}, [onSuccessCallback]);
|
|
120
|
+
|
|
121
|
+
// Reset linking state when component unmounts
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
return () => {
|
|
124
|
+
if (isLinking) {
|
|
125
|
+
setLinkingState(false);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}, [isLinking, setLinkingState]);
|
|
62
129
|
|
|
63
130
|
const mutationOptions = {
|
|
64
131
|
onError: (error: Error) => {
|
|
65
|
-
console.error("Error
|
|
132
|
+
console.error("Error linking account:", error);
|
|
66
133
|
toast.error(error.message);
|
|
134
|
+
setLinkingState(false);
|
|
135
|
+
onError?.(error);
|
|
67
136
|
},
|
|
68
137
|
onSuccess: async (data: any) => {
|
|
69
138
|
console.log("Raw Link Account Data:", data);
|
|
@@ -76,316 +145,348 @@ export const LinkAccount = ({
|
|
|
76
145
|
},
|
|
77
146
|
};
|
|
78
147
|
|
|
79
|
-
|
|
80
|
-
|
|
148
|
+
const validateInput = () => {
|
|
149
|
+
if (selectedMethod === "email") {
|
|
150
|
+
if (!email) {
|
|
151
|
+
setError("Please enter your email address");
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
155
|
+
setError("Please enter a valid email address");
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
} else if (selectedMethod === "phone") {
|
|
159
|
+
if (!phone) {
|
|
160
|
+
setError("Please enter your phone number");
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (!/^\+?[\d\s-]{10,}$/.test(phone)) {
|
|
164
|
+
setError("Please enter a valid phone number");
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
setError(null);
|
|
169
|
+
return true;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const handleSendOTP = async () => {
|
|
173
|
+
if (!validateInput()) return;
|
|
81
174
|
|
|
82
|
-
const handleCopyCode = async () => {
|
|
83
175
|
try {
|
|
84
|
-
|
|
85
|
-
|
|
176
|
+
setLinkingState(true, selectedMethod);
|
|
177
|
+
setError(null);
|
|
178
|
+
|
|
179
|
+
if (selectedMethod === "email") {
|
|
180
|
+
await preAuthenticate({
|
|
181
|
+
client,
|
|
182
|
+
strategy: "email",
|
|
183
|
+
email,
|
|
184
|
+
ecosystem: {
|
|
185
|
+
id: ecosystemWalletId,
|
|
186
|
+
partnerId: partnerId,
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
} else if (selectedMethod === "phone") {
|
|
190
|
+
await preAuthenticate({
|
|
191
|
+
client,
|
|
192
|
+
strategy: "phone",
|
|
193
|
+
phoneNumber: phone,
|
|
194
|
+
ecosystem: {
|
|
195
|
+
id: ecosystemWalletId,
|
|
196
|
+
partnerId: partnerId,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
setOtpSent(true);
|
|
86
202
|
} catch (error) {
|
|
87
|
-
|
|
203
|
+
console.error("Error sending OTP:", error);
|
|
204
|
+
setError(error instanceof Error ? error.message : "Failed to send OTP");
|
|
205
|
+
onError?.(error as Error);
|
|
206
|
+
setLinkingState(false);
|
|
88
207
|
}
|
|
89
208
|
};
|
|
90
209
|
|
|
91
|
-
const
|
|
92
|
-
if (!
|
|
210
|
+
const handleLinkAccount = async () => {
|
|
211
|
+
if (!otp) {
|
|
212
|
+
console.error("No OTP entered");
|
|
213
|
+
setError("Please enter the verification code");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
93
216
|
|
|
94
|
-
setIsUpdatingCode(true);
|
|
95
217
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
218
|
+
setOtpSent(false);
|
|
219
|
+
setLinkingState(true, selectedMethod);
|
|
220
|
+
setError(null);
|
|
221
|
+
|
|
222
|
+
if (selectedMethod === "email") {
|
|
223
|
+
await linkProfile(
|
|
224
|
+
{
|
|
225
|
+
client,
|
|
226
|
+
strategy: "email",
|
|
227
|
+
email,
|
|
228
|
+
verificationCode: otp,
|
|
229
|
+
},
|
|
230
|
+
mutationOptions,
|
|
231
|
+
);
|
|
232
|
+
} else if (selectedMethod === "phone") {
|
|
233
|
+
await linkProfile(
|
|
234
|
+
{
|
|
235
|
+
client,
|
|
236
|
+
strategy: "phone",
|
|
237
|
+
phoneNumber: phone,
|
|
238
|
+
verificationCode: otp,
|
|
239
|
+
},
|
|
240
|
+
mutationOptions,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
105
243
|
} catch (error) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
244
|
+
console.error("Error linking account:", error);
|
|
245
|
+
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
246
|
+
onError?.(error as Error);
|
|
109
247
|
}
|
|
110
248
|
};
|
|
111
249
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
.
|
|
115
|
-
...getProfileDisplayInfo(profile),
|
|
116
|
-
originalProfile: profile,
|
|
117
|
-
}));
|
|
118
|
-
|
|
119
|
-
const handleUnlink = async (profile: any) => {
|
|
120
|
-
setUnlinkingAccountId(profile.title);
|
|
250
|
+
const handleLinkWallet = async (walletType: WalletId) => {
|
|
251
|
+
setLinkingState(true, "wallet");
|
|
252
|
+
console.log("selectedMethod", walletType);
|
|
121
253
|
try {
|
|
122
|
-
|
|
254
|
+
if (!walletType) {
|
|
255
|
+
throw new Error("Wallet type not found");
|
|
256
|
+
}
|
|
257
|
+
await linkProfile(
|
|
258
|
+
{
|
|
259
|
+
client,
|
|
260
|
+
strategy: "wallet",
|
|
261
|
+
wallet: createWallet(walletType),
|
|
262
|
+
chain: thirdwebB3Mainnet,
|
|
263
|
+
},
|
|
264
|
+
mutationOptions,
|
|
265
|
+
);
|
|
123
266
|
} catch (error) {
|
|
124
|
-
console.error("Error
|
|
125
|
-
|
|
126
|
-
|
|
267
|
+
console.error("Error linking account:", error);
|
|
268
|
+
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
269
|
+
onError?.(error as Error);
|
|
127
270
|
}
|
|
128
271
|
};
|
|
129
272
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
273
|
+
const handleSocialLink = async (strategy: SocialStrategy) => {
|
|
274
|
+
try {
|
|
275
|
+
console.log("handleSocialLink", strategy);
|
|
276
|
+
setLinkingState(true, strategy);
|
|
277
|
+
setError(null);
|
|
278
|
+
|
|
279
|
+
const result = await linkProfile(
|
|
280
|
+
{
|
|
281
|
+
client,
|
|
282
|
+
strategy,
|
|
283
|
+
},
|
|
284
|
+
mutationOptions,
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
console.log("result", result);
|
|
288
|
+
|
|
289
|
+
// Don't close the modal yet, wait for auth to complete
|
|
290
|
+
onSuccess?.();
|
|
291
|
+
} catch (error) {
|
|
292
|
+
console.error("Error linking with social:", error);
|
|
293
|
+
setError(error instanceof Error ? error.message : "Failed to link social account");
|
|
294
|
+
onError?.(error as Error);
|
|
295
|
+
setLinkingState(false);
|
|
296
|
+
}
|
|
146
297
|
};
|
|
147
298
|
|
|
299
|
+
// Add effect to handle social auth completion
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
if (isLinking && linkingMethod && !selectedMethod) {
|
|
302
|
+
// This means we're in a social auth flow
|
|
303
|
+
const checkAuthStatus = async () => {
|
|
304
|
+
try {
|
|
305
|
+
// Wait a bit to ensure auth is complete
|
|
306
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
307
|
+
onClose?.();
|
|
308
|
+
} catch (error) {
|
|
309
|
+
console.error("Error checking auth status:", error);
|
|
310
|
+
setLinkingState(false);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
checkAuthStatus();
|
|
315
|
+
}
|
|
316
|
+
}, [isLinking, linkingMethod, selectedMethod, onClose, setLinkingState]);
|
|
317
|
+
|
|
318
|
+
const handleBack = useCallback(() => {
|
|
319
|
+
if (isLinking) return;
|
|
320
|
+
setSelectedMethod(null);
|
|
321
|
+
setEmail("");
|
|
322
|
+
setPhone("");
|
|
323
|
+
setOtp("");
|
|
324
|
+
setOtpSent(false);
|
|
325
|
+
setError(null);
|
|
326
|
+
setLinkingState(false);
|
|
327
|
+
}, [isLinking, setSelectedMethod, setEmail, setPhone, setOtp, setOtpSent, setError, setLinkingState]);
|
|
328
|
+
|
|
329
|
+
const handleFinishedLinking = useCallback(
|
|
330
|
+
(success: boolean) => {
|
|
331
|
+
if (success) {
|
|
332
|
+
onSuccess?.();
|
|
333
|
+
onClose?.();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
setLinkingState(false);
|
|
337
|
+
navigateBack();
|
|
338
|
+
setB3ModalContentType({
|
|
339
|
+
type: "manageAccount",
|
|
340
|
+
activeTab: "settings",
|
|
341
|
+
setActiveTab: () => {},
|
|
342
|
+
chain,
|
|
343
|
+
partnerId,
|
|
344
|
+
});
|
|
345
|
+
},
|
|
346
|
+
[chain, navigateBack, partnerId, setB3ModalContentType, setLinkingState, onSuccess, onClose],
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
useEffect(() => {
|
|
350
|
+
if (isLinking) {
|
|
351
|
+
handleFinishedLinking(true);
|
|
352
|
+
}
|
|
353
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
354
|
+
}, [profiles.length]);
|
|
355
|
+
|
|
356
|
+
if (!account) {
|
|
357
|
+
return <div className="text-b3-foreground-muted py-8 text-center">Please connect your account first</div>;
|
|
358
|
+
}
|
|
359
|
+
|
|
148
360
|
return (
|
|
149
|
-
<div className="
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
</div>
|
|
157
|
-
) : profiles.length > 0 ? (
|
|
158
|
-
<div className="linked-accounts-list space-y-4">
|
|
159
|
-
{profiles.map(profile => (
|
|
160
|
-
<div
|
|
161
|
-
key={profile.title}
|
|
162
|
-
className="linked-account-item hover:bg-b3-line group flex cursor-pointer items-center justify-between rounded-xl p-4 transition-colors"
|
|
163
|
-
>
|
|
164
|
-
<div className="linked-account-info flex items-center gap-3">
|
|
165
|
-
{profile.imageUrl ? (
|
|
166
|
-
<img
|
|
167
|
-
src={profile.imageUrl}
|
|
168
|
-
alt={profile.title}
|
|
169
|
-
className="linked-account-avatar linked-account-avatar-image size-10 rounded-full"
|
|
170
|
-
/>
|
|
171
|
-
) : (
|
|
172
|
-
<div className="linked-account-avatar linked-account-avatar-placeholder bg-b3-primary-wash flex h-10 w-10 items-center justify-center rounded-full">
|
|
173
|
-
<span className="linked-account-initial text-b3-grey font-neue-montreal-semibold text-sm uppercase">
|
|
174
|
-
{profile.initial}
|
|
175
|
-
</span>
|
|
176
|
-
</div>
|
|
177
|
-
)}
|
|
178
|
-
<div className="linked-account-details">
|
|
179
|
-
<div className="linked-account-title-row flex items-center gap-2">
|
|
180
|
-
{(() => {
|
|
181
|
-
const { displayTitle, isAddress } = formatProfileTitle(profile.title);
|
|
182
|
-
|
|
183
|
-
const handleCopyAddress = async (e: React.MouseEvent) => {
|
|
184
|
-
e.stopPropagation();
|
|
185
|
-
try {
|
|
186
|
-
await navigator.clipboard.writeText(profile.title);
|
|
187
|
-
toast.success("Address copied to clipboard!");
|
|
188
|
-
} catch (error) {
|
|
189
|
-
toast.error("Failed to copy address");
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
return (
|
|
194
|
-
<div className="flex items-center gap-1">
|
|
195
|
-
<span
|
|
196
|
-
className={`linked-account-title text-b3-grey font-neue-montreal-semibold ${
|
|
197
|
-
isAddress
|
|
198
|
-
? "font-mono text-sm" // Use monospace font for addresses
|
|
199
|
-
: "break-words" // Use break-words for emails/names (better than break-all)
|
|
200
|
-
}`}
|
|
201
|
-
title={isAddress ? profile.title : undefined} // Show full address on hover
|
|
202
|
-
>
|
|
203
|
-
{displayTitle}
|
|
204
|
-
</span>
|
|
205
|
-
{isAddress && (
|
|
206
|
-
<button
|
|
207
|
-
onClick={handleCopyAddress}
|
|
208
|
-
className="linked-account-copy-button ml-1 rounded p-1 opacity-0 transition-opacity hover:bg-gray-100 group-hover:opacity-100"
|
|
209
|
-
title="Copy full address"
|
|
210
|
-
>
|
|
211
|
-
<Copy size={12} className="text-gray-500 hover:text-gray-700" />
|
|
212
|
-
</button>
|
|
213
|
-
)}
|
|
214
|
-
</div>
|
|
215
|
-
);
|
|
216
|
-
})()}
|
|
217
|
-
<span className="linked-account-type text-b3-foreground-muted font-neue-montreal-medium bg-b3-primary-wash rounded px-2 py-0.5 text-xs">
|
|
218
|
-
{profile.type.toUpperCase()}
|
|
219
|
-
</span>
|
|
220
|
-
</div>
|
|
221
|
-
<div className="linked-account-subtitle text-b3-foreground-muted font-neue-montreal-medium text-sm">
|
|
222
|
-
{profile.subtitle}
|
|
223
|
-
</div>
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
<Button
|
|
227
|
-
variant="ghost"
|
|
228
|
-
size="icon"
|
|
229
|
-
className="linked-account-unlink-button text-b3-grey hover:text-b3-negative"
|
|
230
|
-
onClick={() => handleUnlink(profile)}
|
|
231
|
-
disabled={unlinkingAccountId === profile.title || isUnlinking}
|
|
232
|
-
>
|
|
233
|
-
{unlinkingAccountId === profile.title || isUnlinking ? (
|
|
234
|
-
<Loader2 className="linked-account-unlink-loading animate-spin" />
|
|
235
|
-
) : (
|
|
236
|
-
<UnlinkIcon size={16} className="linked-account-unlink-icon" />
|
|
237
|
-
)}
|
|
238
|
-
</Button>
|
|
239
|
-
</div>
|
|
240
|
-
))}
|
|
241
|
-
</div>
|
|
242
|
-
) : (
|
|
243
|
-
<div className="linked-accounts-empty text-b3-foreground-muted py-8 text-center">
|
|
244
|
-
No linked accounts found
|
|
245
|
-
</div>
|
|
361
|
+
<div className={`b3-link-account space-y-6 p-6 ${className || ""}`} data-testid="link-account">
|
|
362
|
+
<div className="b3-link-account-header flex items-center justify-between">
|
|
363
|
+
<h2 className="b3-link-account-title text-b3-grey font-neue-montreal-semibold text-2xl">Link New Account</h2>
|
|
364
|
+
{selectedMethod && (
|
|
365
|
+
<Button variant="ghost" className="text-b3-grey hover:text-b3-grey/80" onClick={handleBack}>
|
|
366
|
+
Backs
|
|
367
|
+
</Button>
|
|
246
368
|
)}
|
|
247
|
-
|
|
248
|
-
{/* Link New Account Button */}
|
|
249
|
-
<Button
|
|
250
|
-
onClick={handleOpenLinkModal}
|
|
251
|
-
disabled={isLinking}
|
|
252
|
-
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 border-white/12 group relative h-12 w-full rounded-xl border-2 px-[18px] text-base font-semibold text-white shadow-[inset_0px_0px_0px_1px_rgba(10,13,18,0.18),inset_0px_-2px_0px_0px_rgba(10,13,18,0.05)] transition-all"
|
|
253
|
-
>
|
|
254
|
-
<div className="flex items-center justify-center gap-1.5">
|
|
255
|
-
<svg
|
|
256
|
-
width="20"
|
|
257
|
-
height="20"
|
|
258
|
-
viewBox="0 0 20 20"
|
|
259
|
-
fill="none"
|
|
260
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
261
|
-
className="shrink-0"
|
|
262
|
-
>
|
|
263
|
-
<path
|
|
264
|
-
d="M10.0001 13.3333V6.66667M6.66675 10H13.3334M18.3334 10C18.3334 14.6024 14.6025 18.3333 10.0001 18.3333C5.39771 18.3333 1.66675 14.6024 1.66675 10C1.66675 5.39763 5.39771 1.66667 10.0001 1.66667C14.6025 1.66667 18.3334 5.39763 18.3334 10Z"
|
|
265
|
-
stroke="currentColor"
|
|
266
|
-
strokeWidth="1.67"
|
|
267
|
-
strokeLinecap="round"
|
|
268
|
-
strokeLinejoin="round"
|
|
269
|
-
/>
|
|
270
|
-
</svg>
|
|
271
|
-
<span>Link new account</span>
|
|
272
|
-
</div>
|
|
273
|
-
</Button>
|
|
274
369
|
</div>
|
|
275
370
|
|
|
276
|
-
{
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
371
|
+
{!selectedMethod ? (
|
|
372
|
+
<div className="b3-link-account-methods grid gap-3">
|
|
373
|
+
{availableAuthMethods.map(method => (
|
|
374
|
+
<Button
|
|
375
|
+
key={method.id}
|
|
376
|
+
variant="outline"
|
|
377
|
+
className="b3-link-account-method-button border-b3-line hover:border-b3-primary-blue/30 hover:bg-b3-primary-blue/5 text-b3-grey font-neue-montreal-medium h-14 justify-start bg-transparent px-6 text-base transition-all duration-200"
|
|
378
|
+
data-method={method.id}
|
|
379
|
+
onClick={() => {
|
|
380
|
+
if (method.id === "email" || method.id === "phone") {
|
|
381
|
+
setSelectedMethod(method.id);
|
|
382
|
+
} else {
|
|
383
|
+
handleSocialLink(method.id as SocialStrategy);
|
|
384
|
+
}
|
|
385
|
+
}}
|
|
386
|
+
disabled={linkingMethod === method.id}
|
|
387
|
+
>
|
|
388
|
+
{isLinking && linkingMethod === method.id ? (
|
|
389
|
+
<Loader2 className="h-5 w-5 animate-spin" />
|
|
390
|
+
) : (
|
|
391
|
+
<div className="b3-link-account-method-content flex items-center gap-4">
|
|
392
|
+
<div className="b3-link-account-method-icon flex items-center justify-center rounded-full">
|
|
393
|
+
{method.icon}
|
|
297
394
|
</div>
|
|
395
|
+
<span className="b3-link-account-method-label font-medium">{method.label}</span>
|
|
298
396
|
</div>
|
|
299
397
|
)}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
) : (
|
|
320
|
-
"Save"
|
|
321
|
-
)}
|
|
322
|
-
</Button>
|
|
323
|
-
<Button
|
|
324
|
-
size="sm"
|
|
325
|
-
variant="ghost"
|
|
326
|
-
className="referral-code-cancel-button"
|
|
327
|
-
onClick={() => {
|
|
328
|
-
setIsEditingCode(false);
|
|
329
|
-
setNewReferralCode("");
|
|
330
|
-
}}
|
|
331
|
-
>
|
|
332
|
-
Cancel
|
|
333
|
-
</Button>
|
|
334
|
-
</div>
|
|
335
|
-
) : (
|
|
336
|
-
<>
|
|
337
|
-
<div className="referral-code-display rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm">
|
|
338
|
-
{currentReferralCode}
|
|
339
|
-
</div>
|
|
340
|
-
<Button size="icon" variant="ghost" className="referral-code-copy-button" onClick={handleCopyCode}>
|
|
341
|
-
<Copy className="referral-code-copy-icon h-4 w-4" />
|
|
342
|
-
</Button>
|
|
343
|
-
<Button
|
|
344
|
-
size="icon"
|
|
345
|
-
variant="ghost"
|
|
346
|
-
className="referral-code-edit-button"
|
|
347
|
-
onClick={() => {
|
|
348
|
-
setIsEditingCode(true);
|
|
349
|
-
setTimeout(() => {
|
|
350
|
-
referallCodeRef.current?.focus();
|
|
351
|
-
}, 100);
|
|
352
|
-
}}
|
|
353
|
-
>
|
|
354
|
-
<Pencil className="referral-code-edit-icon h-4 w-4" />
|
|
355
|
-
</Button>
|
|
356
|
-
</>
|
|
357
|
-
)}
|
|
358
|
-
</div>
|
|
398
|
+
</Button>
|
|
399
|
+
))}
|
|
400
|
+
{WALLET_METHODS.map(method => {
|
|
401
|
+
if (!method.walletType) {
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return (
|
|
406
|
+
<WalletRow
|
|
407
|
+
key={method.walletType}
|
|
408
|
+
walletId={method.walletType as WalletId}
|
|
409
|
+
onClick={() => handleLinkWallet(method.walletType as WalletId)}
|
|
410
|
+
isLoading={isLinking}
|
|
411
|
+
/>
|
|
412
|
+
);
|
|
413
|
+
})}
|
|
414
|
+
{availableAuthMethods.length === 0 && (
|
|
415
|
+
<div className="text-b3-foreground-muted py-8 text-center">
|
|
416
|
+
All available authentication methods have been connected
|
|
359
417
|
</div>
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
{
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
418
|
+
)}
|
|
419
|
+
</div>
|
|
420
|
+
) : (
|
|
421
|
+
<div className="b3-link-account-form space-y-4">
|
|
422
|
+
{selectedMethod === "email" && (
|
|
423
|
+
<div className="space-y-2">
|
|
424
|
+
<label className="text-b3-grey font-neue-montreal-medium text-sm">Email Address</label>
|
|
425
|
+
<input
|
|
426
|
+
type="email"
|
|
427
|
+
placeholder="Enter your email"
|
|
428
|
+
className="bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2"
|
|
429
|
+
value={email}
|
|
430
|
+
onChange={e => setEmail(e.target.value)}
|
|
431
|
+
disabled={otpSent || (isLinking && linkingMethod === "email")}
|
|
432
|
+
/>
|
|
433
|
+
</div>
|
|
434
|
+
)}
|
|
435
|
+
|
|
436
|
+
{selectedMethod === "phone" && (
|
|
437
|
+
<div className="space-y-2">
|
|
438
|
+
<label className="text-b3-grey font-neue-montreal-medium text-sm">Phone Number</label>
|
|
439
|
+
<input
|
|
440
|
+
type="tel"
|
|
441
|
+
placeholder="Enter your phone number"
|
|
442
|
+
className="bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2"
|
|
443
|
+
value={phone}
|
|
444
|
+
onChange={e => setPhone(e.target.value)}
|
|
445
|
+
disabled={otpSent || (isLinking && linkingMethod === "phone")}
|
|
446
|
+
/>
|
|
447
|
+
<p className="text-b3-foreground-muted font-neue-montreal-medium text-sm">
|
|
448
|
+
Include country code (e.g., +1 for US)
|
|
449
|
+
</p>
|
|
450
|
+
</div>
|
|
451
|
+
)}
|
|
452
|
+
|
|
453
|
+
{error && <div className="text-b3-negative font-neue-montreal-medium py-2 text-sm">{error}</div>}
|
|
454
|
+
|
|
455
|
+
{(selectedMethod === "email" || selectedMethod === "phone") &&
|
|
456
|
+
(otpSent ? (
|
|
457
|
+
<div className="space-y-4">
|
|
458
|
+
<div className="space-y-2">
|
|
459
|
+
<label className="text-b3-grey font-neue-montreal-medium text-sm">Verification Code</label>
|
|
460
|
+
<input
|
|
461
|
+
type="text"
|
|
462
|
+
placeholder="Enter verification code"
|
|
463
|
+
className="bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2"
|
|
464
|
+
value={otp}
|
|
465
|
+
onChange={e => setOtp(e.target.value)}
|
|
466
|
+
/>
|
|
467
|
+
</div>
|
|
468
|
+
<Button
|
|
469
|
+
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white"
|
|
470
|
+
onClick={handleLinkAccount}
|
|
471
|
+
>
|
|
472
|
+
Link Account
|
|
473
|
+
</Button>
|
|
382
474
|
</div>
|
|
383
475
|
) : (
|
|
384
|
-
<
|
|
385
|
-
|
|
386
|
-
|
|
476
|
+
<Button
|
|
477
|
+
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white"
|
|
478
|
+
onClick={handleSendOTP}
|
|
479
|
+
disabled={(!email && !phone) || (isLinking && linkingMethod === selectedMethod)}
|
|
480
|
+
>
|
|
481
|
+
{isLinking && linkingMethod === selectedMethod ? (
|
|
482
|
+
<Loader2 className="animate-spin" />
|
|
483
|
+
) : (
|
|
484
|
+
"Send Verification Code"
|
|
485
|
+
)}
|
|
486
|
+
</Button>
|
|
487
|
+
))}
|
|
387
488
|
</div>
|
|
388
489
|
)}
|
|
389
490
|
</div>
|
|
390
491
|
);
|
|
391
|
-
}
|
|
492
|
+
}
|