@b3dotfun/sdk 0.0.35-alpha.3 → 0.0.35-alpha.5

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.
Files changed (89) hide show
  1. package/dist/cjs/global-account/bsmnt.d.ts +2 -0
  2. package/dist/cjs/global-account/bsmnt.js +42 -1
  3. package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  4. package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.js +55 -0
  5. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  6. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +108 -0
  7. package/dist/cjs/global-account/react/components/B3DynamicModal.js +9 -1
  8. package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  9. package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +21 -11
  10. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +16 -2
  11. package/dist/cjs/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  12. package/dist/cjs/global-account/react/components/icons/AppleIcon.js +8 -0
  13. package/dist/cjs/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  14. package/dist/cjs/global-account/react/components/icons/DiscordIcon.js +8 -0
  15. package/dist/cjs/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  16. package/dist/cjs/global-account/react/components/icons/FarcasterIcon.js +8 -0
  17. package/dist/cjs/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  18. package/dist/cjs/global-account/react/components/icons/GoogleIcon.js +8 -0
  19. package/dist/cjs/global-account/react/components/icons/XIcon.d.ts +9 -0
  20. package/dist/cjs/global-account/react/components/icons/XIcon.js +8 -0
  21. package/dist/cjs/global-account/react/hooks/useAccountWallet.js +3 -2
  22. package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -0
  23. package/dist/cjs/global-account/react/hooks/useProfile.d.ts +1 -1
  24. package/dist/cjs/global-account/react/hooks/useRPMToken.d.ts +7 -0
  25. package/dist/cjs/global-account/react/hooks/useRPMToken.js +11 -0
  26. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +7 -1
  27. package/dist/cjs/global-account/react/utils/updateAvatar.d.ts +4 -0
  28. package/dist/cjs/global-account/react/utils/updateAvatar.js +54 -0
  29. package/dist/esm/global-account/bsmnt.d.ts +2 -0
  30. package/dist/esm/global-account/bsmnt.js +39 -0
  31. package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  32. package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.js +52 -0
  33. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  34. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +102 -0
  35. package/dist/esm/global-account/react/components/B3DynamicModal.js +9 -1
  36. package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  37. package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +22 -12
  38. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +17 -3
  39. package/dist/esm/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  40. package/dist/esm/global-account/react/components/icons/AppleIcon.js +5 -0
  41. package/dist/esm/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  42. package/dist/esm/global-account/react/components/icons/DiscordIcon.js +5 -0
  43. package/dist/esm/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  44. package/dist/esm/global-account/react/components/icons/FarcasterIcon.js +5 -0
  45. package/dist/esm/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  46. package/dist/esm/global-account/react/components/icons/GoogleIcon.js +5 -0
  47. package/dist/esm/global-account/react/components/icons/XIcon.d.ts +9 -0
  48. package/dist/esm/global-account/react/components/icons/XIcon.js +5 -0
  49. package/dist/esm/global-account/react/hooks/useAccountWallet.js +3 -2
  50. package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -0
  51. package/dist/esm/global-account/react/hooks/useProfile.d.ts +1 -1
  52. package/dist/esm/global-account/react/hooks/useRPMToken.d.ts +7 -0
  53. package/dist/esm/global-account/react/hooks/useRPMToken.js +8 -0
  54. package/dist/esm/global-account/react/stores/useModalStore.d.ts +7 -1
  55. package/dist/esm/global-account/react/utils/updateAvatar.d.ts +4 -0
  56. package/dist/esm/global-account/react/utils/updateAvatar.js +18 -0
  57. package/dist/styles/index.css +1 -1
  58. package/dist/types/global-account/bsmnt.d.ts +2 -0
  59. package/dist/types/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  60. package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  61. package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  62. package/dist/types/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  63. package/dist/types/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  64. package/dist/types/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  65. package/dist/types/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  66. package/dist/types/global-account/react/components/icons/XIcon.d.ts +9 -0
  67. package/dist/types/global-account/react/hooks/useProfile.d.ts +1 -1
  68. package/dist/types/global-account/react/hooks/useRPMToken.d.ts +7 -0
  69. package/dist/types/global-account/react/stores/useModalStore.d.ts +7 -1
  70. package/dist/types/global-account/react/utils/updateAvatar.d.ts +4 -0
  71. package/package.json +6 -5
  72. package/src/global-account/bsmnt.ts +47 -0
  73. package/src/global-account/react/components/AvatarCreator/AvatarCreator.tsx +90 -0
  74. package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +233 -0
  75. package/src/global-account/react/components/B3DynamicModal.tsx +27 -2
  76. package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +40 -18
  77. package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +25 -5
  78. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +0 -1
  79. package/src/global-account/react/components/icons/AppleIcon.tsx +33 -0
  80. package/src/global-account/react/components/icons/DiscordIcon.tsx +32 -0
  81. package/src/global-account/react/components/icons/FarcasterIcon.tsx +37 -0
  82. package/src/global-account/react/components/icons/GoogleIcon.tsx +40 -0
  83. package/src/global-account/react/components/icons/XIcon.tsx +28 -0
  84. package/src/global-account/react/hooks/useAccountWallet.tsx +3 -2
  85. package/src/global-account/react/hooks/useAuthentication.ts +9 -0
  86. package/src/global-account/react/hooks/useProfile.ts +1 -1
  87. package/src/global-account/react/hooks/useRPMToken.ts +17 -0
  88. package/src/global-account/react/stores/useModalStore.ts +9 -1
  89. package/src/global-account/react/utils/updateAvatar.ts +21 -0
