@b3dotfun/sdk 0.0.62 → 0.0.63-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.js +61 -23
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +275 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +5 -4
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +288 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +33 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +4 -6
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +66 -147
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +39 -15
- package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/cjs/anyspend/react/components/common/TokenBalance.js +1 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/index.js +11 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +56 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +73 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.js +57 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.js +211 -0
- package/dist/cjs/anyspend/types/api.d.ts +665 -3
- package/dist/cjs/anyspend/utils/orderPayload.js +4 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +17 -4
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.js +141 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/cjs/global-account/react/components/index.d.ts +2 -0
- package/dist/cjs/global-account/react/components/index.js +7 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/index.js +5 -3
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.js +62 -0
- package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/cjs/global-account/react/utils/profileDisplay.js +60 -4
- package/dist/esm/anyspend/react/components/AnySpend.js +62 -24
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +269 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +7 -6
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +285 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +30 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +5 -7
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +67 -148
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +40 -16
- package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/esm/anyspend/react/components/common/TokenBalance.js +2 -2
- package/dist/esm/anyspend/react/components/index.d.ts +5 -1
- package/dist/esm/anyspend/react/components/index.js +5 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +53 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +70 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.js +54 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.js +208 -0
- package/dist/esm/anyspend/types/api.d.ts +665 -3
- package/dist/esm/anyspend/utils/orderPayload.js +4 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +18 -5
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.js +135 -0
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/esm/global-account/react/components/index.d.ts +2 -0
- package/dist/esm/global-account/react/components/index.js +3 -0
- package/dist/esm/global-account/react/hooks/index.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/index.js +2 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.js +59 -0
- package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/esm/global-account/react/utils/profileDisplay.js +59 -4
- package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/types/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/types/anyspend/react/components/index.d.ts +5 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/types/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/types/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/types/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/types/anyspend/types/api.d.ts +665 -3
- package/dist/types/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/types/global-account/react/components/index.d.ts +2 -0
- package/dist/types/global-account/react/hooks/index.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/package.json +4 -3
- package/src/anyspend/react/components/AnySpend.tsx +73 -22
- package/src/anyspend/react/components/AnySpendCustom.tsx +4 -0
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +595 -0
- package/src/anyspend/react/components/AnySpendStakeB3.tsx +8 -11
- package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +522 -0
- package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +73 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +7 -3
- package/src/anyspend/react/components/common/CryptoPaySection.tsx +5 -7
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +9 -18
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +22 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +76 -190
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +2 -3
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +48 -17
- package/src/anyspend/react/components/common/PaySection.tsx +1 -0
- package/src/anyspend/react/components/common/TokenBalance.tsx +2 -2
- package/src/anyspend/react/components/index.ts +5 -1
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +51 -18
- package/src/anyspend/react/hooks/useAnyspendQuote.ts +1 -1
- package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +72 -0
- package/src/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.ts +80 -0
- package/src/anyspend/react/hooks/useConnectedWalletDisplay.ts +69 -0
- package/src/anyspend/react/hooks/usePhantomTransfer.ts +301 -0
- package/src/anyspend/types/api.ts +669 -1
- package/src/anyspend/utils/orderPayload.ts +5 -1
- package/src/global-account/react/components/B3DynamicModal.tsx +18 -4
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +4 -4
- package/src/global-account/react/components/ProfileEditor/ProfileEditor.tsx +265 -0
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +3 -1
- package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +2 -2
- package/src/global-account/react/components/index.ts +4 -0
- package/src/global-account/react/hooks/index.ts +2 -1
- package/src/global-account/react/hooks/useAuthentication.ts +10 -2
- package/src/global-account/react/hooks/useSimBalance.ts +6 -5
- package/src/global-account/react/hooks/useTokenBalanceDirect.tsx +84 -0
- package/src/global-account/react/hooks/useTokenFromUrl.tsx +6 -5
- package/src/global-account/react/stores/useModalStore.ts +43 -1
- package/src/global-account/react/utils/profileDisplay.ts +67 -4
|
@@ -38,6 +38,8 @@ export const buildPayload = (orderType, params) => {
|
|
|
38
38
|
};
|
|
39
39
|
case "custom":
|
|
40
40
|
return { ...payload };
|
|
41
|
+
case "custom_exact_in":
|
|
42
|
+
return { ...payload, expectedDstAmount };
|
|
41
43
|
case "hype_duel":
|
|
42
44
|
return {
|
|
43
45
|
expectedDstAmount,
|
|
@@ -62,6 +64,8 @@ export const buildMetadata = (orderType, params) => {
|
|
|
62
64
|
return { ...baseMetadata, tournament };
|
|
63
65
|
case "custom":
|
|
64
66
|
return { ...baseMetadata, action: payload.action };
|
|
67
|
+
case "custom_exact_in":
|
|
68
|
+
return { ...baseMetadata, action: payload.action };
|
|
65
69
|
case "hype_duel":
|
|
66
70
|
return { ...baseMetadata };
|
|
67
71
|
default:
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
|
|
2
|
+
import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendStakeB3ExactIn, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
|
|
3
3
|
import { AnySpendDepositHype } from "../../../anyspend/react/components/AnyspendDepositHype.js";
|
|
4
4
|
import { AnySpendStakeUpside } from "../../../anyspend/react/components/AnySpendStakeUpside.js";
|
|
5
|
+
import { AnySpendStakeUpsideExactIn } from "../../../anyspend/react/components/AnySpendStakeUpsideExactIn.js";
|
|
5
6
|
import { useGlobalWalletState } from "../../../anyspend/utils/index.js";
|
|
6
7
|
import { useIsMobile, useModalStore } from "../../../global-account/react/index.js";
|
|
7
8
|
import { cn } from "../../../shared/utils/cn.js";
|
|
8
9
|
import { debugB3React } from "../../../shared/utils/debug.js";
|
|
9
10
|
import { useEffect, useRef } from "react";
|
|
11
|
+
import { useSetActiveWallet } from "thirdweb/react";
|
|
10
12
|
import { AvatarEditor } from "./AvatarEditor/AvatarEditor.js";
|
|
11
13
|
import { useB3 } from "./B3Provider/useB3.js";
|
|
12
14
|
import { LinkAccount } from "./LinkAccount/LinkAccount.js";
|
|
15
|
+
import { ProfileEditor } from "./ProfileEditor/ProfileEditor.js";
|
|
13
16
|
import { ManageAccount } from "./ManageAccount/ManageAccount.js";
|
|
14
17
|
import { RequestPermissions } from "./RequestPermissions/RequestPermissions.js";
|
|
15
18
|
import { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow.js";
|
|
16
19
|
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./ui/dialog.js";
|
|
17
20
|
import { Drawer, DrawerContent, DrawerDescription, DrawerTitle } from "./ui/drawer.js";
|
|
18
|
-
import { useSetActiveWallet } from "thirdweb/react";
|
|
19
21
|
const debug = debugB3React("B3DynamicModal");
|
|
20
22
|
export function B3DynamicModal() {
|
|
21
23
|
const { isOpen, setB3ModalOpen, contentType, history, navigateBack } = useModalStore();
|
|
@@ -42,7 +44,9 @@ export function B3DynamicModal() {
|
|
|
42
44
|
"anySpendJoinTournament",
|
|
43
45
|
"anySpendFundTournament",
|
|
44
46
|
"anySpendStakeB3",
|
|
47
|
+
"anySpendStakeB3ExactIn",
|
|
45
48
|
"anySpendStakeUpside",
|
|
49
|
+
"anySpendStakeUpsideExactIn",
|
|
46
50
|
"anySpendBuySpin",
|
|
47
51
|
"anySpendOrderHistory",
|
|
48
52
|
"signInWithB3",
|
|
@@ -50,13 +54,16 @@ export function B3DynamicModal() {
|
|
|
50
54
|
"anySpendBondKit",
|
|
51
55
|
"linkAccount",
|
|
52
56
|
"avatarEditor",
|
|
57
|
+
"profileEditor",
|
|
53
58
|
];
|
|
54
59
|
const freestyleTypes = [
|
|
55
60
|
"anySpendNft",
|
|
56
61
|
"anySpendJoinTournament",
|
|
57
62
|
"anySpendFundTournament",
|
|
58
63
|
"anySpendStakeB3",
|
|
64
|
+
"anySpendStakeB3ExactIn",
|
|
59
65
|
"anySpendStakeUpside",
|
|
66
|
+
"anySpendStakeUpsideExactIn",
|
|
60
67
|
"anySpendBuySpin",
|
|
61
68
|
"anySpendSignatureMint",
|
|
62
69
|
"anySpendBondKit",
|
|
@@ -92,8 +99,12 @@ export function B3DynamicModal() {
|
|
|
92
99
|
return _jsx(OrderHistory, { onBack: () => { }, mode: "modal" });
|
|
93
100
|
case "anySpendStakeB3":
|
|
94
101
|
return _jsx(AnySpendStakeB3, { ...contentType, mode: "modal" });
|
|
102
|
+
case "anySpendStakeB3ExactIn":
|
|
103
|
+
return _jsx(AnySpendStakeB3ExactIn, { ...contentType, mode: "modal" });
|
|
95
104
|
case "anySpendStakeUpside":
|
|
96
105
|
return _jsx(AnySpendStakeUpside, { ...contentType, mode: "modal" });
|
|
106
|
+
case "anySpendStakeUpsideExactIn":
|
|
107
|
+
return _jsx(AnySpendStakeUpsideExactIn, { ...contentType, mode: "modal" });
|
|
97
108
|
case "anySpendBuySpin":
|
|
98
109
|
return _jsx(AnySpendBuySpin, { ...contentType, mode: "modal" });
|
|
99
110
|
case "anySpendSignatureMint":
|
|
@@ -106,6 +117,8 @@ export function B3DynamicModal() {
|
|
|
106
117
|
return _jsx(AnySpendDepositHype, { ...contentType, mode: "modal" });
|
|
107
118
|
case "avatarEditor":
|
|
108
119
|
return _jsx(AvatarEditor, { onSetAvatar: contentType.onSuccess });
|
|
120
|
+
case "profileEditor":
|
|
121
|
+
return _jsx(ProfileEditor, { onSuccess: contentType.onSuccess });
|
|
109
122
|
// Add other modal types here
|
|
110
123
|
default:
|
|
111
124
|
return null;
|
|
@@ -116,8 +129,8 @@ export function B3DynamicModal() {
|
|
|
116
129
|
const ModalTitle = isMobile ? DrawerTitle : DialogTitle;
|
|
117
130
|
const ModalDescription = isMobile ? DrawerDescription : DialogDescription;
|
|
118
131
|
return (_jsxs(ModalComponent, { open: isOpen, onOpenChange: setB3ModalOpen, children: [_jsxs(ModalContent, { className: cn(contentClass, "rounded-2xl bg-white shadow-xl dark:bg-gray-900", "border border-gray-200 dark:border-gray-800",
|
|
119
|
-
// Remove default width classes for avatar editor
|
|
120
|
-
contentType?.type === "avatarEditor"
|
|
132
|
+
// Remove default width classes for avatar editor and profile editor
|
|
133
|
+
contentType?.type === "avatarEditor" || contentType?.type === "profileEditor"
|
|
121
134
|
? "!w-[90vw] !max-w-none" // Use !important to override default styles
|
|
122
|
-
: "mx-auto w-full max-w-md sm:max-w-lg"), hideCloseButton: hideCloseButton, children: [_jsx(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), _jsx(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), _jsxs("div", { className: cn("no-scrollbar max-h-[90dvh] overflow-auto sm:max-h-[80dvh]"), children: [history.length > 0 && contentType?.showBackButton && (_jsxs("button", { onClick: navigateBack, className: "flex items-center gap-2 px-6 py-4 text-gray-600 transition-colors hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: [_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), _jsx("span", { className: "text-sm font-medium", children: "Back" })] })), renderContent()] })] }), contentType?.type === "avatarEditor" && (_jsx("button", { onClick: () => setB3ModalOpen(false), className: "fixed right-5 top-5 z-[100] cursor-pointer text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M18 6L6 18M6 6L18 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }))] }));
|
|
135
|
+
: "mx-auto w-full max-w-md sm:max-w-lg"), hideCloseButton: hideCloseButton, children: [_jsx(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), _jsx(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), _jsxs("div", { className: cn("no-scrollbar max-h-[90dvh] overflow-auto sm:max-h-[80dvh]"), children: [history.length > 0 && contentType?.showBackButton && (_jsxs("button", { onClick: navigateBack, className: "flex items-center gap-2 px-6 py-4 text-gray-600 transition-colors hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: [_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), _jsx("span", { className: "text-sm font-medium", children: "Back" })] })), renderContent()] })] }), (contentType?.type === "avatarEditor" || contentType?.type === "profileEditor") && (_jsx("button", { onClick: () => setB3ModalOpen(false), className: "fixed right-5 top-5 z-[100] cursor-pointer text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M18 6L6 18M6 6L18 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }))] }));
|
|
123
136
|
}
|
|
@@ -32,10 +32,10 @@ export function BalanceContent({ onLogout, showDeposit = true, showSwap = true }
|
|
|
32
32
|
const [openAccordions, setOpenAccordions] = useState([]);
|
|
33
33
|
const hasExpandedRef = useRef(false);
|
|
34
34
|
const avatarUrl = user?.avatar ? getIpfsUrl(user?.avatar) : profile?.avatar;
|
|
35
|
-
const
|
|
35
|
+
const handleEditProfile = () => {
|
|
36
36
|
setB3ModalOpen(true);
|
|
37
37
|
setB3ModalContentType({
|
|
38
|
-
type: "
|
|
38
|
+
type: "profileEditor",
|
|
39
39
|
showBackButton: true,
|
|
40
40
|
onSuccess: () => {
|
|
41
41
|
// navigate back on success
|
|
@@ -87,7 +87,7 @@ export function BalanceContent({ onLogout, showDeposit = true, showSwap = true }
|
|
|
87
87
|
setB3ModalOpen(false);
|
|
88
88
|
setLogoutLoading(false);
|
|
89
89
|
};
|
|
90
|
-
return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "global-account-profile flex items-center gap-4", children: [_jsxs("div", { className: "global-account-profile-avatar relative", children: [avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "Profile", className: "size-24 rounded-full" })) : (_jsx("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), _jsx("button", { onClick:
|
|
90
|
+
return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "global-account-profile flex items-center gap-4", children: [_jsxs("div", { className: "global-account-profile-avatar relative", children: [avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "Profile", className: "size-24 rounded-full" })) : (_jsx("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), _jsx("button", { onClick: handleEditProfile, className: "bg-b3-grey border-b3-background hover:bg-b3-grey/80 absolute -bottom-1 -right-1 flex size-8 items-center justify-center rounded-full border-4 transition-colors", children: _jsx(Pencil, { size: 16, className: "text-b3-background" }) })] }), _jsxs("div", { className: "global-account-profile-info", children: [_jsx("h2", { className: "text-b3-grey text-xl font-semibold", children: user?.username || profile?.displayName || formatUsername(profile?.name || "") }), _jsxs("div", { className: "address-button border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [_jsx("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), _jsx(CopyToClipboard, { text: account?.address || "" })] })] })] }) }), (showDeposit || showSwap) && (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [showDeposit && (_jsxs(Button, { className: "manage-account-deposit bg-b3-primary-wash hover:bg-b3-primary-wash/70 h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
|
|
91
91
|
setB3ModalOpen(true);
|
|
92
92
|
setB3ModalContentType({
|
|
93
93
|
type: "anySpend",
|
|
@@ -0,0 +1,135 @@
|
|
|
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 { validateImageUrl } from "../../../../global-account/react/utils/profileDisplay.js";
|
|
6
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
7
|
+
import { debugB3React } from "../../../../shared/utils/debug.js";
|
|
8
|
+
import { getIpfsUrl } from "../../../../shared/utils/ipfs.js";
|
|
9
|
+
import { client } from "../../../../shared/utils/thirdweb.js";
|
|
10
|
+
import { Check, Loader2, Upload, X } from "lucide-react";
|
|
11
|
+
import { useRef, useState } from "react";
|
|
12
|
+
import { toast } from "sonner";
|
|
13
|
+
import { useActiveAccount } from "thirdweb/react";
|
|
14
|
+
import { upload } from "thirdweb/storage";
|
|
15
|
+
const debug = debugB3React("ProfileEditor");
|
|
16
|
+
export function ProfileEditor({ onSuccess, className }) {
|
|
17
|
+
const [selectedFile, setSelectedFile] = useState(null);
|
|
18
|
+
const [previewUrl, setPreviewUrl] = useState(null);
|
|
19
|
+
const [username, setUsername] = useState("");
|
|
20
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
21
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
22
|
+
const fileInputRef = useRef(null);
|
|
23
|
+
const { user, setUser } = useB3();
|
|
24
|
+
const account = useActiveAccount();
|
|
25
|
+
const { data: profile, refetch: refreshProfile } = useProfile({
|
|
26
|
+
address: account?.address,
|
|
27
|
+
fresh: true,
|
|
28
|
+
});
|
|
29
|
+
const rawAvatarUrl = user?.avatar ? getIpfsUrl(user?.avatar) : profile?.avatar;
|
|
30
|
+
const avatarUrl = validateImageUrl(rawAvatarUrl);
|
|
31
|
+
const safePreviewUrl = validateImageUrl(previewUrl);
|
|
32
|
+
const hasAvatar = !!avatarUrl;
|
|
33
|
+
const currentUsername = user?.username || "";
|
|
34
|
+
const handleFileSelect = (event) => {
|
|
35
|
+
const file = event.target.files?.[0];
|
|
36
|
+
if (file) {
|
|
37
|
+
// Validate file type
|
|
38
|
+
if (!file.type.startsWith("image/")) {
|
|
39
|
+
toast.error("Please select an image file");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Validate file size (max 5MB)
|
|
43
|
+
if (file.size > 5 * 1024 * 1024) {
|
|
44
|
+
toast.error("File size must be less than 5MB");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
setSelectedFile(file);
|
|
48
|
+
// Create preview URL
|
|
49
|
+
const url = URL.createObjectURL(file);
|
|
50
|
+
setPreviewUrl(url);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const handleRemoveFile = () => {
|
|
54
|
+
setSelectedFile(null);
|
|
55
|
+
if (previewUrl) {
|
|
56
|
+
URL.revokeObjectURL(previewUrl);
|
|
57
|
+
setPreviewUrl(null);
|
|
58
|
+
}
|
|
59
|
+
if (fileInputRef.current) {
|
|
60
|
+
fileInputRef.current.value = "";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const handleSave = async () => {
|
|
64
|
+
// Check if there are any changes
|
|
65
|
+
const hasAvatarChange = selectedFile !== null;
|
|
66
|
+
const hasUsernameChange = username.trim() !== "" && username !== currentUsername;
|
|
67
|
+
if (!hasAvatarChange && !hasUsernameChange) {
|
|
68
|
+
toast.error("Please make at least one change");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setIsSaving(true);
|
|
72
|
+
try {
|
|
73
|
+
let ipfsUrl;
|
|
74
|
+
// Upload avatar if selected
|
|
75
|
+
if (hasAvatarChange && selectedFile) {
|
|
76
|
+
debug("Starting upload to IPFS", selectedFile);
|
|
77
|
+
setIsUploading(true);
|
|
78
|
+
ipfsUrl = await upload({
|
|
79
|
+
client,
|
|
80
|
+
files: [selectedFile],
|
|
81
|
+
});
|
|
82
|
+
debug("Upload successful", ipfsUrl);
|
|
83
|
+
setIsUploading(false);
|
|
84
|
+
}
|
|
85
|
+
// Update user profile
|
|
86
|
+
let updatedUser = user;
|
|
87
|
+
// If both avatar and username need updating, do them sequentially
|
|
88
|
+
// Update avatar first if uploaded
|
|
89
|
+
if (ipfsUrl) {
|
|
90
|
+
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
91
|
+
updatedUser = await app.service("users").setAvatar({
|
|
92
|
+
avatar: ipfsUrl,
|
|
93
|
+
},
|
|
94
|
+
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
95
|
+
{});
|
|
96
|
+
}
|
|
97
|
+
// Update username if changed (this will use the updated user from avatar change if both were updated)
|
|
98
|
+
if (hasUsernameChange && user?._id) {
|
|
99
|
+
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
100
|
+
updatedUser = await app.service("users").registerUsername({ username: username },
|
|
101
|
+
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
102
|
+
{});
|
|
103
|
+
}
|
|
104
|
+
// Update user state
|
|
105
|
+
setUser(updatedUser);
|
|
106
|
+
// Refresh profile to get updated data
|
|
107
|
+
await refreshProfile();
|
|
108
|
+
// Show success message
|
|
109
|
+
const changes = [];
|
|
110
|
+
if (hasAvatarChange)
|
|
111
|
+
changes.push("avatar");
|
|
112
|
+
if (hasUsernameChange)
|
|
113
|
+
changes.push("username");
|
|
114
|
+
toast.success(`Successfully updated ${changes.join(" and ")}!`);
|
|
115
|
+
onSuccess?.();
|
|
116
|
+
// Clean up
|
|
117
|
+
handleRemoveFile();
|
|
118
|
+
setUsername("");
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
debug("Error updating profile:", error);
|
|
122
|
+
toast.error("Failed to update profile. Please try again.");
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setIsUploading(false);
|
|
126
|
+
setIsSaving(false);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const handleFileInputClick = () => {
|
|
130
|
+
fileInputRef.current?.click();
|
|
131
|
+
};
|
|
132
|
+
const isLoading = isUploading || isSaving;
|
|
133
|
+
const hasChanges = selectedFile !== null || (username.trim() !== "" && username !== currentUsername);
|
|
134
|
+
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: "Edit Your Profile" }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium", children: "Update your avatar and username" })] }), _jsxs("div", { className: "w-full max-w-md space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "Avatar" }), _jsx("div", { className: "flex justify-center", children: safePreviewUrl || avatarUrl ? (_jsxs("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: safePreviewUrl || avatarUrl || "", alt: safePreviewUrl ? "Preview" : "Current avatar", className: "h-full w-full object-cover" }) }), safePreviewUrl && (_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 }) }))] })) : (_jsx("div", { className: "bg-b3-primary-wash h-32 w-32 rounded-full" })) }), !selectedFile && (_jsxs(Button, { variant: "outline", onClick: handleFileInputClick, disabled: isLoading, className: "w-full", children: [_jsx(Upload, { className: "mr-2 h-4 w-4" }), hasAvatar ? "Change Avatar" : "Upload Avatar"] })), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { htmlFor: "username", className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "Username" }), _jsx("input", { id: "username", type: "text", value: username, onChange: e => setUsername(e.target.value), placeholder: currentUsername || "Enter username", className: "border-b3-line bg-b3-background text-b3-grey placeholder:text-b3-foreground-muted font-neue-montreal-medium focus:border-b3-primary-blue w-full rounded-lg border px-4 py-3 transition-colors focus:outline-none", disabled: isLoading }), currentUsername && (_jsxs("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-xs", children: ["Current: ", currentUsername] }))] })] }), _jsx("div", { className: "flex w-full max-w-md gap-3", children: _jsx(Button, { onClick: handleSave, disabled: isLoading || !hasChanges, className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white disabled:opacity-50", 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" }), "Save Changes"] })) }) }), _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." }) })] }));
|
|
135
|
+
}
|
|
@@ -19,6 +19,7 @@ export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySucce
|
|
|
19
19
|
const { setB3ModalContentType, setB3ModalOpen, isOpen } = useModalStore();
|
|
20
20
|
const account = useActiveAccount();
|
|
21
21
|
const isAuthenticating = useAuthStore(state => state.isAuthenticating);
|
|
22
|
+
const isAuthenticated = useAuthStore(state => state.isAuthenticated);
|
|
22
23
|
const isConnected = useAuthStore(state => state.isConnected);
|
|
23
24
|
const [refetchCount, setRefetchCount] = useState(0);
|
|
24
25
|
const [refetchError, setRefetchError] = useState(null);
|
|
@@ -61,7 +62,7 @@ export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySucce
|
|
|
61
62
|
isOpen,
|
|
62
63
|
source,
|
|
63
64
|
});
|
|
64
|
-
if (isConnected) {
|
|
65
|
+
if (isConnected && isAuthenticated) {
|
|
65
66
|
// Check if we already have a signer for this partner
|
|
66
67
|
const hasExistingSigner = signers?.some(signer => signer.partner.id === partnerId);
|
|
67
68
|
if (hasExistingSigner) {
|
|
@@ -111,6 +112,7 @@ export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySucce
|
|
|
111
112
|
signersEnabled,
|
|
112
113
|
isConnected,
|
|
113
114
|
isAuthenticating,
|
|
115
|
+
isAuthenticated,
|
|
114
116
|
isOpen,
|
|
115
117
|
]);
|
|
116
118
|
debug("render", {
|
|
@@ -37,8 +37,8 @@ export function LoginStep({ onSuccess, chain }) {
|
|
|
37
37
|
}, header: {
|
|
38
38
|
title: "Sign in with B3",
|
|
39
39
|
titleIcon: "https://cdn.b3.fun/b3_logo.svg",
|
|
40
|
-
}, className: "b3-login-step", onConnect: async (wallet) => {
|
|
41
|
-
await onConnect(wallet);
|
|
40
|
+
}, className: "b3-login-step", onConnect: async (wallet, allConnectedWallets) => {
|
|
41
|
+
await onConnect(wallet, allConnectedWallets);
|
|
42
42
|
const account = wallet.getAccount();
|
|
43
43
|
if (!account)
|
|
44
44
|
throw new Error("No account found");
|
|
@@ -13,6 +13,8 @@ export { SignInWithB3Privy } from "./SignInWithB3/SignInWithB3Privy";
|
|
|
13
13
|
export { LoginStepContainer } from "./SignInWithB3/steps/LoginStep";
|
|
14
14
|
export { getConnectOptionsFromStrategy, isWalletType, type AllowedStrategy } from "./SignInWithB3/utils/signInUtils";
|
|
15
15
|
export { ManageAccount } from "./ManageAccount/ManageAccount";
|
|
16
|
+
export { AvatarEditor } from "./AvatarEditor/AvatarEditor";
|
|
17
|
+
export { ProfileEditor } from "./ProfileEditor/ProfileEditor";
|
|
16
18
|
export { RequestPermissions } from "./RequestPermissions/RequestPermissions";
|
|
17
19
|
export { RequestPermissionsButton } from "./RequestPermissions/RequestPermissionsButton";
|
|
18
20
|
export { AccountAssets } from "./AccountAssets/AccountAssets";
|
|
@@ -16,6 +16,9 @@ export { LoginStepContainer } from "./SignInWithB3/steps/LoginStep.js";
|
|
|
16
16
|
export { getConnectOptionsFromStrategy, isWalletType } from "./SignInWithB3/utils/signInUtils.js";
|
|
17
17
|
// ManageAccount Components
|
|
18
18
|
export { ManageAccount } from "./ManageAccount/ManageAccount.js";
|
|
19
|
+
// Profile Components
|
|
20
|
+
export { AvatarEditor } from "./AvatarEditor/AvatarEditor.js";
|
|
21
|
+
export { ProfileEditor } from "./ProfileEditor/ProfileEditor.js";
|
|
19
22
|
// RequestPermissions Components
|
|
20
23
|
export { RequestPermissions } from "./RequestPermissions/RequestPermissions.js";
|
|
21
24
|
export { RequestPermissionsButton } from "./RequestPermissions/RequestPermissionsButton.js";
|
|
@@ -32,11 +32,12 @@ export { useSearchParamsSSR } from "./useSearchParamsSSR";
|
|
|
32
32
|
export { useSimBalance } from "./useSimBalance";
|
|
33
33
|
export { useSiwe } from "./useSiwe";
|
|
34
34
|
export { useTokenBalance } from "./useTokenBalance";
|
|
35
|
+
export { useTokenBalanceDirect } from "./useTokenBalanceDirect";
|
|
35
36
|
export { useTokenBalancesByChain } from "./useTokenBalancesByChain";
|
|
36
37
|
export { useTokenData } from "./useTokenData";
|
|
37
38
|
export { useTokenFromUrl } from "./useTokenFromUrl";
|
|
38
39
|
export { useTokenPrice } from "./useTokenPrice";
|
|
39
40
|
export { useTokenPriceWithFallback } from "./useTokenPriceWithFallback";
|
|
40
41
|
export { useTokensFromAddress } from "./useTokensFromAddress";
|
|
41
|
-
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute";
|
|
42
42
|
export { useURLParams } from "./useURLParams";
|
|
43
|
+
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute";
|
|
@@ -32,11 +32,12 @@ export { useSearchParamsSSR } from "./useSearchParamsSSR.js";
|
|
|
32
32
|
export { useSimBalance } from "./useSimBalance.js";
|
|
33
33
|
export { useSiwe } from "./useSiwe.js";
|
|
34
34
|
export { useTokenBalance } from "./useTokenBalance.js";
|
|
35
|
+
export { useTokenBalanceDirect } from "./useTokenBalanceDirect.js";
|
|
35
36
|
export { useTokenBalancesByChain } from "./useTokenBalancesByChain.js";
|
|
36
37
|
export { useTokenData } from "./useTokenData.js";
|
|
37
38
|
export { useTokenFromUrl } from "./useTokenFromUrl.js";
|
|
38
39
|
export { useTokenPrice } from "./useTokenPrice.js";
|
|
39
40
|
export { useTokenPriceWithFallback } from "./useTokenPriceWithFallback.js";
|
|
40
41
|
export { useTokensFromAddress } from "./useTokensFromAddress.js";
|
|
41
|
-
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute.js";
|
|
42
42
|
export { useURLParams } from "./useURLParams.js";
|
|
43
|
+
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute.js";
|
|
@@ -8,9 +8,9 @@ export declare function useAuthentication(partnerId: string): {
|
|
|
8
8
|
isConnected: boolean;
|
|
9
9
|
wallet: import("thirdweb/dist/types/wallets/in-app/core/wallet/types").EcosystemWallet;
|
|
10
10
|
preAuthenticate: typeof preAuthenticate;
|
|
11
|
-
connect: (
|
|
11
|
+
connect: (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => Promise<void>;
|
|
12
12
|
isAuthenticating: boolean;
|
|
13
|
-
onConnect: (
|
|
13
|
+
onConnect: (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => Promise<void>;
|
|
14
14
|
user: {
|
|
15
15
|
email?: string | undefined;
|
|
16
16
|
username?: string | undefined;
|
|
@@ -136,7 +136,12 @@ export function useAuthentication(partnerId) {
|
|
|
136
136
|
return userAuth;
|
|
137
137
|
}
|
|
138
138
|
}, [activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting]);
|
|
139
|
-
const onConnect = useCallback(async (
|
|
139
|
+
const onConnect = useCallback(async (_walleAutoConnectedWith, allConnectedWallets) => {
|
|
140
|
+
debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
|
|
141
|
+
const wallet = allConnectedWallets.find(wallet => wallet.id.startsWith("ecosystem."));
|
|
142
|
+
if (!wallet) {
|
|
143
|
+
throw new Error("No smart wallet found during auto-connect");
|
|
144
|
+
}
|
|
140
145
|
debug("@@useAuthentication:onConnect", { wallet });
|
|
141
146
|
try {
|
|
142
147
|
setHasStartedConnecting(true);
|
|
@@ -203,7 +208,7 @@ export function useAuthentication(partnerId) {
|
|
|
203
208
|
const { isLoading: useAutoConnectLoading } = useAutoConnect({
|
|
204
209
|
client,
|
|
205
210
|
wallets: [wallet],
|
|
206
|
-
onConnect
|
|
211
|
+
onConnect,
|
|
207
212
|
});
|
|
208
213
|
/**
|
|
209
214
|
* useAutoConnectLoading starts as false
|
|
@@ -21,4 +21,4 @@ export interface SimBalanceResponse {
|
|
|
21
21
|
wallet_address: string;
|
|
22
22
|
balances: SimBalanceItem[];
|
|
23
23
|
}
|
|
24
|
-
export declare function useSimBalance(address?: string): import("@tanstack/react-query").UseQueryResult<SimBalanceResponse, Error>;
|
|
24
|
+
export declare function useSimBalance(address?: string, chainIdsParam?: number[]): import("@tanstack/react-query").UseQueryResult<SimBalanceResponse, Error>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
|
2
|
-
async function fetchSimBalance(address) {
|
|
2
|
+
async function fetchSimBalance(address, chainIdsParam) {
|
|
3
3
|
if (!address)
|
|
4
4
|
throw new Error("Address is required");
|
|
5
|
-
|
|
5
|
+
const chainIds = chainIdsParam.length === 0 ? "mainnet" : chainIdsParam.join(",");
|
|
6
|
+
let url = `https://simdune-api.sean-430.workers.dev/?url=https://api.sim.dune.com/v1/evm/balances/${address}?metadata=logo&chain_ids=${chainIds}`;
|
|
6
7
|
if (process.env.NEXT_PUBLIC_LOCAL_KEY) {
|
|
7
8
|
url += `&localkey=${process.env.NEXT_PUBLIC_LOCAL_KEY}`;
|
|
8
9
|
}
|
|
@@ -13,13 +14,13 @@ async function fetchSimBalance(address) {
|
|
|
13
14
|
const balanceData = await response.json();
|
|
14
15
|
return balanceData;
|
|
15
16
|
}
|
|
16
|
-
export function useSimBalance(address) {
|
|
17
|
+
export function useSimBalance(address, chainIdsParam) {
|
|
17
18
|
return useQuery({
|
|
18
|
-
queryKey: ["simBalance", address],
|
|
19
|
+
queryKey: ["simBalance", address, chainIdsParam],
|
|
19
20
|
queryFn: () => {
|
|
20
21
|
if (!address)
|
|
21
22
|
throw new Error("Address is required");
|
|
22
|
-
return fetchSimBalance(address);
|
|
23
|
+
return fetchSimBalance(address, chainIdsParam || []);
|
|
23
24
|
},
|
|
24
25
|
enabled: Boolean(address),
|
|
25
26
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { components } from "../../../anyspend/types/api";
|
|
2
|
+
interface UseTokenBalanceProps {
|
|
3
|
+
token: components["schemas"]["Token"];
|
|
4
|
+
address?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TokenBalanceResult {
|
|
7
|
+
rawBalance: bigint | null;
|
|
8
|
+
formattedBalance: string;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function useTokenBalanceDirect({ token, address }: UseTokenBalanceProps): TokenBalanceResult;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isNativeToken } from "../../../anyspend/index.js";
|
|
3
|
+
import { useAccountWallet } from "../../../global-account/react/index.js";
|
|
4
|
+
import { formatTokenAmount } from "../../../shared/utils/number.js";
|
|
5
|
+
import { getERC20Balances, getNativeTokenBalance } from "../../../shared/utils/thirdweb-insights.js";
|
|
6
|
+
import { useQuery } from "@tanstack/react-query";
|
|
7
|
+
import { useEffect } from "react";
|
|
8
|
+
export function useTokenBalanceDirect({ token, address }) {
|
|
9
|
+
const account = useAccountWallet();
|
|
10
|
+
const effectiveAddress = address || account?.address;
|
|
11
|
+
const { data: tokenBalance, isLoading, isFetching, refetch, } = useQuery({
|
|
12
|
+
queryKey: ["tokenBalance", effectiveAddress, token.chainId, token.address],
|
|
13
|
+
queryFn: async () => {
|
|
14
|
+
if (!effectiveAddress)
|
|
15
|
+
return { formatted: "0", raw: null };
|
|
16
|
+
if (isNativeToken(token.address)) {
|
|
17
|
+
const nativeToken = await getNativeTokenBalance(effectiveAddress, token.chainId);
|
|
18
|
+
if (nativeToken && nativeToken.balance) {
|
|
19
|
+
const rawBalance = nativeToken.balance;
|
|
20
|
+
return {
|
|
21
|
+
formatted: formatTokenAmount(BigInt(rawBalance), Number(nativeToken.decimals || 18)),
|
|
22
|
+
raw: BigInt(rawBalance),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return { formatted: "0", raw: null };
|
|
26
|
+
}
|
|
27
|
+
const response = await getERC20Balances(effectiveAddress, {
|
|
28
|
+
chainIds: [token.chainId],
|
|
29
|
+
includeSpam: false,
|
|
30
|
+
});
|
|
31
|
+
const tokenBalance = response.data?.find(t => t.token_address === token.address);
|
|
32
|
+
if (tokenBalance?.balance) {
|
|
33
|
+
return {
|
|
34
|
+
formatted: formatTokenAmount(BigInt(tokenBalance.balance), Number(tokenBalance.decimals || 18)),
|
|
35
|
+
raw: BigInt(tokenBalance.balance),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return { formatted: "0", raw: null };
|
|
39
|
+
},
|
|
40
|
+
enabled: !!effectiveAddress,
|
|
41
|
+
staleTime: 30000,
|
|
42
|
+
gcTime: 5 * 60 * 1000,
|
|
43
|
+
retry: 2,
|
|
44
|
+
structuralSharing: false,
|
|
45
|
+
});
|
|
46
|
+
// Force a refetch when the wallet or token changes
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (effectiveAddress) {
|
|
49
|
+
refetch();
|
|
50
|
+
}
|
|
51
|
+
}, [effectiveAddress, token.address, token.chainId, token.symbol, refetch]);
|
|
52
|
+
// Determine if we're actually loading
|
|
53
|
+
const isActuallyLoading = !effectiveAddress || isLoading || (isFetching && !tokenBalance);
|
|
54
|
+
return {
|
|
55
|
+
rawBalance: tokenBalance?.raw || BigInt(0),
|
|
56
|
+
formattedBalance: tokenBalance?.formatted || "0",
|
|
57
|
+
isLoading: isActuallyLoading,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -28,10 +28,11 @@ export function useTokenFromUrl({ defaultToken, prefix }) {
|
|
|
28
28
|
// Get parameters from URL
|
|
29
29
|
const currencyParam = searchParams.get(`${prefix}Currency`);
|
|
30
30
|
const chainIdParam = searchParams.get(`${prefix}ChainId`);
|
|
31
|
-
// Determine if we should fetch token info
|
|
32
|
-
const shouldFetchToken = Boolean(currencyParam && chainIdParam && currencyParam.toLowerCase() !== defaultToken.address.toLowerCase());
|
|
33
31
|
// Determine network based on chainId
|
|
34
|
-
const
|
|
32
|
+
const chainInfo = chainIdParam ? getCoingeckoChainInfo(Number(chainIdParam)) : null;
|
|
33
|
+
const network = chainInfo?.coingecko_id || "";
|
|
34
|
+
// Determine if we should fetch token info
|
|
35
|
+
const shouldFetchToken = Boolean(currencyParam && chainIdParam && chainInfo && currencyParam.toLowerCase() !== defaultToken.address.toLowerCase());
|
|
35
36
|
const { data: tokenInfo, isError } = useQuery({
|
|
36
37
|
queryKey: ["tokenInfo", network, currencyParam],
|
|
37
38
|
queryFn: () => fetchTokenInfo(network, currencyParam || ""),
|
|
@@ -210,6 +210,20 @@ export interface AnySpendStakeB3Props extends BaseModalProps {
|
|
|
210
210
|
/** Callback function called when the stake is successful */
|
|
211
211
|
onSuccess?: () => void;
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Props for the AnySpend Stake B3 (Custom Exact In) modal
|
|
215
|
+
* Handles B3 token staking operations using the custom exact in flow
|
|
216
|
+
*/
|
|
217
|
+
export interface AnySpendStakeB3ExactInProps extends BaseModalProps {
|
|
218
|
+
/** Modal type identifier */
|
|
219
|
+
type: "anySpendStakeB3ExactIn";
|
|
220
|
+
/** Recipient address to stake B3 for */
|
|
221
|
+
recipientAddress: string;
|
|
222
|
+
/** Stake amount */
|
|
223
|
+
stakeAmount?: string;
|
|
224
|
+
/** Callback function called when the stake is successful */
|
|
225
|
+
onSuccess?: () => void;
|
|
226
|
+
}
|
|
213
227
|
/**
|
|
214
228
|
* Props for the AnySpend Stake Contract modal
|
|
215
229
|
* Handles token staking operations to a given contract
|
|
@@ -230,6 +244,22 @@ export interface AnySpendStakeUpsideProps extends BaseModalProps {
|
|
|
230
244
|
/** Callback function called when the stake is successful */
|
|
231
245
|
onSuccess?: () => void;
|
|
232
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Props for the AnySpend Stake Upside (Exact In) modal
|
|
249
|
+
* Handles token staking operations using the custom exact in flow
|
|
250
|
+
*/
|
|
251
|
+
export interface AnySpendStakeUpsideExactInProps extends BaseModalProps {
|
|
252
|
+
/** Modal type identifier */
|
|
253
|
+
type: "anySpendStakeUpsideExactIn";
|
|
254
|
+
/** Recipient address to stake tokens for */
|
|
255
|
+
recipientAddress: string;
|
|
256
|
+
/** Staking contract address */
|
|
257
|
+
stakingContractAddress: string;
|
|
258
|
+
/** Token to stake */
|
|
259
|
+
token: components["schemas"]["Token"];
|
|
260
|
+
/** Callback function called when the stake is successful */
|
|
261
|
+
onSuccess?: () => void;
|
|
262
|
+
}
|
|
233
263
|
/**
|
|
234
264
|
* Props for the AnySpend Buy Spin modal
|
|
235
265
|
* Handles spin wheel entry purchases
|
|
@@ -321,10 +351,16 @@ export interface AvatarEditorModalProps extends BaseModalProps {
|
|
|
321
351
|
/** Callback function called when avatar is successfully set */
|
|
322
352
|
onSuccess?: () => void;
|
|
323
353
|
}
|
|
354
|
+
export interface ProfileEditorModalProps extends BaseModalProps {
|
|
355
|
+
/** Modal type identifier */
|
|
356
|
+
type: "profileEditor";
|
|
357
|
+
/** Callback function called when profile is successfully updated */
|
|
358
|
+
onSuccess?: () => void;
|
|
359
|
+
}
|
|
324
360
|
/**
|
|
325
361
|
* Union type of all possible modal content types
|
|
326
362
|
*/
|
|
327
|
-
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps;
|
|
363
|
+
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | ProfileEditorModalProps;
|
|
328
364
|
/**
|
|
329
365
|
* State interface for the modal store
|
|
330
366
|
*/
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { type Profile } from "thirdweb/wallets";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that an image URL uses an allowed schema
|
|
4
|
+
* @param url - The URL to validate
|
|
5
|
+
* @returns The URL if valid, null otherwise
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateImageUrl(url: string | null | undefined): string | null;
|
|
2
8
|
export interface ExtendedProfileDetails {
|
|
3
9
|
id?: string;
|
|
4
10
|
email?: string;
|