@b3dotfun/sdk 0.0.65-test.1 → 0.0.65-test.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.
Files changed (105) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +5 -3
  2. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +1 -1
  3. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +1 -1
  4. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +1 -1
  5. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +0 -6
  6. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +5 -3
  7. package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
  8. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
  9. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +1 -0
  10. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +149 -39
  11. package/dist/cjs/global-account/react/components/B3DynamicModal.js +1 -9
  12. package/dist/cjs/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +39 -0
  13. package/dist/cjs/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.js +37 -0
  14. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +4 -3
  15. package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.js +1 -1
  16. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +1 -1
  17. package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +6 -3
  18. package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +1 -1
  19. package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +77 -9
  20. package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.d.ts +2 -1
  21. package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.js +2 -2
  22. package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +3 -1
  23. package/dist/cjs/global-account/react/components/index.d.ts +1 -2
  24. package/dist/cjs/global-account/react/components/index.js +6 -8
  25. package/dist/cjs/global-account/react/components/ui/drawer.js +1 -1
  26. package/dist/cjs/global-account/react/hooks/useAccountWallet.d.ts +1 -0
  27. package/dist/cjs/global-account/react/hooks/useAccountWallet.js +18 -0
  28. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
  29. package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +2 -2
  30. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +1 -7
  31. package/dist/cjs/shared/constants/chains/supported.d.ts +1 -1
  32. package/dist/cjs/shared/utils/ipfs.js +10 -3
  33. package/dist/esm/anyspend/react/components/AnySpend.js +5 -3
  34. package/dist/esm/anyspend/react/components/AnySpendCustom.js +1 -1
  35. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +1 -1
  36. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +1 -1
  37. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +0 -6
  38. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +5 -3
  39. package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
  40. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
  41. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +1 -0
  42. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +151 -41
  43. package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -9
  44. package/dist/esm/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +39 -0
  45. package/dist/esm/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.js +34 -0
  46. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +4 -3
  47. package/dist/esm/global-account/react/components/ManageAccount/HomeActions.js +1 -1
  48. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +1 -1
  49. package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +6 -3
  50. package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +1 -1
  51. package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +74 -9
  52. package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.d.ts +2 -1
  53. package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.js +2 -2
  54. package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +4 -2
  55. package/dist/esm/global-account/react/components/index.d.ts +1 -2
  56. package/dist/esm/global-account/react/components/index.js +3 -4
  57. package/dist/esm/global-account/react/components/ui/drawer.js +1 -1
  58. package/dist/esm/global-account/react/hooks/useAccountWallet.d.ts +1 -0
  59. package/dist/esm/global-account/react/hooks/useAccountWallet.js +17 -0
  60. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
  61. package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +2 -2
  62. package/dist/esm/global-account/react/stores/useModalStore.d.ts +1 -7
  63. package/dist/esm/shared/constants/chains/supported.d.ts +1 -1
  64. package/dist/esm/shared/utils/ipfs.js +10 -3
  65. package/dist/styles/index.css +1 -1
  66. package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +0 -6
  67. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
  68. package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +1 -0
  69. package/dist/types/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +39 -0
  70. package/dist/types/global-account/react/components/ModalHeader/ModalHeader.d.ts +2 -1
  71. package/dist/types/global-account/react/components/index.d.ts +1 -2
  72. package/dist/types/global-account/react/hooks/useAccountWallet.d.ts +1 -0
  73. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
  74. package/dist/types/global-account/react/hooks/useUserQuery.d.ts +2 -2
  75. package/dist/types/global-account/react/stores/useModalStore.d.ts +1 -7
  76. package/dist/types/shared/constants/chains/supported.d.ts +1 -1
  77. package/package.json +2 -1
  78. package/src/anyspend/react/components/AnySpend.tsx +5 -4
  79. package/src/anyspend/react/components/AnySpendCustom.tsx +0 -2
  80. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +0 -2
  81. package/src/anyspend/react/components/AnyspendDepositHype.tsx +0 -2
  82. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +7 -14
  83. package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +1 -1
  84. package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +251 -79
  85. package/src/global-account/react/components/B3DynamicModal.tsx +3 -11
  86. package/src/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.tsx +84 -0
  87. package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +4 -7
  88. package/src/global-account/react/components/ManageAccount/HomeActions.tsx +1 -1
  89. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +2 -2
  90. package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +14 -11
  91. package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +1 -1
  92. package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +129 -23
  93. package/src/global-account/react/components/ModalHeader/ModalHeader.tsx +16 -8
  94. package/src/global-account/react/components/SignInWithB3/SignIn.tsx +11 -7
  95. package/src/global-account/react/components/index.ts +3 -4
  96. package/src/global-account/react/components/ui/drawer.tsx +1 -1
  97. package/src/global-account/react/hooks/useAccountWallet.tsx +26 -0
  98. package/src/global-account/react/stores/useModalStore.ts +1 -9
  99. package/src/shared/utils/ipfs.ts +10 -3
  100. package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +0 -6
  101. package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.js +0 -141
  102. package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +0 -6
  103. package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.js +0 -135
  104. package/dist/types/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +0 -6
  105. package/src/global-account/react/components/ProfileEditor/ProfileEditor.tsx +0 -265