@@ -1,4 +1,6 @@
1
1
  declare const app: import("@b3dotfun/basement-api").ClientApplication;
2
2
  export declare const authenticate: (accessToken: string, identityToken: string, params?: Record<string, any>) => Promise<import("@feathersjs/authentication").AuthenticationResult | null>;
3
3
  export declare const resetSocket: () => void;
4
+ export declare function extractAvatarIdFromUrl(url: string): string | null;
5
+ export declare const authenticateWithB3JWT: (fullToken: string, params?: Record<string, any>) => Promise<import("@feathersjs/authentication").AuthenticationResult | null>;
4
6
  export default app;
@@ -3,12 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.resetSocket = exports.authenticate = void 0;
6
+ exports.authenticateWithB3JWT = exports.resetSocket = exports.authenticate = void 0;
7
+ exports.extractAvatarIdFromUrl = extractAvatarIdFromUrl;
7
8
  const basement_api_1 = require("@b3dotfun/basement-api");
9
+ const debug_1 = require("../shared/utils/debug");
8
10
  const authentication_client_1 = require("@feathersjs/authentication-client");
9
11
  const socketio_client_1 = __importDefault(require("@feathersjs/socketio-client"));
10
12
  const js_cookie_1 = __importDefault(require("js-cookie"));
11
13
  const socket_io_client_1 = __importDefault(require("socket.io-client"));
14
+ const debug = (0, debug_1.debugB3React)("bsmnt");
12
15
  // Also use b3 auth token since we are using b3-jwt strategy
13
16
  const BSMNT_AUTH_COOKIE_NAME = "b3-auth";
14
17
  const BSMNT_API_URL = process.env.EXPO_PUBLIC_BSMNT_API ||
@@ -66,4 +69,42 @@ const resetSocket = () => {
66
69
  // reset the socket connection
67
70
  };
68
71
  exports.resetSocket = resetSocket;
72
+ function extractAvatarIdFromUrl(url) {
73
+ const regex = /https:\/\/models\.readyplayer\.me\/([a-f0-9]{24})\.[a-zA-Z0-9]+/;
74
+ const match = url.match(regex);
75
+ return match ? match[1] : null;
76
+ }
77
+ const authenticateWithB3JWT = async (fullToken, params) => {
78
+ // Do not authenticate if there is no token
79
+ if (!fullToken) {
80
+ console.log("No token found, not authenticating");
81
+ return null;
82
+ }
83
+ debug("Authenticating with token:12", fullToken);
84
+ try {
85
+ const response = await app.authenticate({
86
+ strategy: "b3-jwt",
87
+ accessToken: fullToken,
88
+ }, {
89
+ query: params || {},
90
+ });
91
+ debug("Authenticated", response);
92
+ // Store streamToken if it exists in the response
93
+ if (response?.streamToken) {
94
+ js_cookie_1.default.set("stream-token", response.streamToken, {
95
+ expires: new Date(response.authExpires),
96
+ secure: process.env.NODE_ENV === "production",
97
+ sameSite: "strict",
98
+ });
99
+ debug("Stream token stored in cookies");
100
+ }
101
+ return response;
102
+ }
103
+ catch (error) {
104
+ debug(`Authentication error:5`, error);
105
+ debug("Authentication JWT", fullToken);
106
+ return null;
107
+ }
108
+ };
109
+ exports.authenticateWithB3JWT = authenticateWithB3JWT;
69
110
  exports.default = app;
