@b3dotfun/sdk 0.0.35-alpha.3 → 0.0.35-alpha.4
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/global-account/bsmnt.d.ts +2 -0
- package/dist/cjs/global-account/bsmnt.js +42 -1
- package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.js +55 -0
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +108 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +9 -1
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +16 -2
- package/dist/cjs/global-account/react/hooks/useAccountWallet.js +3 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -0
- package/dist/cjs/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/cjs/global-account/react/hooks/useRPMToken.js +11 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +7 -1
- package/dist/cjs/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/dist/cjs/global-account/react/utils/updateAvatar.js +54 -0
- package/dist/esm/global-account/bsmnt.d.ts +2 -0
- package/dist/esm/global-account/bsmnt.js +39 -0
- package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.js +52 -0
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +102 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +9 -1
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +17 -3
- package/dist/esm/global-account/react/hooks/useAccountWallet.js +3 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -0
- package/dist/esm/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/esm/global-account/react/hooks/useRPMToken.js +8 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +7 -1
- package/dist/esm/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/dist/esm/global-account/react/utils/updateAvatar.js +18 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/global-account/bsmnt.d.ts +2 -0
- package/dist/types/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
- package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
- package/dist/types/global-account/react/hooks/useProfile.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useRPMToken.d.ts +7 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +7 -1
- package/dist/types/global-account/react/utils/updateAvatar.d.ts +4 -0
- package/package.json +6 -5
- package/src/global-account/bsmnt.ts +47 -0
- package/src/global-account/react/components/AvatarCreator/AvatarCreator.tsx +90 -0
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +233 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +27 -2
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +25 -5
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +0 -1
- package/src/global-account/react/hooks/useAccountWallet.tsx +3 -2
- package/src/global-account/react/hooks/useAuthentication.ts +9 -0
- package/src/global-account/react/hooks/useProfile.ts +1 -1
- package/src/global-account/react/hooks/useRPMToken.ts +17 -0
- package/src/global-account/react/stores/useModalStore.ts +9 -1
- package/src/global-account/react/utils/updateAvatar.ts +21 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import app from "../../../../global-account/app.js";
|
|
4
|
+
import { Button, useB3, useProfile } from "../../../../global-account/react/index.js";
|
|
5
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
6
|
+
import { debugB3React } from "../../../../shared/utils/debug.js";
|
|
7
|
+
import { client } from "../../../../shared/utils/thirdweb.js";
|
|
8
|
+
import { Check, Loader2, Upload, X } from "lucide-react";
|
|
9
|
+
import { useRef, useState } from "react";
|
|
10
|
+
import { toast } from "sonner";
|
|
11
|
+
import { useActiveAccount } from "thirdweb/react";
|
|
12
|
+
import { upload } from "thirdweb/storage";
|
|
13
|
+
const debug = debugB3React("AvatarEditor");
|
|
14
|
+
export function AvatarEditor({ onSetAvatar, className }) {
|
|
15
|
+
const [selectedFile, setSelectedFile] = useState(null);
|
|
16
|
+
const [previewUrl, setPreviewUrl] = useState(null);
|
|
17
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
18
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
19
|
+
const fileInputRef = useRef(null);
|
|
20
|
+
const { setUser } = useB3();
|
|
21
|
+
const account = useActiveAccount();
|
|
22
|
+
const { data: profile, refetch: refreshProfile } = useProfile({
|
|
23
|
+
address: account?.address,
|
|
24
|
+
fresh: true,
|
|
25
|
+
});
|
|
26
|
+
// Thirdweb upload function
|
|
27
|
+
const hasAvatar = profile?.avatar;
|
|
28
|
+
const handleFileSelect = (event) => {
|
|
29
|
+
const file = event.target.files?.[0];
|
|
30
|
+
if (file) {
|
|
31
|
+
// Validate file type
|
|
32
|
+
if (!file.type.startsWith("image/")) {
|
|
33
|
+
toast.error("Please select an image file");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Validate file size (max 5MB)
|
|
37
|
+
if (file.size > 5 * 1024 * 1024) {
|
|
38
|
+
toast.error("File size must be less than 5MB");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setSelectedFile(file);
|
|
42
|
+
// Create preview URL
|
|
43
|
+
const url = URL.createObjectURL(file);
|
|
44
|
+
setPreviewUrl(url);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const handleRemoveFile = () => {
|
|
48
|
+
setSelectedFile(null);
|
|
49
|
+
if (previewUrl) {
|
|
50
|
+
URL.revokeObjectURL(previewUrl);
|
|
51
|
+
setPreviewUrl(null);
|
|
52
|
+
}
|
|
53
|
+
if (fileInputRef.current) {
|
|
54
|
+
fileInputRef.current.value = "";
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleUpload = async () => {
|
|
58
|
+
if (!selectedFile) {
|
|
59
|
+
toast.error("Please select an image first");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setIsUploading(true);
|
|
63
|
+
try {
|
|
64
|
+
debug("Starting upload to IPFS", selectedFile);
|
|
65
|
+
// Upload to IPFS using Thirdweb
|
|
66
|
+
const ipfsUrl = await upload({
|
|
67
|
+
client,
|
|
68
|
+
files: [selectedFile],
|
|
69
|
+
});
|
|
70
|
+
debug("Upload successful", ipfsUrl);
|
|
71
|
+
// Save avatar URL using profiles service
|
|
72
|
+
setIsSaving(true);
|
|
73
|
+
const user = await app.service("users").setAvatar({
|
|
74
|
+
avatar: ipfsUrl,
|
|
75
|
+
},
|
|
76
|
+
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
77
|
+
{});
|
|
78
|
+
// update user
|
|
79
|
+
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
80
|
+
setUser(user);
|
|
81
|
+
// Refresh profile to get updated avatar
|
|
82
|
+
await refreshProfile();
|
|
83
|
+
toast.success(hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!");
|
|
84
|
+
onSetAvatar?.();
|
|
85
|
+
// Clean up
|
|
86
|
+
handleRemoveFile();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
debug("Error uploading avatar:", error);
|
|
90
|
+
toast.error("Failed to upload avatar. Please try again.");
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
setIsUploading(false);
|
|
94
|
+
setIsSaving(false);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const handleFileInputClick = () => {
|
|
98
|
+
fileInputRef.current?.click();
|
|
99
|
+
};
|
|
100
|
+
const isLoading = isUploading || isSaving;
|
|
101
|
+
return (_jsxs("div", { className: cn("flex flex-col items-center justify-center space-y-6 p-8", className), children: [_jsxs("div", { className: "space-y-2 text-center", children: [_jsx("h2", { className: "font-neue-montreal-semibold text-b3-grey text-2xl", children: hasAvatar ? "Update Your Avatar" : "Set Your Avatar" }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium", children: "Upload an image to personalize your profile" })] }), hasAvatar && !previewUrl && (_jsx("div", { className: "relative", children: _jsx("div", { className: "border-b3-primary-blue h-32 w-32 overflow-hidden rounded-full border-4", children: _jsx("img", { src: profile.avatar, alt: "Current avatar", className: "h-full w-full object-cover" }) }) })), _jsxs("div", { className: "w-full max-w-md", children: [!selectedFile ? (_jsxs("div", { onClick: handleFileInputClick, className: "border-b3-line hover:border-b3-primary-blue hover:bg-b3-primary-wash/20 cursor-pointer rounded-xl border-2 border-dashed p-8 text-center transition-colors", children: [_jsx(Upload, { className: "text-b3-grey mx-auto mb-4 h-12 w-12" }), _jsx("p", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "Click to select an image" }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "PNG, JPG, or GIF up to 5MB" })] })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "border-b3-primary-blue mx-auto h-32 w-32 overflow-hidden rounded-full border-4", children: previewUrl ? (_jsx("img", { src: previewUrl, alt: "Preview", className: "h-full w-full object-cover" })) : (_jsx("div", { className: "bg-b3-primary-wash flex h-full w-full items-center justify-center rounded-full", children: _jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "No file selected" }) })) }), _jsx("button", { onClick: handleRemoveFile, className: "bg-b3-negative absolute -right-2 -top-2 flex h-8 w-8 items-center justify-center rounded-full text-white transition-colors hover:bg-red-600", disabled: isLoading, children: _jsx(X, { size: 16 }) })] }), _jsxs("div", { className: "space-y-1 text-center", children: [_jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: selectedFile.name }), _jsxs("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-xs", children: [(selectedFile.size / 1024 / 1024).toFixed(2), " MB"] })] })] })), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden" })] }), _jsxs("div", { className: "flex w-full max-w-md gap-3", children: [selectedFile && (_jsx(Button, { onClick: handleUpload, disabled: isLoading, className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white", children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isUploading ? "Uploading..." : "Saving..."] })) : (_jsxs(_Fragment, { children: [_jsx(Check, { className: "mr-2 h-4 w-4" }), hasAvatar ? "Update Avatar" : "Set Avatar"] })) })), _jsxs(Button, { variant: "outline", onClick: handleFileInputClick, disabled: isLoading, className: "flex-1", children: [_jsx(Upload, { className: "mr-2 h-4 w-4" }), selectedFile ? "Change Image" : "Select Image"] })] }), _jsx("div", { className: "text-b3-foreground-muted font-neue-montreal-medium max-w-md text-center text-xs", children: _jsx("p", { children: "Your avatar will be uploaded to IPFS and stored securely. Make sure you have the rights to use this image." }) })] }));
|
|
102
|
+
}
|
|
@@ -4,6 +4,7 @@ import { AnySpendDepositHype } from "../../../anyspend/react/components/Anyspend
|
|
|
4
4
|
import { useIsMobile, useModalStore } from "../../../global-account/react/index.js";
|
|
5
5
|
import { cn } from "../../../shared/utils/cn.js";
|
|
6
6
|
import { debugB3React } from "../../../shared/utils/debug.js";
|
|
7
|
+
import { AvatarEditor } from "./AvatarEditor/AvatarEditor.js";
|
|
7
8
|
import { useB3 } from "./B3Provider/useB3.js";
|
|
8
9
|
import { LinkAccount } from "./LinkAccount/LinkAccount.js";
|
|
9
10
|
import { ManageAccount } from "./ManageAccount/ManageAccount.js";
|
|
@@ -29,6 +30,7 @@ export function B3DynamicModal() {
|
|
|
29
30
|
"anySpendSignatureMint",
|
|
30
31
|
"anySpendBondKit",
|
|
31
32
|
"linkAccount",
|
|
33
|
+
"avatarEditor",
|
|
32
34
|
];
|
|
33
35
|
const freestyleTypes = [
|
|
34
36
|
"anySpendNft",
|
|
@@ -80,6 +82,8 @@ export function B3DynamicModal() {
|
|
|
80
82
|
return _jsx(LinkAccount, { ...contentType });
|
|
81
83
|
case "anySpendDepositHype":
|
|
82
84
|
return _jsx(AnySpendDepositHype, { ...contentType, mode: "modal" });
|
|
85
|
+
case "avatarEditor":
|
|
86
|
+
return _jsx(AvatarEditor, { onSetAvatar: contentType.onSuccess });
|
|
83
87
|
// Add other modal types here
|
|
84
88
|
default:
|
|
85
89
|
return null;
|
|
@@ -89,5 +93,9 @@ export function B3DynamicModal() {
|
|
|
89
93
|
const ModalContent = isMobile ? DrawerContent : DialogContent;
|
|
90
94
|
const ModalTitle = isMobile ? DrawerTitle : DialogTitle;
|
|
91
95
|
const ModalDescription = isMobile ? DrawerDescription : DialogDescription;
|
|
92
|
-
return (
|
|
96
|
+
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",
|
|
97
|
+
// Remove default width classes for avatar editor
|
|
98
|
+
contentType?.type === "avatarEditor"
|
|
99
|
+
? "!w-[90vw] !max-w-none" // Use !important to override default styles
|
|
100
|
+
: "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" }) }) }))] }));
|
|
93
101
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, CopyToClipboard, useAuthentication, useB3BalanceFromAddresses, useModalStore, useNativeBalance, useProfile, } from "../../../../global-account/react/index.js";
|
|
2
|
+
import { Button, CopyToClipboard, useAuthentication, useB3, useB3BalanceFromAddresses, useModalStore, useNativeBalance, useProfile, } from "../../../../global-account/react/index.js";
|
|
3
3
|
import { BankIcon } from "../../../../global-account/react/components/icons/BankIcon.js";
|
|
4
4
|
import { SignOutIcon } from "../../../../global-account/react/components/icons/SignOutIcon.js";
|
|
5
5
|
import { SwapIcon } from "../../../../global-account/react/components/icons/SwapIcon.js";
|
|
6
6
|
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
7
|
+
import { getIpfsUrl } from "../../../../shared/utils/ipfs.js";
|
|
7
8
|
import { Loader2, Pencil } from "lucide-react";
|
|
8
9
|
import { useEffect, useRef, useState } from "react";
|
|
9
10
|
import { useActiveAccount } from "thirdweb/react";
|
|
@@ -23,11 +24,24 @@ export function BalanceContent({ onLogout, partnerId, showDeposit = true, showSw
|
|
|
23
24
|
address: eoaAddress || account?.address,
|
|
24
25
|
fresh: true,
|
|
25
26
|
});
|
|
26
|
-
const {
|
|
27
|
+
const { user } = useB3();
|
|
28
|
+
const { setB3ModalOpen, setB3ModalContentType, navigateBack } = useModalStore();
|
|
27
29
|
const { logout } = useAuthentication(partnerId);
|
|
28
30
|
const [logoutLoading, setLogoutLoading] = useState(false);
|
|
29
31
|
const [openAccordions, setOpenAccordions] = useState([]);
|
|
30
32
|
const hasExpandedRef = useRef(false);
|
|
33
|
+
const avatarUrl = user?.avatar ? getIpfsUrl(user?.avatar) : profile?.avatar;
|
|
34
|
+
const handleEditAvatar = () => {
|
|
35
|
+
setB3ModalOpen(true);
|
|
36
|
+
setB3ModalContentType({
|
|
37
|
+
type: "avatarEditor",
|
|
38
|
+
showBackButton: true,
|
|
39
|
+
onSuccess: () => {
|
|
40
|
+
// navigate back on success
|
|
41
|
+
navigateBack();
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
};
|
|
31
45
|
console.log("eoaAddress", eoaAddress);
|
|
32
46
|
console.log("account?.address", account?.address);
|
|
33
47
|
// Balance data fetching
|
|
@@ -71,7 +85,7 @@ export function BalanceContent({ onLogout, partnerId, showDeposit = true, showSw
|
|
|
71
85
|
setB3ModalOpen(false);
|
|
72
86
|
setLogoutLoading(false);
|
|
73
87
|
};
|
|
74
|
-
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: [
|
|
88
|
+
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: handleEditAvatar, 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: 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: () => {
|
|
75
89
|
setB3ModalOpen(true);
|
|
76
90
|
setB3ModalContentType({
|
|
77
91
|
type: "anySpend",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useB3, useProfile } from "../../../global-account/react/index.js";
|
|
2
2
|
import { ecosystemWalletId } from "../../../shared/constants/index.js";
|
|
3
3
|
import { debugB3React } from "../../../shared/utils/debug.js";
|
|
4
|
+
import { getIpfsUrl } from "../../../shared/utils/ipfs.js";
|
|
4
5
|
import { useEffect, useMemo, useState } from "react";
|
|
5
6
|
import { getLastAuthProvider, useActiveWallet, useConnectedWallets, useWalletImage } from "thirdweb/react";
|
|
6
7
|
import { socialIcons } from "thirdweb/wallets/in-app";
|
|
@@ -17,7 +18,7 @@ function useLastAuthProvider() {
|
|
|
17
18
|
return lastAuthProvider;
|
|
18
19
|
}
|
|
19
20
|
export function useAccountWallet() {
|
|
20
|
-
const { account } = useB3();
|
|
21
|
+
const { account, user } = useB3();
|
|
21
22
|
const activeWallet = useActiveWallet();
|
|
22
23
|
const connectedWallets = useConnectedWallets();
|
|
23
24
|
const connectedSmartWallet = connectedWallets.find(wallet => wallet.id === ecosystemWalletId);
|
|
@@ -38,7 +39,7 @@ export function useAccountWallet() {
|
|
|
38
39
|
: "https://gradvatar.com/0x0000000000000000000000000000000000000000"; // show smart wallet of eoa wallet is gradvatar
|
|
39
40
|
const { data: profileData } = useProfile({ address: account?.address });
|
|
40
41
|
const ensName = profileData?.displayName?.replace(/\.b3\.fun/g, "");
|
|
41
|
-
const avatarUrl = profileData?.avatar;
|
|
42
|
+
const avatarUrl = user?.avatar ? getIpfsUrl(user?.avatar) : profileData?.avatar;
|
|
42
43
|
const res = useMemo(() => ({
|
|
43
44
|
wallet: {
|
|
44
45
|
...account,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import app from "../../../global-account/app.js";
|
|
2
|
+
import { authenticateWithB3JWT } from "../../../global-account/bsmnt.js";
|
|
2
3
|
import { useAuthStore, useB3 } from "../../../global-account/react/index.js";
|
|
3
4
|
import { ecosystemWalletId } from "../../../shared/constants/index.js";
|
|
4
5
|
import { b3MainnetThirdWeb } from "../../../shared/constants/chains/supported.js";
|
|
@@ -60,6 +61,9 @@ export function useAuthentication(partnerId, loginWithSiwe) {
|
|
|
60
61
|
setIsAuthenticated(true);
|
|
61
62
|
setIsAuthenticatingV2(false);
|
|
62
63
|
debug("Re-authenticated successfully", { userAuth });
|
|
64
|
+
// Authenticate on BSMNT with B3 JWT
|
|
65
|
+
const b3Jwt = await authenticateWithB3JWT(userAuth.accessToken);
|
|
66
|
+
console.log("@@b3Jwt", b3Jwt);
|
|
63
67
|
}
|
|
64
68
|
catch (error) {
|
|
65
69
|
// If re-authentication fails, try fresh authentication
|
|
@@ -69,6 +73,9 @@ export function useAuthentication(partnerId, loginWithSiwe) {
|
|
|
69
73
|
setIsAuthenticated(true);
|
|
70
74
|
setIsAuthenticatingV2(false);
|
|
71
75
|
debug("Fresh authentication successful", { userAuth });
|
|
76
|
+
// Authenticate on BSMNT with B3 JWT
|
|
77
|
+
const b3Jwt = await authenticateWithB3JWT(userAuth.accessToken);
|
|
78
|
+
console.log("@@b3Jwt", b3Jwt);
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
catch (error) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useQueryBSMNT } from "../../../global-account/react/hooks/useQueryBSMNT.js";
|
|
3
|
+
export function useRPMToken() {
|
|
4
|
+
const { data, runQuery: refetch, isLoading, error: isError, } = useQueryBSMNT("profiles", "getReadyPlayerMeToken", undefined, true);
|
|
5
|
+
const token = data?.token || "";
|
|
6
|
+
const accountId = data?.accountId || "";
|
|
7
|
+
return { token, accountId, refetch, isLoading, isError };
|
|
8
|
+
}
|
|
@@ -291,10 +291,16 @@ export interface AnySpendDepositHypeProps extends BaseModalProps {
|
|
|
291
291
|
/** Callback function called when the deposit is successful */
|
|
292
292
|
onSuccess?: (amount?: string) => void;
|
|
293
293
|
}
|
|
294
|
+
export interface AvatarEditorModalProps extends BaseModalProps {
|
|
295
|
+
/** Modal type identifier */
|
|
296
|
+
type: "avatarEditor";
|
|
297
|
+
/** Callback function called when avatar is successfully set */
|
|
298
|
+
onSuccess?: () => void;
|
|
299
|
+
}
|
|
294
300
|
/**
|
|
295
301
|
* Union type of all possible modal content types
|
|
296
302
|
*/
|
|
297
|
-
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps;
|
|
303
|
+
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps;
|
|
298
304
|
/**
|
|
299
305
|
* State interface for the modal store
|
|
300
306
|
*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import app, { extractAvatarIdFromUrl } from "../../../global-account/bsmnt.js";
|
|
2
|
+
import { debugB3React } from "../../../shared/utils/debug.js";
|
|
3
|
+
const debug = debugB3React("updateAvatar");
|
|
4
|
+
export async function updateAvatar(avatar) {
|
|
5
|
+
try {
|
|
6
|
+
// Extract avatar ID from URL
|
|
7
|
+
const avatarID = extractAvatarIdFromUrl(avatar);
|
|
8
|
+
if (!avatarID) {
|
|
9
|
+
throw new Error("Invalid avatar URL");
|
|
10
|
+
}
|
|
11
|
+
// Set the avatar in the profiles service
|
|
12
|
+
return await app.service("profiles").setAvatar({ avatarUrl: String(avatar), avatarID: String(avatarID) }, {});
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
debug("Failed to update avatar:", error);
|
|
16
|
+
throw error; // Re-throw to handle in component
|
|
17
|
+
}
|
|
18
|
+
}
|