@@ -40,6 +40,6 @@ const SettingsContent = ({ partnerId, onLogout, chain, }) => {
40
40
  }
41
41
  setB3ModalOpen(true);
42
42
  };
43
- return (_jsxs("div", { className: "flex h-[470px] flex-col", children: [_jsx(ModalHeader, { title: "Settings" }), _jsx("div", { className: "p-5", children: _jsx("div", { className: "flex items-center rounded-xl border border-[#e4e4e7] bg-[#f4f4f5] p-4", children: _jsx(SettingsProfileCard, {}) }) }), _jsx("div", { className: "space-y-3 px-5", children: _jsx(SettingsMenuItem, { icon: _jsx(LinkIcon, { className: "text-b3-grey-500" }), title: "Linked Accounts", subtitle: "3 connected accounts", onClick: () => handleNavigate("linkAccount") }) })] }));
43
+ return (_jsxs("div", { className: "flex h-[470px] flex-col", children: [_jsx(ModalHeader, { showBackButton: false, showCloseButton: false, title: "Settings" }), _jsx("div", { className: "p-5", children: _jsx("div", { className: "flex items-center rounded-xl border border-[#e4e4e7] bg-[#f4f4f5] p-4", children: _jsx(SettingsProfileCard, {}) }) }), _jsx("div", { className: "space-y-3 px-5", children: _jsx(SettingsMenuItem, { icon: _jsx(LinkIcon, { className: "text-b3-grey-500" }), title: "Linked Accounts", subtitle: "3 connected accounts", onClick: () => handleNavigate("linkAccount") }) })] }));
44
44
  };
45
45
  export default SettingsContent;
@@ -1,22 +1,40 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import app from "../../../../global-account/app.js";
2
3
  import { useB3, useModalStore, useProfile } from "../../../../global-account/react/index.js";
3
4
  import { formatUsername } from "../../../../shared/utils/index.js";
4
- import { getIpfsUrl } from "../../../../shared/utils/ipfs.js";
5
- import { Pencil } from "lucide-react";
5
+ import { Check, Loader2, Pencil, X } from "lucide-react";
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { toast } from "sonner";
6
8
  import { useActiveAccount } from "thirdweb/react";
7
9
  import { useFirstEOA } from "../../hooks/useFirstEOA.js";