@@ -0,0 +1,6 @@
1
+ interface AvatarCreatorProps {
2
+ onSetAvatar?: () => void;
3
+ className?: string;
4
+ }
5
+ export declare function AvatarCreator({ onSetAvatar, className }: AvatarCreatorProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AvatarCreator = AvatarCreator;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("../../../../global-account/react");
7
+ const useRPMToken_1 = require("../../../../global-account/react/hooks/useRPMToken");
8
+ const updateAvatar_1 = require("../../../../global-account/react/utils/updateAvatar");
9
+ const cn_1 = require("../../../../shared/utils/cn");
10
+ const debug_1 = require("../../../../shared/utils/debug");
11
+ const react_avatar_creator_1 = require("@readyplayerme/react-avatar-creator");
12
+ const react_2 = require("react");
13
+ const sonner_1 = require("sonner");
14
+ const react_3 = require("thirdweb/react");
15
+ const debug = (0, debug_1.debugB3React)("AvatarCreator");
16
+ const config = {
17
+ clearCache: true,
18
+ bodyType: "fullbody",
19
+ quickStart: true,
20
+ language: "en",
21
+ };
22
+ function AvatarCreator({ onSetAvatar, className }) {
23
+ const { token, refetch: refetchRPMToken } = (0, useRPMToken_1.useRPMToken)();
24
+ const [loading, setIsLoading] = (0, react_2.useState)(false);
25
+ const account = (0, react_3.useActiveAccount)();
26
+ const { data: profile, refetch: refreshProfile } = (0, react_1.useProfile)({
27
+ address: account?.address,
28
+ fresh: true,
29
+ });
30
+ const hasAvatar = profile?.avatar;
31
+ const handleOnAvatarExported = async (event) => {
32
+ setIsLoading(true);
33
+ debug("@@AvatarExportedEvent", event);
34
+ try {
35
+ const avatarUpload = await (0, updateAvatar_1.updateAvatar)(event.data.url);
36
+ debug("@@avatarUpload", avatarUpload);
37
+ await refreshProfile();
38
+ sonner_1.toast.success(hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!");
39
+ onSetAvatar?.();
40
+ await refetchRPMToken(undefined);
41
+ }
42
+ catch (e) {
43
+ debug("@@error:AvatarCreator", e);
44
+ sonner_1.toast.error("Failed to update avatar. Please try again.");
45
+ }
46
+ setIsLoading(false);
47
+ };
48
+ if (loading) {
49
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-[80vh] w-full flex-col items-center justify-center gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted-foreground text-sm font-medium", children: "Saving your avatar" })] }));
50
+ }
51
+ if (!token) {
52
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-[80vh] w-full flex-col items-center justify-center gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" }), (0, jsx_runtime_1.jsx)("p", { className: "text-muted-foreground text-sm font-medium", children: "Loading avatar creator" })] }));
53
+ }
54
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("h-[calc(90vh-2px)] w-full", className), children: (0, jsx_runtime_1.jsx)(react_avatar_creator_1.AvatarCreator, { className: "h-full w-full", subdomain: "b3", config: { ...config, token }, onAvatarExported: handleOnAvatarExported }) }));
55
+ }
@@ -0,0 +1,6 @@
1
+ interface AvatarEditorProps {
2
+ onSetAvatar?: () => void;
3
+ className?: string;
4
+ }
5
+ export declare function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ "use client";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.AvatarEditor = AvatarEditor;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const app_1 = __importDefault(require("../../../../global-account/app"));
10
+ const react_1 = require("../../../../global-account/react");
11
+ const cn_1 = require("../../../../shared/utils/cn");
12
+ const debug_1 = require("../../../../shared/utils/debug");
13
+ const thirdweb_1 = require("../../../../shared/utils/thirdweb");
14
+ const lucide_react_1 = require("lucide-react");
15
+ const react_2 = require("react");
16
+ const sonner_1 = require("sonner");
17
+ const react_3 = require("thirdweb/react");
18
+ const storage_1 = require("thirdweb/storage");
19
+ const debug = (0, debug_1.debugB3React)("AvatarEditor");
20
+ function AvatarEditor({ onSetAvatar, className }) {
21
+ const [selectedFile, setSelectedFile] = (0, react_2.useState)(null);
22
+ const [previewUrl, setPreviewUrl] = (0, react_2.useState)(null);
23
+ const [isUploading, setIsUploading] = (0, react_2.useState)(false);
24
+ const [isSaving, setIsSaving] = (0, react_2.useState)(false);
25
+ const fileInputRef = (0, react_2.useRef)(null);
26
+ const { setUser } = (0, react_1.useB3)();
27
+ const account = (0, react_3.useActiveAccount)();
28
+ const { data: profile, refetch: refreshProfile } = (0, react_1.useProfile)({
29
+ address: account?.address,
30
+ fresh: true,
31
+ });
32
+ // Thirdweb upload function
33
+ const hasAvatar = profile?.avatar;
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
+ sonner_1.toast.error("Please select an image file");
40
+ return;
41
+ }
42
+ // Validate file size (max 5MB)
43
+ if (file.size > 5 * 1024 * 1024) {
44
+ sonner_1.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 handleUpload = async () => {
64
+ if (!selectedFile) {
65
+ sonner_1.toast.error("Please select an image first");
66
+ return;
67
+ }
68
+ setIsUploading(true);
69
+ try {
70
+ debug("Starting upload to IPFS", selectedFile);
71
+ // Upload to IPFS using Thirdweb
72
+ const ipfsUrl = await (0, storage_1.upload)({
73
+ client: thirdweb_1.client,
74
+ files: [selectedFile],
75
+ });
76
+ debug("Upload successful", ipfsUrl);
77
+ // Save avatar URL using profiles service
78
+ setIsSaving(true);
79
+ const user = await app_1.default.service("users").setAvatar({
80
+ avatar: ipfsUrl,
81
+ },
82
+ // @ts-expect-error - our typed client is expecting context even though it's set elsewhere
83
+ {});
84
+ // update user
85
+ // @ts-expect-error this resolved fine, look into why expect-error needed
86
+ setUser(user);
87
+ // Refresh profile to get updated avatar
88
+ await refreshProfile();
89
+ sonner_1.toast.success(hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!");
90
+ onSetAvatar?.();
91
+ // Clean up
92
+ handleRemoveFile();
93
+ }
94
+ catch (error) {
95
+ debug("Error uploading avatar:", error);
96
+ sonner_1.toast.error("Failed to upload avatar. Please try again.");
97
+ }
98
+ finally {
99
+ setIsUploading(false);
100
+ setIsSaving(false);
101
+ }
102
+ };
103
+ const handleFileInputClick = () => {
104
+ fileInputRef.current?.click();
105
+ };
106
+ const isLoading = isUploading || isSaving;
107
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex flex-col items-center justify-center space-y-6 p-8", className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-2 text-center", children: [(0, jsx_runtime_1.jsx)("h2", { className: "font-neue-montreal-semibold text-b3-grey text-2xl", children: hasAvatar ? "Update Your Avatar" : "Set Your Avatar" }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium", children: "Upload an image to personalize your profile" })] }), hasAvatar && !previewUrl && ((0, jsx_runtime_1.jsx)("div", { className: "relative", children: (0, jsx_runtime_1.jsx)("div", { className: "border-b3-primary-blue h-32 w-32 overflow-hidden rounded-full border-4", children: (0, jsx_runtime_1.jsx)("img", { src: profile.avatar, alt: "Current avatar", className: "h-full w-full object-cover" }) }) })), (0, jsx_runtime_1.jsxs)("div", { className: "w-full max-w-md", children: [!selectedFile ? ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.Upload, { className: "text-b3-grey mx-auto mb-4 h-12 w-12" }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "Click to select an image" }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "PNG, JPG, or GIF up to 5MB" })] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)("div", { className: "border-b3-primary-blue mx-auto h-32 w-32 overflow-hidden rounded-full border-4", children: previewUrl ? ((0, jsx_runtime_1.jsx)("img", { src: previewUrl, alt: "Preview", className: "h-full w-full object-cover" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash flex h-full w-full items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "No file selected" }) })) }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 16 }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-1 text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: selectedFile.name }), (0, jsx_runtime_1.jsxs)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-xs", children: [(selectedFile.size / 1024 / 1024).toFixed(2), " MB"] })] })] })), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full max-w-md gap-3", children: [selectedFile && ((0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleUpload, disabled: isLoading, className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white", children: isLoading ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isUploading ? "Uploading..." : "Saving..."] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "mr-2 h-4 w-4" }), hasAvatar ? "Update Avatar" : "Set Avatar"] })) })), (0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "outline", onClick: handleFileInputClick, disabled: isLoading, className: "flex-1", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Upload, { className: "mr-2 h-4 w-4" }), selectedFile ? "Change Image" : "Select Image"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium max-w-md text-center text-xs", children: (0, jsx_runtime_1.jsx)("p", { children: "Your avatar will be uploaded to IPFS and stored securely. Make sure you have the rights to use this image." }) })] }));
108
+ }
@@ -7,6 +7,7 @@ const AnyspendDepositHype_1 = require("../../../anyspend/react/components/Anyspe
7
7
  const react_2 = require("../../../global-account/react");
8
8
  const cn_1 = require("../../../shared/utils/cn");
9
9
  const debug_1 = require("../../../shared/utils/debug");
10
+ const AvatarEditor_1 = require("./AvatarEditor/AvatarEditor");
10
11
  const useB3_1 = require("./B3Provider/useB3");
11
12
  const LinkAccount_1 = require("./LinkAccount/LinkAccount");
12
13
  const ManageAccount_1 = require("./ManageAccount/ManageAccount");
@@ -32,6 +33,7 @@ function B3DynamicModal() {
32
33
  "anySpendSignatureMint",
33
34
  "anySpendBondKit",
34
35
  "linkAccount",
36
+ "avatarEditor",
35
37
  ];
36
38
  const freestyleTypes = [
37
39
  "anySpendNft",
@@ -83,6 +85,8 @@ function B3DynamicModal() {
83
85
  return (0, jsx_runtime_1.jsx)(LinkAccount_1.LinkAccount, { ...contentType });
84
86
  case "anySpendDepositHype":
85
87
  return (0, jsx_runtime_1.jsx)(AnyspendDepositHype_1.AnySpendDepositHype, { ...contentType, mode: "modal" });
88
+ case "avatarEditor":
89
+ return (0, jsx_runtime_1.jsx)(AvatarEditor_1.AvatarEditor, { onSetAvatar: contentType.onSuccess });
86
90
  // Add other modal types here
87
91
  default:
88
92
  return null;
@@ -92,5 +96,9 @@ function B3DynamicModal() {
92
96
  const ModalContent = isMobile ? drawer_1.DrawerContent : dialog_1.DialogContent;
93
97
  const ModalTitle = isMobile ? drawer_1.DrawerTitle : dialog_1.DialogTitle;
94
98
  const ModalDescription = isMobile ? drawer_1.DrawerDescription : dialog_1.DialogDescription;
95
- return ((0, jsx_runtime_1.jsx)(ModalComponent, { open: isOpen, onOpenChange: setB3ModalOpen, children: (0, jsx_runtime_1.jsxs)(ModalContent, { className: (0, cn_1.cn)(contentClass, "rounded-2xl bg-white shadow-xl dark:bg-gray-900", "border border-gray-200 dark:border-gray-800", "mx-auto w-full max-w-md", "sm:max-w-lg sm:rounded-b-none"), hideCloseButton: hideCloseButton, children: [(0, jsx_runtime_1.jsx)(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), (0, jsx_runtime_1.jsx)(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("no-scrollbar max-h-[90dvh] overflow-auto sm:max-h-[80dvh]"), children: [history.length > 0 && contentType?.showBackButton && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), (0, jsx_runtime_1.jsx)("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium", children: "Back" })] })), renderContent()] })] }) }));
99
+ return ((0, jsx_runtime_1.jsxs)(ModalComponent, { open: isOpen, onOpenChange: setB3ModalOpen, children: [(0, jsx_runtime_1.jsxs)(ModalContent, { className: (0, cn_1.cn)(contentClass, "rounded-2xl bg-white shadow-xl dark:bg-gray-900", "border border-gray-200 dark:border-gray-800",
100
+ // Remove default width classes for avatar editor
101
+ contentType?.type === "avatarEditor"
102
+ ? "!w-[90vw] !max-w-none" // Use !important to override default styles
103
+ : "mx-auto w-full max-w-md sm:max-w-lg"), hideCloseButton: hideCloseButton, children: [(0, jsx_runtime_1.jsx)(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), (0, jsx_runtime_1.jsx)(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("no-scrollbar max-h-[90dvh] overflow-auto sm:max-h-[80dvh]"), children: [history.length > 0 && contentType?.showBackButton && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), (0, jsx_runtime_1.jsx)("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium", children: "Back" })] })), renderContent()] })] }), contentType?.type === "avatarEditor" && ((0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: (0, jsx_runtime_1.jsx)("path", { d: "M18 6L6 18M6 6L18 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }))] }));
96
104
  }
@@ -1,2 +1,4 @@
1
1
  import { LinkAccountModalProps } from "../../stores/useModalStore";
2
- export declare function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, partnerId, }: LinkAccountModalProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, partnerId, className, }: LinkAccountModalProps & {
3
+ className?: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LinkAccount = LinkAccount;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const app_1 = __importDefault(require("../../../../global-account/app"));
8
9
  const constants_1 = require("../../../../shared/constants");
9
10
  const thirdweb_1 = require("../../../../shared/utils/thirdweb");
10
11
  const lucide_react_1 = require("lucide-react");
@@ -15,18 +16,27 @@ const wallets_1 = require("thirdweb/wallets");
15
16
  const useModalStore_1 = require("../../stores/useModalStore");
16
17
  const profileDisplay_1 = require("../../utils/profileDisplay");
17
18
  const useB3_1 = require("../B3Provider/useB3");
19
+ const AppleIcon_1 = require("../icons/AppleIcon");
20
+ const DiscordIcon_1 = require("../icons/DiscordIcon");
21
+ const FarcasterIcon_1 = require("../icons/FarcasterIcon");
22
+ const GoogleIcon_1 = require("../icons/GoogleIcon");
23
+ const XIcon_1 = require("../icons/XIcon");
18
24
  const button_1 = require("../ui/button");
19
- const app_1 = __importDefault(require("../../../../global-account/app"));
20
25
  const AUTH_METHODS = [
21
- { id: "email", label: "Email", enabled: true },
22
- { id: "phone", label: "Phone", enabled: true },
23
- { id: "google", label: "Google", enabled: true },
24
- { id: "x", label: "X (Twitter)", enabled: true },
25
- { id: "discord", label: "Discord", enabled: true },
26
- { id: "apple", label: "Apple", enabled: true },
27
- { id: "farcaster", label: "Farcaster", enabled: true },
26
+ { id: "email", label: "Email", enabled: true, icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { className: "text-b3-primary-blue size-6" }) },
27
+ { id: "phone", label: "Phone", enabled: true, icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Phone, { className: "text-b3-primary-blue size-6" }) },
28
+ { id: "google", label: "Google", enabled: true, icon: (0, jsx_runtime_1.jsx)(GoogleIcon_1.GoogleIcon, { className: "size-6" }) },
29
+ { id: "x", label: "X (Twitter)", enabled: true, icon: (0, jsx_runtime_1.jsx)(XIcon_1.XIcon, { className: "size-6" }) },
30
+ { id: "discord", label: "Discord", enabled: true, icon: (0, jsx_runtime_1.jsx)(DiscordIcon_1.DiscordIcon, { className: "size-6" }) },
31
+ { id: "apple", label: "Apple", enabled: true, icon: (0, jsx_runtime_1.jsx)(AppleIcon_1.AppleIcon, { className: "size-6" }) },
32
+ {
33
+ id: "farcaster",
34
+ label: "Farcaster",
35
+ enabled: true,
36
+ icon: (0, jsx_runtime_1.jsx)(FarcasterIcon_1.FarcasterIcon, { className: "size-6" }),
37
+ },
28
38
  ];
29
- function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, partnerId, }) {
39
+ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, partnerId, className, }) {
30
40
  const { isLinking, linkingMethod, setLinkingState, navigateBack, setB3ModalContentType } = (0, useModalStore_1.useModalStore)();
31
41
  const [selectedMethod, setSelectedMethod] = (0, react_1.useState)(null);
32
42
  const [email, setEmail] = (0, react_1.useState)("");
@@ -245,12 +255,12 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
245
255
  if (!account) {
246
256
  return (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "Please connect your account first" });
247
257
  }
248
- return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6 p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-b3-grey font-neue-montreal-semibold text-2xl", children: "Link New Account" }), selectedMethod && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", className: "text-b3-grey hover:text-b3-grey/80", onClick: handleBack, children: "Backs" }))] }), !selectedMethod ? ((0, jsx_runtime_1.jsxs)("div", { className: "grid gap-3", children: [availableAuthMethods.map(method => ((0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-wash hover:bg-b3-primary-wash/70 text-b3-grey font-neue-montreal-semibold h-16 justify-start px-6 text-lg", onClick: () => {
258
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `b3-link-account space-y-6 p-6 ${className || ""}`, "data-testid": "link-account", children: [(0, jsx_runtime_1.jsxs)("div", { className: "b3-link-account-header flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h2", { className: "b3-link-account-title text-b3-grey font-neue-montreal-semibold text-2xl", children: "Link New Account" }), selectedMethod && ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", className: "text-b3-grey hover:text-b3-grey/80", onClick: handleBack, children: "Backs" }))] }), !selectedMethod ? ((0, jsx_runtime_1.jsxs)("div", { className: "b3-link-account-methods grid gap-3", children: [availableAuthMethods.map(method => ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "outline", 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", "data-method": method.id, onClick: () => {
249
259
  if (method.id === "email" || method.id === "phone") {
250
260
  setSelectedMethod(method.id);
251
261
  }
252
262
  else {
253
263
  handleSocialLink(method.id);
254
264
  }
255
- }, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" }) : method.label }, method.id))), availableAuthMethods.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [selectedMethod === "email" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), (0, jsx_runtime_1.jsx)("input", { type: "email", placeholder: "Enter your email", 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", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), (0, jsx_runtime_1.jsx)("input", { type: "tel", placeholder: "Enter your phone number", 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", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && (0, jsx_runtime_1.jsx)("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Enter verification code", 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", value: otp, onChange: e => setOtp(e.target.value) })] }), (0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleLinkAccount, children: "Link Account" })] })) : ((0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleSendOTP, disabled: (!email && !phone) || (isLinking && linkingMethod === selectedMethod), children: isLinking && linkingMethod === selectedMethod ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" })) : ("Send Verification Code") }))] }))] }));
265
+ }, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-5 w-5 animate-spin" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "b3-link-account-method-content flex items-center gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "b3-link-account-method-icon flex items-center justify-center rounded-full", children: method.icon }), (0, jsx_runtime_1.jsx)("span", { className: "b3-link-account-method-label font-medium", children: method.label })] })) }, method.id))), availableAuthMethods.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "b3-link-account-form space-y-4", children: [selectedMethod === "email" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), (0, jsx_runtime_1.jsx)("input", { type: "email", placeholder: "Enter your email", 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", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), (0, jsx_runtime_1.jsx)("input", { type: "tel", placeholder: "Enter your phone number", 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", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && (0, jsx_runtime_1.jsx)("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Enter verification code", 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", value: otp, onChange: e => setOtp(e.target.value) })] }), (0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleLinkAccount, children: "Link Account" })] })) : ((0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleSendOTP, disabled: (!email && !phone) || (isLinking && linkingMethod === selectedMethod), children: isLinking && linkingMethod === selectedMethod ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" })) : ("Send Verification Code") }))] }))] }));
256
266
  }