10
+ import { IPFSMediaRenderer } from "../IPFSMediaRenderer/IPFSMediaRenderer.js";
8
11
  const SettingsProfileCard = () => {
9
12
  const account = useActiveAccount();
10
13
  const { address: eoaAddress } = useFirstEOA();
11
- const { data: profile } = useProfile({
14
+ const { data: profile, refetch: refreshProfile } = useProfile({
12
15
  address: eoaAddress || account?.address,
13
16
  fresh: true,
14
17
  });
15
- const { user } = useB3();
18
+ const { user, setUser } = useB3();
16
19
  const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
17
20
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
18
21
  const navigateBack = useModalStore(state => state.navigateBack);
19
- const avatarUrl = user?.avatar ? getIpfsUrl(user?.avatar) : profile?.avatar;
22
+ // State for inline username editing
23
+ const [isEditingUsername, setIsEditingUsername] = useState(false);
24
+ const [editedUsername, setEditedUsername] = useState("");
25
+ const [isSaving, setIsSaving] = useState(false);
26
+ const inputRef = useRef(null);
27
+ // IPFSMediaRenderer will handle IPFS URL conversion and validation
28
+ const avatarSrc = user?.avatar || profile?.avatar;
29
+ // Get current username - prioritize user.username, fallback to profile data
30
+ const currentUsername = user?.username || profile?.displayName || formatUsername(profile?.name || "");
31
+ // Focus input when entering edit mode
32
+ useEffect(() => {
33
+ if (isEditingUsername && inputRef.current) {
34
+ inputRef.current.focus();
35
+ inputRef.current.select();
36
+ }
37
+ }, [isEditingUsername]);
20
38
  const handleEditAvatar = () => {
21
39
  setB3ModalOpen(true);
22
40
  setB3ModalContentType({
@@ -28,9 +46,56 @@ const SettingsProfileCard = () => {
28
46
  });
29
47
  };
30
48
  const handleEditUsername = () => {
31
- // TODO: Implement edit username functionality
32
- console.log("Edit username clicked");
49
+ setEditedUsername(currentUsername || "");
50
+ setIsEditingUsername(true);
33
51
  };
34
- return (_jsxs("div", { className: "flex w-full items-center gap-3", children: [_jsxs("div", { className: "relative shrink-0", children: [avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "Profile", className: "border-black/8 size-14 rounded-full border object-cover" })) : (_jsx("div", { className: "bg-b3-primary-wash border-black/8 size-14 rounded-full border" })), _jsx("button", { onClick: handleEditAvatar, className: "absolute -bottom-0.5 -right-0.5 flex size-[18px] items-center justify-center rounded-full border-[1.5px] border-white bg-[#a0a0ab] transition-colors hover:bg-[#a0a0ab]/80", "aria-label": "Edit avatar", children: _jsx(Pencil, { size: 10, className: "text-white", strokeWidth: 2.5 }) })] }), _jsxs("div", { className: "flex shrink-0 flex-col gap-1", children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx("p", { className: "font-neue-montreal-semibold text-lg leading-none text-[#0B57C2]", children: profile?.displayName || formatUsername(profile?.name || "") }) }), _jsx("button", { onClick: handleEditUsername, className: "flex items-center justify-center gap-1 text-left transition-opacity hover:opacity-80", children: _jsx("p", { className: "font-inter text-sm font-semibold leading-5 text-[#51525C]", children: "Edit Username" }) })] })] }));
52
+ const handleCancelEdit = () => {
53
+ setIsEditingUsername(false);
54
+ setEditedUsername("");
55
+ };
56
+ const handleSaveUsername = async () => {
57
+ if (!editedUsername.trim()) {
58
+ toast.error("Username cannot be empty");
59
+ return;
60
+ }
61
+ if (editedUsername === currentUsername) {
62
+ // No change, just exit edit mode
63
+ handleCancelEdit();
64
+ return;
65
+ }
66
+ setIsSaving(true);
67
+ try {
68
+ const updatedUser = await app.service("users").registerUsername({ username: editedUsername.trim() },
69
+ // @ts-expect-error - our typed client is expecting context even though it's set elsewhere
70
+ {});
71
+ // Update user state - registerUsername returns an array with single user
72
+ setUser(Array.isArray(updatedUser) ? updatedUser[0] : updatedUser);
73
+ // Refresh profile to get updated data
74
+ await refreshProfile();
75
+ toast.success("Username updated successfully!");
76
+ setIsEditingUsername(false);
77
+ setEditedUsername("");
78
+ }
79
+ catch (error) {
80
+ console.error("Error updating username:", error);
81
+ toast.error("Failed to update username. Please try again.");
82
+ }
83
+ finally {
84
+ setIsSaving(false);
85
+ }
86
+ };
87
+ const handleKeyDown = (e) => {
88
+ if (e.key === "Enter") {
89
+ handleSaveUsername();
90
+ }
91
+ else if (e.key === "Escape") {
92
+ handleCancelEdit();
93
+ }
94
+ };
95
+ return (_jsxs("div", { className: "flex w-full items-center gap-3", children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx(IPFSMediaRenderer, { src: avatarSrc, alt: "Profile", className: "border-black/8 size-14 rounded-full border object-cover" }), _jsx("button", { onClick: handleEditAvatar, className: "absolute -bottom-0.5 -right-0.5 flex size-[18px] items-center justify-center rounded-full border-[1.5px] border-white bg-[#a0a0ab] transition-colors hover:bg-[#a0a0ab]/80", "aria-label": "Edit avatar", children: _jsx(Pencil, { size: 10, className: "text-white", strokeWidth: 2.5 }) })] }), _jsx("div", { className: "flex shrink-0 flex-col gap-1", children: isEditingUsername ? (
96
+ /* Edit mode - inline input */
97
+ _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { ref: inputRef, type: "text", value: editedUsername, onChange: e => setEditedUsername(e.target.value), onKeyDown: handleKeyDown, disabled: isSaving, className: "border-b3-line bg-b3-background text-b3-grey placeholder:text-b3-foreground-muted font-neue-montreal-semibold focus:border-b3-primary-blue w-full rounded-md border px-2 py-1 text-lg leading-none transition-colors focus:outline-none disabled:opacity-50", placeholder: "Enter username" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: handleSaveUsername, disabled: isSaving, className: "text-b3-primary-blue hover:text-b3-primary-blue/80 flex items-center justify-center rounded-md p-1 transition-colors disabled:opacity-50", "aria-label": "Save username", children: isSaving ? _jsx(Loader2, { size: 18, className: "animate-spin" }) : _jsx(Check, { size: 18, strokeWidth: 2.5 }) }), _jsx("button", { onClick: handleCancelEdit, disabled: isSaving, className: "text-b3-foreground-muted hover:text-b3-grey flex items-center justify-center rounded-md p-1 transition-colors disabled:opacity-50", "aria-label": "Cancel editing", children: _jsx(X, { size: 18, strokeWidth: 2.5 }) })] })] })) : (
98
+ /* Display mode */
99
+ _jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx("p", { className: "font-neue-montreal-semibold text-lg leading-none text-[#0B57C2]", children: currentUsername }) }), _jsx("button", { onClick: handleEditUsername, className: "flex items-center justify-center gap-1 text-left transition-opacity hover:opacity-80", children: _jsx("p", { className: "font-inter text-sm font-semibold leading-5 text-[#51525C]", children: "Edit Username" }) })] })) })] }));
35
100
  };