@@ -7,6 +7,7 @@ const BankIcon_1 = require("../../../../global-account/react/components/icons/Ba
7
7
  const SignOutIcon_1 = require("../../../../global-account/react/components/icons/SignOutIcon");
8
8
  const SwapIcon_1 = require("../../../../global-account/react/components/icons/SwapIcon");
9
9
  const utils_1 = require("../../../../shared/utils");
10
+ const ipfs_1 = require("../../../../shared/utils/ipfs");
10
11
  const lucide_react_1 = require("lucide-react");
11
12
  const react_2 = require("react");
12
13
  const react_3 = require("thirdweb/react");
@@ -26,11 +27,24 @@ function BalanceContent({ onLogout, partnerId, showDeposit = true, showSwap = tr
26
27
  address: eoaAddress || account?.address,
27
28
  fresh: true,
28
29
  });
29
- const { setB3ModalOpen, setB3ModalContentType } = (0, react_1.useModalStore)();
30
+ const { user } = (0, react_1.useB3)();
31
+ const { setB3ModalOpen, setB3ModalContentType, navigateBack } = (0, react_1.useModalStore)();
30
32
  const { logout } = (0, react_1.useAuthentication)(partnerId);
31
33
  const [logoutLoading, setLogoutLoading] = (0, react_2.useState)(false);
32
34
  const [openAccordions, setOpenAccordions] = (0, react_2.useState)([]);
33
35
  const hasExpandedRef = (0, react_2.useRef)(false);
36
+ const avatarUrl = user?.avatar ? (0, ipfs_1.getIpfsUrl)(user?.avatar) : profile?.avatar;
37
+ const handleEditAvatar = () => {
38
+ setB3ModalOpen(true);
39
+ setB3ModalContentType({
40
+ type: "avatarEditor",
41
+ showBackButton: true,
42
+ onSuccess: () => {
43
+ // navigate back on success
44
+ navigateBack();
45
+ },
46
+ });
47
+ };
34
48
  console.log("eoaAddress", eoaAddress);
35
49
  console.log("account?.address", account?.address);
36
50
  // Balance data fetching
@@ -74,7 +88,7 @@ function BalanceContent({ onLogout, partnerId, showDeposit = true, showSwap = tr
74
88
  setB3ModalOpen(false);
75
89
  setLogoutLoading(false);
76
90
  };
77
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between", children: (0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile-avatar relative", children: [profile?.avatar ? ((0, jsx_runtime_1.jsx)("img", { src: profile?.avatar, alt: "Profile", className: "size-24 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-grey border-b3-background absolute -bottom-1 -right-1 flex size-8 items-center justify-center rounded-full border-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 16, className: "text-b3-background" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile-info", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || (0, utils_1.formatUsername)(profile?.name || "") }), (0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: account?.address || "" })] })] })] }) }), (showDeposit || showSwap) && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [showDeposit && ((0, jsx_runtime_1.jsxs)(react_1.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
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between", children: (0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile-avatar relative", children: [avatarUrl ? ((0, jsx_runtime_1.jsx)("img", { src: avatarUrl, alt: "Profile", className: "size-24 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 16, className: "text-b3-background" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "global-account-profile-info", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || (0, utils_1.formatUsername)(profile?.name || "") }), (0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: account?.address || "" })] })] })] }) }), (showDeposit || showSwap) && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [showDeposit && ((0, jsx_runtime_1.jsxs)(react_1.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: () => {
78
92
  setB3ModalOpen(true);
79
93
  setB3ModalContentType({
80
94
  type: "anySpend",
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface AppleIconProps {
3
+ className?: string;
4
+ size?: number;
5
+ color?: string;
6
+ style?: React.CSSProperties;
7
+ }
8
+ export declare function AppleIcon({ className, size, color, style }: AppleIconProps): import("react/jsx-runtime").JSX.Element;
9
+ export default AppleIcon;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppleIcon = AppleIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function AppleIcon({ className, size = 24, color = "currentColor", style }) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: "0 0 41.5 51", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, children: (0, jsx_runtime_1.jsx)("g", { children: (0, jsx_runtime_1.jsx)("path", { fill: color, d: "M40.2,17.4c-3.4,2.1-5.5,5.7-5.5,9.7c0,4.5,2.7,8.6,6.8,10.3c-0.8,2.6-2,5-3.5,7.2c-2.2,3.1-4.5,6.3-7.9,6.3s-4.4-2-8.4-2\n\t\tc-3.9,0-5.3,2.1-8.5,2.1s-5.4-2.9-7.9-6.5C2,39.5,0.1,33.7,0,27.6c0-9.9,6.4-15.2,12.8-15.2c3.4,0,6.2,2.2,8.3,2.2\n\t\tc2,0,5.2-2.3,9-2.3C34.1,12.2,37.9,14.1,40.2,17.4z M28.3,8.1C30,6.1,30.9,3.6,31,1c0-0.3,0-0.7-0.1-1c-2.9,0.3-5.6,1.7-7.5,3.9\n\t\tc-1.7,1.9-2.7,4.3-2.8,6.9c0,0.3,0,0.6,0.1,0.9c0.2,0,0.5,0.1,0.7,0.1C24.1,11.6,26.6,10.2,28.3,8.1z" }) }) }));
7
+ }
8
+ exports.default = AppleIcon;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface DiscordIconProps {
3
+ className?: string;
4
+ size?: number;
5
+ color?: string;
6
+ style?: React.CSSProperties;
7
+ }
8
+ export declare function DiscordIcon({ className, size, color, style }: DiscordIconProps): import("react/jsx-runtime").JSX.Element;
9
+ export default DiscordIcon;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiscordIcon = DiscordIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function DiscordIcon({ className, size = 24, color = "#5865F2", style }) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: "0 -28.5 256 256", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, preserveAspectRatio: "xMidYMid", children: (0, jsx_runtime_1.jsx)("g", { children: (0, jsx_runtime_1.jsx)("path", { d: "M216.856339,16.5966031 C200.285002,8.84328665 182.566144,3.2084988 164.041564,0 C161.766523,4.11318106 159.108624,9.64549908 157.276099,14.0464379 C137.583995,11.0849896 118.072967,11.0849896 98.7430163,14.0464379 C96.9108417,9.64549908 94.1925838,4.11318106 91.8971895,0 C73.3526068,3.2084988 55.6133949,8.86399117 39.0420583,16.6376612 C5.61752293,67.146514 -3.4433191,116.400813 1.08711069,164.955721 C23.2560196,181.510915 44.7403634,191.567697 65.8621325,198.148576 C71.0772151,190.971126 75.7283628,183.341335 79.7352139,175.300261 C72.104019,172.400575 64.7949724,168.822202 57.8887866,164.667963 C59.7209612,163.310589 61.5131304,161.891452 63.2445898,160.431257 C105.36741,180.133187 151.134928,180.133187 192.754523,160.431257 C194.506336,161.891452 196.298154,163.310589 198.110326,164.667963 C191.183787,168.842556 183.854737,172.420929 176.223542,175.320965 C180.230393,183.341335 184.861538,190.991831 190.096624,198.16893 C211.238746,191.588051 232.743023,181.531619 254.911949,164.955721 C260.227747,108.668201 245.831087,59.8662432 216.856339,16.5966031 Z M85.4738752,135.09489 C72.8290281,135.09489 62.4592217,123.290155 62.4592217,108.914901 C62.4592217,94.5396472 72.607595,82.7145587 85.4738752,82.7145587 C98.3405064,82.7145587 108.709962,94.5189427 108.488529,108.914901 C108.508531,123.290155 98.3405064,135.09489 85.4738752,135.09489 Z M170.525237,135.09489 C157.88039,135.09489 147.510584,123.290155 147.510584,108.914901 C147.510584,94.5396472 157.658606,82.7145587 170.525237,82.7145587 C183.391518,82.7145587 193.761324,94.5189427 193.539891,108.914901 C193.539891,123.290155 183.391518,135.09489 170.525237,135.09489 Z", fill: color, fillRule: "nonzero" }) }) }));
7
+ }
8
+ exports.default = DiscordIcon;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface FarcasterIconProps {
3
+ className?: string;
4
+ size?: number;
5
+ color?: string;
6
+ style?: React.CSSProperties;
7
+ }
8
+ export declare function FarcasterIcon({ className, size, color, style }: FarcasterIconProps): import("react/jsx-runtime").JSX.Element;
9
+ export default FarcasterIcon;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FarcasterIcon = FarcasterIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function FarcasterIcon({ className, size = 24, color = "#855DCD", style }) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { width: size, height: size, viewBox: "0 0 1000 1000", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, children: [(0, jsx_runtime_1.jsx)("rect", { width: "1000", height: "1000", rx: "200", fill: color }), (0, jsx_runtime_1.jsx)("path", { d: "M257.778 155.556H742.222V844.444H671.111V528.889H670.414C662.554 441.677 589.258 373.333 500 373.333C410.742 373.333 337.446 441.677 329.586 528.889H328.889V844.444H257.778V155.556Z", fill: "white" }), (0, jsx_runtime_1.jsx)("path", { d: "M128.889 253.333L157.778 351.111H182.222V746.667C169.949 746.667 160 756.616 160 768.889V795.556H155.556C143.283 795.556 133.333 805.505 133.333 817.778V844.444H382.222V817.778C382.222 805.505 372.273 795.556 360 795.556H355.556V768.889C355.556 756.616 345.606 746.667 333.333 746.667H306.667V253.333H128.889Z", fill: "white" }), (0, jsx_runtime_1.jsx)("path", { d: "M675.556 746.667C663.283 746.667 653.333 756.616 653.333 768.889V795.556H648.889C636.616 795.556 626.667 805.505 626.667 817.778V844.444H875.556V817.778C875.556 805.505 865.606 795.556 853.333 795.556H848.889V768.889C848.889 756.616 838.94 746.667 826.667 746.667V351.111H851.111L880 253.333H702.222V746.667H675.556Z", fill: "white" })] }));
7
+ }
8
+ exports.default = FarcasterIcon;
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export interface GoogleIconProps {
3
+ className?: string;
4
+ size?: number;
5
+ style?: React.CSSProperties;
6
+ }
7
+ export declare function GoogleIcon({ className, size, style }: GoogleIconProps): import("react/jsx-runtime").JSX.Element;
8
+ export default GoogleIcon;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoogleIcon = GoogleIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function GoogleIcon({ className, size = 24, style }) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { width: size, height: size, viewBox: "0 0 48 48", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, children: [(0, jsx_runtime_1.jsx)("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }), (0, jsx_runtime_1.jsx)("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }), (0, jsx_runtime_1.jsx)("path", { fill: "#FBBC05", d: "M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z" }), (0, jsx_runtime_1.jsx)("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" }), (0, jsx_runtime_1.jsx)("path", { fill: "none", d: "M0 0h48v48H0z" })] }));
7
+ }
8
+ exports.default = GoogleIcon;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface XIconProps {
3
+ className?: string;
4
+ size?: number;
5
+ color?: string;
6
+ style?: React.CSSProperties;
7
+ }
8
+ export declare function XIcon({ className, size, color, style }: XIconProps): import("react/jsx-runtime").JSX.Element;
9
+ export default XIcon;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XIcon = XIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function XIcon({ className, size = 24, color = "currentColor", style }) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: "0 0 300 300.251", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, children: (0, jsx_runtime_1.jsx)("path", { d: "M178.57 127.15 290.27 0h-26.46l-97.03 110.38L89.34 0H0l117.13 166.93L0 300.25h26.46l102.4-116.59 81.8 116.59h89.34M36.01 19.54H76.66l187.13 262.13h-40.66", fill: color }) }));
7
+ }
8
+ exports.default = XIcon;
@@ -4,6 +4,7 @@ exports.useAccountWallet = useAccountWallet;
4
4
  const react_1 = require("../../../global-account/react");
5
5
  const constants_1 = require("../../../shared/constants");
6
6
  const debug_1 = require("../../../shared/utils/debug");
7
+ const ipfs_1 = require("../../../shared/utils/ipfs");
7
8
  const react_2 = require("react");
8
9
  const react_3 = require("thirdweb/react");
9
10
  const in_app_1 = require("thirdweb/wallets/in-app");
@@ -20,7 +21,7 @@ function useLastAuthProvider() {
20
21
  return lastAuthProvider;
21
22
  }
22
23
  function useAccountWallet() {
23
- const { account } = (0, react_1.useB3)();
24
+ const { account, user } = (0, react_1.useB3)();
24
25
  const activeWallet = (0, react_3.useActiveWallet)();
25
26
  const connectedWallets = (0, react_3.useConnectedWallets)();
26
27
  const connectedSmartWallet = connectedWallets.find(wallet => wallet.id === constants_1.ecosystemWalletId);
@@ -41,7 +42,7 @@ function useAccountWallet() {
41
42
  : "https://gradvatar.com/0x0000000000000000000000000000000000000000"; // show smart wallet of eoa wallet is gradvatar
42
43
  const { data: profileData } = (0, react_1.useProfile)({ address: account?.address });
43
44
  const ensName = profileData?.displayName?.replace(/\.b3\.fun/g, "");
44
- const avatarUrl = profileData?.avatar;
45
+ const avatarUrl = user?.avatar ? (0, ipfs_1.getIpfsUrl)(user?.avatar) : profileData?.avatar;
45
46
  const res = (0, react_2.useMemo)(() => ({
46
47
  wallet: {
47
48
  ...account,
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.useAuthentication = useAuthentication;
7
7
  const app_1 = __importDefault(require("../../../global-account/app"));
8
+ const bsmnt_1 = require("../../../global-account/bsmnt");
8
9
  const react_1 = require("../../../global-account/react");
9
10
  const constants_1 = require("../../../shared/constants");
10
11
  const supported_1 = require("../../../shared/constants/chains/supported");
@@ -66,6 +67,9 @@ function useAuthentication(partnerId, loginWithSiwe) {
66
67
  setIsAuthenticated(true);
67
68
  setIsAuthenticatingV2(false);
68
69
  debug("Re-authenticated successfully", { userAuth });
70
+ // Authenticate on BSMNT with B3 JWT
71
+ const b3Jwt = await (0, bsmnt_1.authenticateWithB3JWT)(userAuth.accessToken);
72
+ console.log("@@b3Jwt", b3Jwt);
69
73
  }
70
74
  catch (error) {
71
75
  // If re-authentication fails, try fresh authentication
@@ -75,6 +79,9 @@ function useAuthentication(partnerId, loginWithSiwe) {
75
79
  setIsAuthenticated(true);
76
80
  setIsAuthenticatingV2(false);
77
81
  debug("Fresh authentication successful", { userAuth });
82
+ // Authenticate on BSMNT with B3 JWT
83
+ const b3Jwt = await (0, bsmnt_1.authenticateWithB3JWT)(userAuth.accessToken);
84
+ console.log("@@b3Jwt", b3Jwt);
78
85
  }
79
86
  }
80
87
  catch (error) {
@@ -9,7 +9,7 @@ export interface Profile {
9
9
  export interface CombinedProfile {
10
10
  name: string | null;
11
11
  address: string | null;
12
- avatar: string | null;
12
+ avatar: string | undefined;
13
13
  bio: string | null;
14
14
  displayName: string | null;
15
15
  profiles: Profile[];