36
101
  export default SettingsProfileCard;
@@ -1,4 +1,5 @@
1
- declare const ModalHeader: ({ handleBack, handleClose, title, children, showCloseButton, className, showBackWord, }: {
1
+ declare const ModalHeader: ({ showBackButton, handleBack, handleClose, title, children, showCloseButton, className, showBackWord, }: {
2
+ showBackButton?: boolean;
2
3
  handleBack?: () => void;
3
4
  handleClose?: () => void;
4
5
  title: string;
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../../../../shared/utils/index.js";
3
3
  import { ChevronDown, X } from "lucide-react";
4
4
  import { useModalStore } from "../../stores/index.js";
5
- const ModalHeader = ({ handleBack, handleClose, title, children, showCloseButton = true, className, showBackWord = false, }) => {
5
+ const ModalHeader = ({ showBackButton = true, handleBack, handleClose, title, children, showCloseButton = true, className, showBackWord = false, }) => {
6
6
  const navigateBack = useModalStore(state => state.navigateBack);
7
7
  const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
8
- return (_jsxs("div", { className: cn("flex h-16 items-center justify-between border-b border-[#e4e4e7] bg-white px-5 py-3", className), children: [_jsxs("button", { onClick: handleBack || navigateBack, className: "flex h-6 w-6 items-center justify-center transition-opacity hover:opacity-70", children: [_jsx(ChevronDown, { className: "h-6 w-6 rotate-90 text-[#51525c]" }), showBackWord && _jsx("span", { className: "text-sm font-medium", children: "Back" })] }), _jsx("p", { className: "font-inter text-lg font-semibold leading-7 text-[#18181b]", children: title }), showCloseButton && (_jsx("button", { onClick: handleClose || (() => setB3ModalOpen(false)), className: "flex h-6 w-6 items-center justify-center transition-opacity hover:opacity-70", children: _jsx(X, { className: "h-6 w-6 text-[#51525c]" }) })), children] }));
8
+ return (_jsxs("div", { className: cn("flex h-16 items-center justify-between border-b border-[#e4e4e7] bg-white px-5 py-3", className), children: [showBackButton ? (_jsxs("button", { onClick: handleBack || navigateBack, className: "flex h-6 w-6 items-center justify-center transition-opacity hover:opacity-70", children: [_jsx(ChevronDown, { className: "h-6 w-6 rotate-90 text-[#51525c]" }), showBackWord && _jsx("span", { className: "text-sm font-medium", children: "Back" })] })) : (_jsx("div", { className: "w-2" })), _jsx("p", { className: "font-inter text-lg font-semibold leading-7 text-[#18181b]", children: title }), showCloseButton ? (_jsx("button", { onClick: handleClose || (() => setB3ModalOpen(false)), className: "flex h-6 w-6 items-center justify-center transition-opacity hover:opacity-70", children: _jsx(X, { className: "h-6 w-6 text-[#51525c]" }) })) : (_jsx("div", { className: "w-2" })), children] }));
9
9
  };
10
10
  export default ModalHeader;
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { SignInWithB3, StyleRoot, useAccountWallet, useAuthentication, useB3, useIsMobile, } from "../../../../global-account/react/index.js";
2
+ import { IPFSMediaRenderer, SignInWithB3, StyleRoot, useAccountWallet, useAuthentication, useB3, useIsMobile, } from "../../../../global-account/react/index.js";
3
3
  import Icon from "../../../../global-account/react/components/custom/Icon.js";
4
4
  import { ecosystemWalletId } from "../../../../shared/constants/index.js";
5
5
  import { cn, truncateAddress } from "../../../../shared/utils/index.js";
6
6
  import { Menu, MenuButton, MenuItems, Transition } from "@headlessui/react";
7
7
  import { useEffect } from "react";
8
8
  import { useConnectedWallets, useSetActiveWallet, useWalletInfo } from "thirdweb/react";
9
+ import { useAccountWalletImage } from "../../hooks/useAccountWallet.js";
9
10
  import { ManageAccountButton } from "../custom/ManageAccountButton.js";
10
11
  export function SignIn(props) {
11
12
  const { className } = props;
@@ -34,8 +35,9 @@ export function SignIn(props) {
34
35
  setActiveWallet(connectedEOAWallet);
35
36
  }
36
37
  }, [connectedEOAWallet, isActiveEOAWallet, setActiveWallet, automaticallySetFirstEoa]);
38
+ const walletImage = useAccountWalletImage();
37
39
  // Desktop version - original dropdown menu
38
- return (_jsx(StyleRoot, { children: _jsx(Menu, { className: `relative flex items-center ${className || ""}`, as: "div", children: globalAddress ? (_jsxs(_Fragment, { children: [_jsxs(MenuButton, { className: "bg-b3-react-background group flex h-10 items-center gap-1 rounded-xl px-3", children: [!!wallet.meta?.icon && (_jsx("img", { src: wallet.meta.icon, alt: wallet.meta.icon, className: "bg-b3-react-primary h-6 w-6 rounded-full object-cover opacity-100" })), _jsx("div", { className: "text-as-primary", children: ensName ? ensName : truncateAddress(globalAddress) })] }), _jsx(Transition, { enter: "duration-200 ease-out", enterFrom: "scale-95 opacity-0", enterTo: "scale-100 opacity-100", leave: "duration-300 ease-out", leaveFrom: "scale-100 opacity-100", leaveTo: "scale-95 opacity-0", children: _jsx(MenuItems, { className: "b3-root absolute -right-4 top-full min-w-64 rounded-2xl border lg:right-0", modal: false,
40
+ return (_jsx(StyleRoot, { children: _jsx(Menu, { className: `relative flex items-center ${className || ""}`, as: "div", children: globalAddress ? (_jsxs(_Fragment, { children: [_jsxs(MenuButton, { className: "bg-b3-react-background group flex h-10 items-center gap-1 rounded-xl px-3 focus:outline-none", children: [!!walletImage && (_jsx(IPFSMediaRenderer, { src: walletImage, alt: "Wallet Image", className: "bg-b3-react-primary h-6 w-6 rounded-full object-cover opacity-100" })), _jsx("div", { className: "text-as-primary", children: ensName ? ensName : truncateAddress(globalAddress) })] }), _jsx(Transition, { enter: "duration-200 ease-out", enterFrom: "scale-95 opacity-0", enterTo: "scale-100 opacity-100", leave: "duration-300 ease-out", leaveFrom: "scale-100 opacity-100", leaveTo: "scale-95 opacity-0", children: _jsx(MenuItems, { className: "b3-root absolute -right-4 top-full min-w-64 rounded-2xl border focus:outline-none lg:right-0", modal: false,
39
41
  // TODO: Figure out why setting anchor on mobile causes z-index issues where it appears under elements
40
42
  anchor: isMobile ? "top end" : undefined, children: _jsxs("div", { className: "bg-b3-react-background", children: [connectedEOAWallet ? (_jsxs("div", { className: cn("border-b3-react-subtle bg-b3-react-background flex cursor-pointer items-center justify-between rounded-xl p-3"), onClick: () => handleSetActiveAccount(connectedEOAWallet?.id), children: [_jsxs("div", { className: "flex items-center", children: [_jsx("img", { className: "bg-b3-react-primary h-16 w-16 rounded-full opacity-100", src: eoaWalletIcon, alt: connectedEOAWallet?.id }), _jsxs("div", { className: "ml-4 grow", children: [ensName && _jsx("div", { children: ensName }), _jsx("div", { children: truncateAddress(globalAddress) }), _jsx("div", { children: walletInfo?.name })] })] }), isActiveEOAWallet && _jsx(Icon, { className: "fill-b3-react-primary", name: "check" })] })) : (connectedSmartWallet && (_jsxs("div", { className: cn("mb-2 flex cursor-pointer items-center justify-between rounded-xl p-3", isActiveSmartWallet
41
43
  ? "bg-b3-react-background"
@@ -15,8 +15,7 @@ export { getConnectOptionsFromStrategy, isWalletType, type AllowedStrategy } fro
15
15
  export { ManageAccount } from "./ManageAccount/ManageAccount";
16
16
  export { Deposit } from "./Deposit/Deposit";
17
17
  export { Send } from "./Send/Send";
18
- export { AvatarEditor } from "./AvatarEditor/AvatarEditor";
19
- export { ProfileEditor } from "./ProfileEditor/ProfileEditor";
18
+ export { IPFSMediaRenderer } from "./IPFSMediaRenderer/IPFSMediaRenderer";
20
19
  export { RequestPermissions } from "./RequestPermissions/RequestPermissions";
21
20
  export { RequestPermissionsButton } from "./RequestPermissions/RequestPermissionsButton";
22
21
  export { AccountAssets } from "./AccountAssets/AccountAssets";
@@ -1,3 +1,4 @@
1
+ // TODO woj: Barrel file for all components, this might be reason of bundle size issues
1
2
  // Core Components
2
3
  export { B3DynamicModal } from "./B3DynamicModal.js";
3
4
  export { B3Provider, InnerProvider } from "./B3Provider/B3Provider.js";
@@ -20,10 +21,8 @@ export { ManageAccount } from "./ManageAccount/ManageAccount.js";
20
21
  export { Deposit } from "./Deposit/Deposit.js";
21
22
  // Send Components
22
23
  export { Send } from "./Send/Send.js";
23
- // B3 Global Branding Wrapper
24
- // Profile Components
25
- export { AvatarEditor } from "./AvatarEditor/AvatarEditor.js";
26
- export { ProfileEditor } from "./ProfileEditor/ProfileEditor.js";
24
+ // Media Components
25
+ export { IPFSMediaRenderer } from "./IPFSMediaRenderer/IPFSMediaRenderer.js";
27
26
  // RequestPermissions Components
28
27
  export { RequestPermissions } from "./RequestPermissions/RequestPermissions.js";
29
28
  export { RequestPermissionsButton } from "./RequestPermissions/RequestPermissionsButton.js";
@@ -12,7 +12,7 @@ const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(D
12
12
  DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
13
13
  const DrawerContent = React.forwardRef(({ className, children, ...props }, ref) => {
14
14
  const container = typeof window !== "undefined" ? document.getElementById("b3-root") : null;
15
- return (_jsxs(DrawerPortal, { container: container, children: [_jsx(DrawerOverlay, {}), _jsx(DrawerPrimitive.Content, { ref: ref, className: cn("bg-b3-react-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border py-6", className), ...props, children: children })] }));
15
+ return (_jsxs(DrawerPortal, { container: container, children: [_jsx(DrawerOverlay, {}), _jsx(DrawerPrimitive.Content, { ref: ref, className: cn("bg-b3-react-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border py-6 pt-5", className), ...props, children: children })] }));
16
16
  });
17
17
  DrawerContent.displayName = "DrawerContent";
18
18
  const DrawerHeader = ({ className, ...props }) => (_jsx("div", { className: cn("grid gap-1.5 p-4 text-center sm:text-left", className), ...props }));
@@ -16,3 +16,4 @@ export declare function useAccountWallet(): {
16
16
  eoaWalletIcon?: string;
17
17
  smartWalletIcon?: string;
18
18
  };
19
+ export declare function useAccountWalletImage(): string;
@@ -69,3 +69,20 @@ export function useAccountWallet() {
69
69
  ]);
70
70
  return res;
71
71
  }
72
+ export function useAccountWalletImage() {
73
+ const { account, user } = useB3();
74
+ const activeWallet = useActiveWallet();
75
+ const connectedWallets = useConnectedWallets();
76
+ const connectedSmartWallet = connectedWallets.find(wallet => wallet.id === ecosystemWalletId);
77
+ const connectedEOAWallet = connectedWallets.find(wallet => wallet.id !== ecosystemWalletId);
78
+ const isActiveSmartWallet = activeWallet?.id === connectedSmartWallet?.id;
79
+ const { data: walletImage } = useWalletImage(connectedEOAWallet?.id);
80
+ // If not EOA sign in, then we need to show the smart wallet icon
81
+ const lastAuthProvider = useLastAuthProvider();
82
+ const smartWalletIcon = lastAuthProvider && !connectedEOAWallet
83
+ ? socialIcons[lastAuthProvider]
84
+ : "https://gradvatar.com/0x0000000000000000000000000000000000000000"; // show smart wallet of eoa wallet is gradvatar
85
+ const { data: profileData } = useProfile({ address: account?.address });
86
+ const avatarUrl = user?.avatar || profileData?.avatar;
87
+ return avatarUrl || (isActiveSmartWallet ? smartWalletIcon : walletImage) || "";
88
+ }
@@ -13,8 +13,8 @@ export declare function useAuthentication(partnerId: string): {
13
13
  onConnect: (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => Promise<void>;
14
14
  user: {
15
15
  email?: string | undefined;
16
- username?: string | undefined;
17
16
  telNumber?: string | undefined;
17
+ username?: string | undefined;
18
18
  ens?: string | undefined;
19
19
  avatar?: string | undefined;
20
20
  preferences?: {} | undefined;
@@ -41,8 +41,8 @@ export declare function useAuthentication(partnerId: string): {
41
41
  name?: string | undefined;
42
42
  address?: string | undefined;
43
43
  email?: string | undefined;
44
- phone?: string | undefined;
45
44
  username?: string | undefined;
45
+ phone?: string | undefined;
46
46
  fid?: string | undefined;
47
47
  };
48
48
  }[] | undefined;
@@ -8,8 +8,8 @@ import { Users } from "@b3dotfun/b3-api";
8
8
  export declare function useUserQuery(): {
9
9
  user: {
10
10
  email?: string | undefined;
11
- username?: string | undefined;
12
11
  telNumber?: string | undefined;
12
+ username?: string | undefined;
13
13
  ens?: string | undefined;
14
14
  avatar?: string | undefined;
15
15
  preferences?: {} | undefined;
@@ -36,8 +36,8 @@ export declare function useUserQuery(): {
36
36
  name?: string | undefined;
37
37
  address?: string | undefined;
38
38
  email?: string | undefined;
39
- phone?: string | undefined;
40
39
  username?: string | undefined;
40
+ phone?: string | undefined;
41
41
  fid?: string | undefined;
42
42
  };
43
43
  }[] | undefined;
@@ -360,12 +360,6 @@ export interface AvatarEditorModalProps extends BaseModalProps {
360
360
  /** Callback function called when avatar is successfully set */
361
361
  onSuccess?: () => void;
362
362
  }
363
- export interface ProfileEditorModalProps extends BaseModalProps {
364
- /** Modal type identifier */
365
- type: "profileEditor";
366
- /** Callback function called when profile is successfully updated */
367
- onSuccess?: () => void;
368
- }
369
363
  /**
370
364
  * Props for the Deposit modal
371
365
  * Allows users to deposit tokens into their global account
@@ -391,7 +385,7 @@ export interface SendModalProps extends BaseModalProps {
391
385
  /**
392
386
  * Union type of all possible modal content types
393
387
  */
394
- export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | LinkNewAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | DepositModalProps | SendModalProps | ProfileEditorModalProps;
388
+ export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | LinkNewAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | DepositModalProps | SendModalProps;
395
389
  /**
396
390
  * State interface for the modal store
397
391
  */
@@ -35,13 +35,13 @@ export declare const supportedChainNetworks: {
35
35
  uri: string;
36
36
  }[];
37
37
  };
38
+ _id: string | {};
38
39
  icon: {
39
40
  format: string;
40
41
  height: number;
41
42
  width: number;
42
43
  url: string;
43
44
  };
44
- _id: string | {};
45
45
  }[];
46
46
  export declare const coingeckoChains: Record<number, {
47
47
  coingecko_id: string;
@@ -1,7 +1,14 @@
1
+ /**
2
+ * List of IPFS gateways to use for converting ipfs:// URLs to HTTP URLs
3
+ * These gateways must match the allowed list in profileDisplay.ts validateImageUrl()
4
+ */
1
5
  const IPFS_GATEWAYS = [
2
- "https://cloudflare-ipfs.com/ipfs",
3
- "https://ipfs.io/ipfs",
4
- // Can add more gateways as needed
6
+ "https://cloudflare-ipfs.com/ipfs", // Primary gateway - fast and reliable
7
+ "https://ipfs.io/ipfs", // Fallback gateway
8
+ "https://gateway.pinata.cloud/ipfs", // Additional option
9
+ "https://dweb.link/ipfs", // Additional option
10
+ "https://nftstorage.link/ipfs", // Additional option
11
+ "https://w3s.link/ipfs", // Additional option
5
12
  ];
6
13
  /**
7
14
  * Converts an IPFS URL to a gateway URL