@b3dotfun/sdk 0.0.30-alpha.9 → 0.0.31-alpha.0

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 (71) hide show
  1. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
  2. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +6 -1
  3. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  4. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +2 -2
  5. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  6. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +3 -3
  7. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
  8. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +94 -0
  9. package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.js +5 -0
  10. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +3 -40
  11. package/dist/cjs/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
  12. package/dist/cjs/global-account/react/components/ManageAccount/TokenBalanceRow.js +8 -0
  13. package/dist/cjs/global-account/react/components/TokenIcon.d.ts +11 -0
  14. package/dist/cjs/global-account/react/components/TokenIcon.js +43 -0
  15. package/dist/cjs/global-account/react/components/ui/accordion.d.ts +7 -0
  16. package/dist/cjs/global-account/react/components/ui/accordion.js +53 -0
  17. package/dist/cjs/global-account/react/components/ui/dialog.js +1 -1
  18. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -0
  19. package/dist/cjs/global-account/utils/analytics.d.ts +6 -0
  20. package/dist/cjs/global-account/utils/analytics.js +1 -0
  21. package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
  22. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +5 -1
  23. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  24. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +2 -2
  25. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  26. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +4 -4
  27. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
  28. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +88 -0
  29. package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.js +2 -0
  30. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +6 -40
  31. package/dist/esm/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
  32. package/dist/esm/global-account/react/components/ManageAccount/TokenBalanceRow.js +5 -0
  33. package/dist/esm/global-account/react/components/TokenIcon.d.ts +11 -0
  34. package/dist/esm/global-account/react/components/TokenIcon.js +37 -0
  35. package/dist/esm/global-account/react/components/ui/accordion.d.ts +7 -0
  36. package/dist/esm/global-account/react/components/ui/accordion.js +14 -0
  37. package/dist/esm/global-account/react/components/ui/dialog.js +1 -1
  38. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -0
  39. package/dist/esm/global-account/utils/analytics.d.ts +6 -0
  40. package/dist/esm/global-account/utils/analytics.js +1 -0
  41. package/dist/styles/index.css +1 -1
  42. package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
  43. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  44. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  45. package/dist/types/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
  46. package/dist/types/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
  47. package/dist/types/global-account/react/components/TokenIcon.d.ts +11 -0
  48. package/dist/types/global-account/react/components/ui/accordion.d.ts +7 -0
  49. package/dist/types/global-account/utils/analytics.d.ts +6 -0
  50. package/package.json +10 -18
  51. package/src/anyspend/react/components/AnySpendStakeB3.tsx +1 -1
  52. package/src/anyspend/react/components/AnyspendDepositHype.tsx +9 -0
  53. package/src/anyspend/react/components/AnyspendSignatureMint.tsx +4 -4
  54. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +12 -3
  55. package/src/anyspend/react/components/common/PanelOnramp.tsx +8 -4
  56. package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +228 -0
  57. package/src/global-account/react/components/ManageAccount/ContentTokens.tsx +3 -0
  58. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +7 -285
  59. package/src/global-account/react/components/ManageAccount/TokenBalanceRow.tsx +46 -0
  60. package/src/global-account/react/components/TokenIcon.tsx +87 -0
  61. package/src/global-account/react/components/ui/accordion.tsx +53 -0
  62. package/src/global-account/react/components/ui/dialog.tsx +1 -1
  63. package/src/global-account/react/hooks/useB3BalanceFromAddresses.ts +1 -1
  64. package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +3 -0
  65. package/src/global-account/utils/analytics.ts +10 -0
  66. package/dist/cjs/index.d.ts +0 -0
  67. package/dist/cjs/index.js +0 -2
  68. package/dist/esm/index.d.ts +0 -0
  69. package/dist/esm/index.js +0 -2
  70. package/dist/types/index.d.ts +0 -0
  71. package/src/index.ts +0 -1
@@ -1,3 +1,9 @@
1
+ declare global {
2
+ interface Window {
3
+ gtag: (...args: any[]) => void;
4
+ dataLayer: any[];
5
+ }
6
+ }
1
7
  /**
2
8
  * Load Google Analytics 4 script and initialize
3
9
  */
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ // Global window interface augmentations for B3 SDK
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.sendGA4Event = exports.loadGA4Script = void 0;
4
5
  const GA4_MEASUREMENT_ID = "G-VER9DKJH87";
@@ -1,3 +1,7 @@
1
+ export declare const HYPE_TOKEN_DETAILS: {
2
+ SYMBOL: string;
3
+ LOGO_URI: string;
4
+ };
1
5
  export interface AnySpendDepositHypeProps {
2
6
  loadOrder?: string;
3
7
  mode?: "modal" | "page";
@@ -22,6 +22,10 @@ import { ESCROW_ABI } from "../../../anyspend/abis/escrow.js";
22
22
  import { ArrowDown } from "lucide-react";
23
23
  import { PanelOnramp } from "./common/PanelOnramp.js";
24
24
  const SLIPPAGE_PERCENT = 3;
25
+ export const HYPE_TOKEN_DETAILS = {
26
+ SYMBOL: "HYPE",
27
+ LOGO_URI: "https://cdn.hypeduel.com/hypes-coin.svg",
28
+ };
25
29
  function generateEncodedDataForDepositHype(amount, beneficiary) {
26
30
  invariant(BigInt(amount) > 0, "Amount must be greater than zero");
27
31
  const encodedData = encodeFunctionData({
@@ -118,7 +122,7 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
118
122
  await handleFiatOrder();
119
123
  }
120
124
  };
121
- const mainView = (_jsxs("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsx("div", { children: _jsx("h1", { className: "text-as-primary text-xl font-bold", children: paymentType === "crypto" ? "Deposit Crypto" : "Fund with Fiat" }) }) }), _jsx("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? (_jsx(PaySection, { paymentType: "crypto", selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, selectedFiatPaymentMethod: selectedFiatPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD), onSelectFiatPaymentMethod: () => setActivePanel(PanelView.FIAT_PAYMENT_METHOD), anyspendQuote: anyspendQuote })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: recipientAddress, destinationToken: B3_TOKEN, destinationChainId: base.id, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: PanelView.RECIPIENT_SELECTION }) })), _jsx("div", { className: cn("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: _jsx(Button, { variant: "ghost", className: cn("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: B3_TOKEN, selectedDstChainId: base.id, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, onChangeDstAmount: value => {
125
+ const mainView = (_jsxs("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsx("div", { children: _jsx("h1", { className: "text-as-primary text-xl font-bold", children: paymentType === "crypto" ? "Deposit Crypto" : "Fund with Fiat" }) }) }), _jsx("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? (_jsx(PaySection, { paymentType: "crypto", selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, selectedFiatPaymentMethod: selectedFiatPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD), onSelectFiatPaymentMethod: () => setActivePanel(PanelView.FIAT_PAYMENT_METHOD), anyspendQuote: anyspendQuote })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: recipientAddress, destinationToken: B3_TOKEN, destinationChainId: base.id, dstTokenSymbol: HYPE_TOKEN_DETAILS.SYMBOL, hideDstToken: true, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: PanelView.RECIPIENT_SELECTION }) })), _jsx("div", { className: cn("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: _jsx(Button, { variant: "ghost", className: cn("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: B3_TOKEN, dstTokenSymbol: HYPE_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: HYPE_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: base.id, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, onChangeDstAmount: value => {
122
126
  setIsSrcInputDirty(false);
123
127
  setSrcAmount(value);
124
128
  }, anyspendQuote: anyspendQuote }))] }) }), _jsx(ErrorSection, { error: getAnyspendQuoteError }), _jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2", getAnyspendQuoteError && "mt-0"), children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: cn("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: btnInfo.text }) }), mainFooter ? mainFooter : null] }));
@@ -12,6 +12,8 @@ interface CryptoReceiveSectionProps {
12
12
  setSelectedDstToken?: (token: components["schemas"]["Token"]) => void;
13
13
  onChangeDstAmount?: (value: string) => void;
14
14
  anyspendQuote?: any;
15
+ dstTokenSymbol?: string;
16
+ dstTokenLogoURI?: string;
15
17
  }
16
- export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
18
+ export declare function CryptoReceiveSection({ isDepositMode, isBuyMode, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, }: CryptoReceiveSectionProps): import("react/jsx-runtime").JSX.Element;
17
19
  export {};
@@ -6,10 +6,10 @@ import { formatDisplayNumber } from "../../../../shared/utils/number.js";
6
6
  import { ChevronRight } from "lucide-react";
7
7
  import { motion } from "motion/react";
8
8
  import { OrderTokenAmount } from "./OrderTokenAmount.js";
9
- export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, }) {
9
+ export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, }) {
10
10
  return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: isDepositMode ? "Deposit" : "Receive" }), selectedRecipientAddress ? (_jsx("button", { className: cn("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: _jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? formatUsername(recipientName) : shortenAddress(selectedRecipientAddress || "") }), _jsx(ChevronRight, { className: "h-4 w-4" })] }) })) : (_jsx("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: _jsx("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
11
11
  // Fixed destination token display for buy mode and deposit mode
12
- _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary text-2xl font-bold", children: dstAmount || "0" }), _jsxs("div", { className: "bg-as-brand/10 border-as-brand/30 flex items-center gap-3 rounded-xl border px-4 py-3", children: [dstToken.metadata?.logoURI && (_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-8 w-8 rounded-full" })), _jsx("span", { className: "text-as-brand text-lg font-bold", children: dstToken.symbol })] })] })) : (
12
+ _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary text-2xl font-bold", children: dstAmount || "0" }), _jsxs("div", { className: "bg-as-brand/10 border-as-brand/30 flex items-center gap-3 rounded-xl border px-4 py-3", children: [(dstTokenLogoURI || dstToken.metadata?.logoURI) && (_jsx("img", { src: dstTokenLogoURI || dstToken.metadata?.logoURI, alt: dstTokenSymbol || dstToken.symbol, className: "h-8 w-8 rounded-full" })), _jsx("span", { className: "text-as-brand text-lg font-bold", children: dstTokenSymbol || dstToken.symbol })] })] })) : (
13
13
  // Token selection for regular swap mode
14
14
  _jsx(OrderTokenAmount, { address: selectedRecipientAddress, context: "to", inputValue: dstAmount, onChangeInput: onChangeDstAmount || (() => { }), chainId: selectedDstChainId || dstToken.chainId, setChainId: setSelectedDstChainId || (() => { }), token: dstToken, setToken: setSelectedDstToken || (() => { }) })), _jsxs("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: [formatDisplayNumber(anyspendQuote?.data?.currencyOut?.amountUsd, {
15
15
  style: "currency",
@@ -1,6 +1,6 @@
1
1
  import { components } from "../../../../anyspend/types/api";
2
2
  import { FiatPaymentMethod } from "./FiatPaymentMethod";
3
- export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, }: {
3
+ export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken, }: {
4
4
  srcAmountOnRamp: string;
5
5
  setSrcAmountOnRamp: (amount: string) => void;
6
6
  selectedPaymentMethod?: FiatPaymentMethod;
@@ -13,4 +13,6 @@ export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selec
13
13
  onDestinationChainChange?: (chainId: number) => void;
14
14
  fiatPaymentMethodIndex: number;
15
15
  recipientSelectionPanelIndex: number;
16
+ dstTokenSymbol?: string;
17
+ hideDstToken?: boolean;
16
18
  }): import("react/jsx-runtime").JSX.Element;
@@ -2,14 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useCoinbaseOnrampOptions, useGeoOnrampOptions } from "../../../../anyspend/react/index.js";
3
3
  import { ALL_CHAINS } from "../../../../anyspend/utils/chain.js";
4
4
  import { Input, useGetGeo, useProfile } from "../../../../global-account/react/index.js";
5
- import { formatUsername } from "../../../../shared/utils/index.js";
5
+ import { cn, formatUsername } from "../../../../shared/utils/index.js";
6
6
  import { formatAddress } from "../../../../shared/utils/formatAddress.js";
7
7
  import { ChevronRight, Wallet } from "lucide-react";
8
8
  import { useRef } from "react";
9
9
  import { toast } from "sonner";
10
10
  import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
11
11
  import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
12
- export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, }) {
12
+ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken = false, }) {
13
13
  // Get geo-based onramp options to access fee information
14
14
  const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
15
15
  // Helper function to get fees from API data
@@ -68,9 +68,9 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPayme
68
68
  };
69
69
  return (_jsxs("div", { className: "panel-onramp bg-as-surface-primary flex w-full flex-col", children: [_jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm font-bold", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm", onClick: () => setActivePanel(fiatPaymentMethodIndex), children: selectedPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "C" }) }), "Coinbase Pay"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedPaymentMethod === FiatPaymentMethod.STRIPE ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "S" }) }), "Stripe"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { ref: amountInputRef, type: "text", value: srcAmountOnRamp, onChange: handleAmountChange, placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
70
70
  width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
71
- } })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "20", "25"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmountOnRamp === value
71
+ } })] }) }), _jsx("div", { className: cn("mx-auto mb-6 inline-grid grid-cols-4 gap-2", hideDstToken && "mb-0"), children: ["5", "10", "20", "25"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmountOnRamp === value
72
72
  ? "border-as-border-secondary bg-as-surface-secondary"
73
- : "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && (_jsx(OrderTokenAmountFiat, { address: _recipientAddress, context: "to", inputValue: destinationAmount || "0", onChangeInput: () => { }, chainId: destinationChainId, setChainId: onDestinationChainChange || (() => { }), token: destinationToken, setToken: onDestinationTokenChange || (() => { }) }))] }), _jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary mt-4 flex w-full flex-col gap-3 rounded-xl border p-4", children: [_jsxs("div", { className: "flex w-full items-center justify-between gap-2", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm", children: "Recipient" }), _recipientAddress ? (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(recipientSelectionPanelIndex), children: [_jsx("span", { className: "text-sm", children: recipientName ? formatUsername(recipientName) : formatAddress(_recipientAddress) }), _jsx(ChevronRight, { size: 16 })] })) : (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx(Wallet, { className: "text-as-brand", size: 16 }), "Select recipient", _jsx(ChevronRight, { size: 16 })] }))] }), _jsx("div", { className: "divider w-full" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Expected to receive" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: [destinationAmount || "0", " ", destinationToken?.symbol || ""] }), _jsxs("span", { className: "text-as-tertiarry text-sm", children: ["on ", destinationChainId ? ALL_CHAINS[destinationChainId]?.name : ""] }), destinationToken && destinationChainId && destinationToken.metadata?.logoURI && (_jsx("img", { src: ALL_CHAINS[destinationChainId]?.logoUrl, alt: "Chain", className: "h-4 w-4 rounded-full" }))] })] }), _jsx("div", { className: "divider w-full" }), _jsx("div", { className: "", children: _jsx("div", { className: "flex items-center justify-between", children: (() => {
73
+ : "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && !hideDstToken && (_jsx(OrderTokenAmountFiat, { address: _recipientAddress, context: "to", inputValue: destinationAmount || "0", onChangeInput: () => { }, chainId: destinationChainId, setChainId: onDestinationChainChange || (() => { }), token: destinationToken, setToken: onDestinationTokenChange || (() => { }) }))] }), _jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary mt-4 flex w-full flex-col gap-3 rounded-xl border p-4", children: [_jsxs("div", { className: "flex w-full items-center justify-between gap-2", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm", children: "Recipient" }), _recipientAddress ? (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(recipientSelectionPanelIndex), children: [_jsx("span", { className: "text-sm", children: recipientName ? formatUsername(recipientName) : formatAddress(_recipientAddress) }), _jsx(ChevronRight, { size: 16 })] })) : (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx(Wallet, { className: "text-as-brand", size: 16 }), "Select recipient", _jsx(ChevronRight, { size: 16 })] }))] }), _jsx("div", { className: "divider w-full" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Expected to receive" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: [destinationAmount || "0", " ", dstTokenSymbol || destinationToken?.symbol || ""] }), _jsxs("span", { className: "text-as-tertiarry text-sm", children: ["on ", destinationChainId ? ALL_CHAINS[destinationChainId]?.name : ""] }), destinationToken && destinationChainId && destinationToken.metadata?.logoURI && (_jsx("img", { src: ALL_CHAINS[destinationChainId]?.logoUrl, alt: "Chain", className: "h-4 w-4 rounded-full" }))] })] }), _jsx("div", { className: "divider w-full" }), _jsx("div", { className: "", children: _jsx("div", { className: "flex items-center justify-between", children: (() => {
74
74
  const currentPaymentMethod = selectedPaymentMethod || FiatPaymentMethod.NONE;
75
75
  const fee = getFeeFromApi(currentPaymentMethod);
76
76
  return (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total" }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(currentPaymentMethod).toFixed(2)] })] }));
@@ -0,0 +1,6 @@
1
+ interface BalanceContentProps {
2
+ onLogout?: () => void;
3
+ partnerId: string;
4
+ }
5
+ export declare function BalanceContent({ onLogout, partnerId }: BalanceContentProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, CopyToClipboard, useAuthentication, useB3BalanceFromAddresses, useModalStore, useNativeBalance, useProfile, } from "../../../../global-account/react/index.js";
3
+ import { BankIcon } from "../../../../global-account/react/components/icons/BankIcon.js";
4
+ import { SignOutIcon } from "../../../../global-account/react/components/icons/SignOutIcon.js";
5
+ import { SwapIcon } from "../../../../global-account/react/components/icons/SwapIcon.js";
6
+ import { formatUsername } from "../../../../shared/utils/index.js";
7
+ import { Loader2, Pencil } from "lucide-react";
8
+ import { useEffect, useRef, useState } from "react";
9
+ import { useActiveAccount } from "thirdweb/react";
10
+ import useFirstEOA from "../../hooks/useFirstEOA.js";
11
+ import { B3TokenIcon, EthereumTokenIcon } from "../TokenIcon.js";
12
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../ui/accordion.js";
13
+ import { TokenBalanceRow } from "./TokenBalanceRow.js";
14
+ function centerTruncate(str, length = 4) {
15
+ if (str.length <= length * 2)
16
+ return str;
17
+ return `${str.slice(0, length)}...${str.slice(-length)}`;
18
+ }
19
+ export function BalanceContent({ onLogout, partnerId }) {
20
+ const account = useActiveAccount();
21
+ const { address: eoaAddress, info: eoaInfo } = useFirstEOA();
22
+ const { data: profile } = useProfile({
23
+ address: eoaAddress || account?.address,
24
+ fresh: true,
25
+ });
26
+ const { setB3ModalOpen, setB3ModalContentType } = useModalStore();
27
+ const { logout } = useAuthentication(partnerId);
28
+ const [logoutLoading, setLogoutLoading] = useState(false);
29
+ const [openAccordions, setOpenAccordions] = useState([]);
30
+ const hasExpandedRef = useRef(false);
31
+ console.log("eoaAddress", eoaAddress);
32
+ console.log("account?.address", account?.address);
33
+ // Balance data fetching
34
+ const { data: eoaNativeBalance, isLoading: eoaNativeLoading } = useNativeBalance(eoaAddress);
35
+ const { data: eoaB3Balance, isLoading: eoaB3Loading } = useB3BalanceFromAddresses(eoaAddress);
36
+ const { data: b3Balance, isLoading: b3Loading } = useB3BalanceFromAddresses(account?.address);
37
+ const { data: nativeBalance, isLoading: nativeLoading } = useNativeBalance(account?.address);
38
+ // Calculate total USD values for comparison
39
+ const globalAccountTotalUsd = (b3Balance?.balanceUsd || 0) + (nativeBalance?.totalUsd || 0);
40
+ const eoaTotalUsd = (eoaB3Balance?.balanceUsd || 0) + (eoaNativeBalance?.totalUsd || 0);
41
+ // Check if both data sets are ready (not loading and have data)
42
+ const isGlobalDataReady = !b3Loading && !nativeLoading && b3Balance !== undefined && nativeBalance !== undefined;
43
+ const isEoaDataReady = !eoaAddress || (!eoaB3Loading && !eoaNativeLoading && eoaB3Balance !== undefined && eoaNativeBalance !== undefined);
44
+ const isBothDataReady = isGlobalDataReady && isEoaDataReady;
45
+ // Reset expansion flag when component mounts
46
+ useEffect(() => {
47
+ hasExpandedRef.current = false;
48
+ setOpenAccordions([]);
49
+ }, []);
50
+ // Auto-expand the appropriate section when data becomes ready
51
+ useEffect(() => {
52
+ if (isBothDataReady && !hasExpandedRef.current && eoaAddress && account?.address) {
53
+ hasExpandedRef.current = true;
54
+ // Determine which section to expand based on higher balance
55
+ if (globalAccountTotalUsd === 0 && eoaTotalUsd === 0) {
56
+ // If both have 0 balance, expand global account by default
57
+ setOpenAccordions(["global-account"]);
58
+ }
59
+ else if (globalAccountTotalUsd >= eoaTotalUsd) {
60
+ setOpenAccordions(["global-account"]);
61
+ }
62
+ else {
63
+ setOpenAccordions(["eoa-account"]);
64
+ }
65
+ }
66
+ }, [isBothDataReady, globalAccountTotalUsd, eoaTotalUsd, eoaAddress, account?.address]);
67
+ const onLogoutEnhanced = async () => {
68
+ setLogoutLoading(true);
69
+ await logout();
70
+ onLogout?.();
71
+ setB3ModalOpen(false);
72
+ setLogoutLoading(false);
73
+ };
74
+ return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "relative", children: [profile?.avatar ? (_jsx("img", { src: profile?.avatar, alt: "Profile", className: "size-24 rounded-full" })) : (_jsx("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), _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: _jsx(Pencil, { size: 16, className: "text-b3-background" }) })] }), _jsxs("div", { children: [_jsx("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || formatUsername(profile?.name || "") }), _jsxs("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [_jsx("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), _jsx(CopyToClipboard, { text: account?.address || "" })] })] })] }) }), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs(Button, { className: "manage-account-deposit bg-b3-primary-wash hover:bg-b3-primary-wash/70 h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
75
+ setB3ModalOpen(true);
76
+ setB3ModalContentType({
77
+ type: "anySpend",
78
+ defaultActiveTab: "fiat",
79
+ showBackButton: true,
80
+ });
81
+ }, children: [_jsx(BankIcon, { size: 24, className: "text-b3-primary-blue shrink-0" }), _jsx("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Deposit" })] }), _jsxs(Button, { className: "manage-account-swap bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
82
+ setB3ModalOpen(true);
83
+ setB3ModalContentType({
84
+ type: "anySpend",
85
+ showBackButton: true,
86
+ });
87
+ }, children: [_jsx(SwapIcon, { size: 24, className: "text-b3-primary-blue" }), _jsx("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Swap" })] })] }), _jsxs(Accordion, { type: "multiple", value: openAccordions, onValueChange: setOpenAccordions, className: "space-y-2", children: [_jsxs(AccordionItem, { value: "global-account", className: "border-none", children: [_jsx(AccordionTrigger, { className: "text-b3-grey font-neue-montreal-semibold py-2 hover:no-underline", children: _jsx("span", { children: "Balance" }) }), _jsxs(AccordionContent, { className: "space-y-4", children: [_jsx(TokenBalanceRow, { icon: _jsx(B3TokenIcon, { className: "size-10" }), name: "B3", balance: `${b3Balance?.formattedTotal || "0.00"} B3`, usdValue: b3Balance?.balanceUsdFormatted || "0.00", priceChange: b3Balance?.priceChange24h }), _jsx(TokenBalanceRow, { icon: _jsx(EthereumTokenIcon, { className: "size-10" }), name: "Ethereum", balance: `${nativeBalance?.formattedTotal || "0.00"} ETH`, usdValue: nativeBalance?.formattedTotalUsd || "0.00", priceChange: nativeBalance?.priceChange24h })] })] }), eoaAddress && (_jsxs(AccordionItem, { value: "eoa-account", className: "border-none", children: [_jsx(AccordionTrigger, { className: "text-b3-grey font-neue-montreal-semibold py-2 hover:no-underline", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { children: ["Connected ", eoaInfo?.data?.name || "Wallet"] }), _jsxs("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [_jsx("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(eoaAddress, 6) }), _jsx(CopyToClipboard, { text: eoaAddress })] })] }) }), _jsxs(AccordionContent, { className: "space-y-4", children: [_jsx(TokenBalanceRow, { icon: _jsx(B3TokenIcon, { className: "size-10" }), name: "B3", balance: `${eoaB3Balance?.formattedTotal || "0.00"} B3`, usdValue: eoaB3Balance?.balanceUsdFormatted || "0.00", priceChange: eoaB3Balance?.priceChange24h }), _jsx(TokenBalanceRow, { icon: _jsx(EthereumTokenIcon, { className: "size-10" }), name: "Ethereum", balance: `${eoaNativeBalance?.formattedTotal || "0.00"} ETH`, usdValue: eoaNativeBalance?.formattedTotalUsd || "0.00", priceChange: eoaNativeBalance?.priceChange24h })] })] }))] }), _jsxs("button", { className: "border-b3-line hover:bg-b3-line relative flex w-full items-center justify-center rounded-2xl border p-4 transition-colors", onClick: onLogoutEnhanced, children: [_jsx("span", { className: "font-neue-montreal-semibold text-b3-grey", children: "Sign out" }), _jsx("div", { className: "absolute right-4", children: logoutLoading ? (_jsx(Loader2, { className: "animate-spin", size: 16 })) : (_jsx(SignOutIcon, { size: 16, className: "text-b3-grey" })) })] })] }));
88
+ }
@@ -9,6 +9,7 @@ import { NumericFormat } from "react-number-format";
9
9
  import { toast } from "sonner";
10
10
  import { useActiveAccount } from "thirdweb/react";
11
11
  import { encodeFunctionData, erc20Abi, isAddress, parseUnits } from "viem";
12
+ import invariant from "invariant";
12
13
  // Panel view enum for managing navigation between token list and send form
13
14
  var TokenPanelView;
14
15
  (function (TokenPanelView) {
@@ -140,6 +141,7 @@ export function ContentTokens({ activeTab }) {
140
141
  address: displayToken.address,
141
142
  };
142
143
  try {
144
+ invariant(isAddress(recipientAddress), "Recipient address is not a valid address");
143
145
  const sendTokenData = encodeFunctionData({
144
146
  abi: erc20Abi,
145
147
  functionName: "transfer",
@@ -1,42 +1,25 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, CopyToClipboard, TabsContentPrimitive, TabsListPrimitive, TabsPrimitive, TabTriggerPrimitive, useAccountAssets, useAuthentication, useB3BalanceFromAddresses, useGetAllTWSigners, useModalStore, useNativeBalance, useProfile, useRemoveSessionKey, } from "../../../../global-account/react/index.js";
3
- import { BankIcon } from "../../../../global-account/react/components/icons/BankIcon.js";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, TabsContentPrimitive, TabsListPrimitive, TabsPrimitive, TabTriggerPrimitive, useAccountAssets, useAuthentication, useGetAllTWSigners, useModalStore, useRemoveSessionKey, } from "../../../../global-account/react/index.js";
4
3
  import { SignOutIcon } from "../../../../global-account/react/components/icons/SignOutIcon.js";
5
- import { SwapIcon } from "../../../../global-account/react/components/icons/SwapIcon.js";
6
- import { formatUsername } from "../../../../shared/utils/index.js";
7
4
  import { formatNumber } from "../../../../shared/utils/formatNumber.js";
8
5
  import { client } from "../../../../shared/utils/thirdweb.js";
9
- import { BarChart3, Coins, Image, LinkIcon, Loader2, Pencil, Settings, Triangle, UnlinkIcon } from "lucide-react";
6
+ import { BarChart3, Coins, Image, LinkIcon, Loader2, Settings, UnlinkIcon } from "lucide-react";
10
7
  import { useState } from "react";
11
8
  import { useActiveAccount, useProfiles, useUnlinkProfile } from "thirdweb/react";
12
9
  import { formatUnits } from "viem";
13
- import useFirstEOA from "../../hooks/useFirstEOA.js";
14
10
  import { getProfileDisplayInfo } from "../../utils/profileDisplay.js";
15
11
  import { AccountAssets } from "../AccountAssets/AccountAssets.js";
16
12
  import { ContentTokens } from "./ContentTokens.js";
17
- function centerTruncate(str, length = 4) {
18
- if (str.length <= length * 2)
19
- return str;
20
- return `${str.slice(0, length)}...${str.slice(-length)}`;
21
- }
13
+ import { BalanceContent } from "./BalanceContent.js";
22
14
  export function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain, partnerId, }) {
23
15
  const [revokingSignerId, setRevokingSignerId] = useState(null);
24
16
  const account = useActiveAccount();
25
17
  const { data: nfts, isLoading } = useAccountAssets(account?.address);
26
- const { data: b3Balance } = useB3BalanceFromAddresses(account?.address);
27
- const { data: nativeBalance } = useNativeBalance(account?.address);
28
- const { address: eoaAddress } = useFirstEOA();
29
- const { data: profile } = useProfile({
30
- address: eoaAddress || account?.address,
31
- fresh: true,
32
- });
33
- const { data: eoaNativeBalance } = useNativeBalance(eoaAddress);
34
- const { data: eoaB3Balance } = useB3BalanceFromAddresses(eoaAddress);
35
18
  const { data: signers, refetch: refetchSigners } = useGetAllTWSigners({
36
19
  chain,
37
20
  accountAddress: account?.address,
38
21
  });
39
- const { setB3ModalOpen, setB3ModalContentType, contentType } = useModalStore();
22
+ const { setB3ModalOpen, contentType } = useModalStore();
40
23
  const { activeTab = "overview", setActiveTab } = contentType;
41
24
  const { logout } = useAuthentication(partnerId);
42
25
  const [logoutLoading, setLogoutLoading] = useState(false);
@@ -63,23 +46,6 @@ export function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit
63
46
  setB3ModalOpen(false);
64
47
  setLogoutLoading(false);
65
48
  };
66
- const BalanceContent = () => {
67
- const { info: eoaInfo } = useFirstEOA();
68
- return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "relative", children: [profile?.avatar ? (_jsx("img", { src: profile?.avatar, alt: "Profile", className: "size-24 rounded-full" })) : (_jsx("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), _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: _jsx(Pencil, { size: 16, className: "text-b3-background" }) })] }), _jsxs("div", { children: [_jsx("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || formatUsername(profile?.name || "") }), _jsxs("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [_jsx("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), _jsx(CopyToClipboard, { text: account?.address || "" })] })] })] }) }), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs(Button, { className: "manage-account-deposit bg-b3-primary-wash hover:bg-b3-primary-wash/70 h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
69
- setB3ModalOpen(true);
70
- setB3ModalContentType({
71
- type: "anySpend",
72
- defaultActiveTab: "fiat",
73
- showBackButton: true,
74
- });
75
- }, children: [_jsx(BankIcon, { size: 24, className: "text-b3-primary-blue shrink-0" }), _jsx("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Deposit" })] }), _jsxs(Button, { className: "manage-account-swap bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
76
- setB3ModalOpen(true);
77
- setB3ModalContentType({
78
- type: "anySpend",
79
- showBackButton: true,
80
- });
81
- }, children: [_jsx(SwapIcon, { size: 24, className: "text-b3-primary-blue" }), _jsx("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Swap" })] })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-b3-grey font-neue-montreal-semibold", children: "Balance" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: _jsx("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", alt: "B3", className: "size-10" }) }), _jsxs("div", { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "B3" }) }), _jsxs("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [b3Balance?.formattedTotal || "0.00", " B3"] })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", b3Balance?.balanceUsdFormatted || "0.00"] }), _jsx("div", { className: "flex items-center gap-1", children: b3Balance?.priceChange24h !== null && b3Balance?.priceChange24h !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Triangle, { className: `size-3 ${b3Balance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), _jsxs("span", { className: `font-neue-montreal-medium text-sm ${b3Balance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [b3Balance.priceChange24h >= 0 ? "+" : "", b3Balance.priceChange24h.toFixed(2), "%"] })] })) : (_jsx("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: _jsx("img", { src: "https://cdn.b3.fun/ethereum.svg", alt: "ETH", className: "size-10" }) }), _jsxs("div", { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "Ethereum" }) }), _jsxs("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [nativeBalance?.formattedTotal || "0.00", " ETH"] })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", nativeBalance?.formattedTotalUsd || "0.00"] }), _jsx("div", { className: "flex items-center gap-2", children: nativeBalance?.priceChange24h !== null && nativeBalance?.priceChange24h !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Triangle, { className: `size-3 ${nativeBalance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), _jsxs("span", { className: `font-neue-montreal-medium text-sm ${nativeBalance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [nativeBalance.priceChange24h >= 0 ? "+" : "", nativeBalance.priceChange24h.toFixed(2), "%"] })] })) : (_jsx("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] })] }), eoaAddress && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("h3", { className: "text-b3-grey font-neue-montreal-semibold", children: ["Connected ", eoaInfo?.data?.name || "Wallet"] }), _jsxs("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [_jsx("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(eoaAddress, 6) }), _jsx(CopyToClipboard, { text: eoaAddress })] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: _jsx("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", alt: "B3", className: "size-10" }) }), _jsxs("div", { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "B3" }) }), _jsxs("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [eoaB3Balance?.formattedTotal || "0.00", " B3"] })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", eoaB3Balance?.balanceUsdFormatted || "0.00"] }), _jsx("div", { className: "flex items-center gap-1", children: eoaB3Balance?.priceChange24h !== null && eoaB3Balance?.priceChange24h !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Triangle, { className: `size-3 ${eoaB3Balance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), _jsxs("span", { className: `font-neue-montreal-medium text-sm ${eoaB3Balance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [eoaB3Balance.priceChange24h >= 0 ? "+" : "", eoaB3Balance.priceChange24h.toFixed(2), "%"] })] })) : (_jsx("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: _jsx("img", { src: "https://cdn.b3.fun/ethereum.svg", alt: "ETH", className: "size-10" }) }), _jsxs("div", { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "Ethereum" }) }), _jsxs("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [eoaNativeBalance?.formattedTotal || "0.00", " ETH"] })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", eoaNativeBalance?.formattedTotalUsd || "0.00"] }), _jsx("div", { className: "flex items-center gap-2", children: eoaNativeBalance?.priceChange24h !== null && eoaNativeBalance?.priceChange24h !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Triangle, { className: `size-3 ${eoaNativeBalance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), _jsxs("span", { className: `font-neue-montreal-medium text-sm ${eoaNativeBalance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [eoaNativeBalance.priceChange24h >= 0 ? "+" : "", eoaNativeBalance.priceChange24h.toFixed(2), "%"] })] })) : (_jsx("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] })] })), _jsxs("div", { className: "border-b3-line flex items-center justify-between rounded-2xl border p-4", children: [_jsxs("div", { className: "", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4" }), _jsx("h3", { className: "font-neue-montreal-semibold text-b3-grey", children: "Global Account" })] }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium mt-2 text-sm", children: "Your universal account for all B3 apps" })] }), _jsx("button", { className: "text-b3-grey hover:text-b3-grey/80 hover:bg-b3-line border-b3-line flex size-12 items-center justify-center rounded-full border", onClick: onLogoutEnhanced, children: logoutLoading ? _jsx(Loader2, { className: "animate-spin" }) : _jsx(SignOutIcon, { size: 16, className: "text-b3-grey" }) })] })] }));
82
- };
83
49
  const AppsContent = () => (_jsxs("div", { className: "space-y-4", children: [signers?.map((signer) => (_jsx("div", { className: "rounded-xl border border-gray-200 p-4 dark:border-gray-800", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800", children: _jsx("span", { className: "text-xs font-medium text-gray-600 dark:text-gray-400", children: "App" }) }), _jsxs("div", { children: [_jsx("h3", { className: "font-medium text-gray-900 dark:text-white", children: signer.partner.name }), _jsxs("div", { className: "mt-2 space-y-1", children: [_jsxs("p", { className: "text-xs text-gray-500", children: ["Added ", new Date(signer.createdAt).toLocaleDateString()] }), _jsxs("p", { className: "text-xs text-gray-500", children: ["Expires ", new Date(Number(signer.endTimestamp) * 1000).toLocaleDateString()] }), _jsxs("p", { className: "text-xs text-gray-500", children: ["Max spend: ", formatNumber(Number(formatUnits(signer.nativeTokenLimitPerTransaction, 18))), " ETH"] })] })] })] }), _jsx(Button, { variant: "outline", size: "sm", className: "border-red-200 text-red-500 hover:border-red-300 hover:text-red-600", onClick: () => handleRevoke(signer), disabled: revokingSignerId === signer.id, children: revokingSignerId === signer.id ? "Revoking..." : "Revoke" })] }) }, signer.id))), !signers?.length && _jsx("div", { className: "py-12 text-center text-gray-500", children: "No connected apps" })] }));
84
50
  const SettingsContent = () => {
85
51
  const [unlinkingAccountId, setUnlinkingAccountId] = useState(null);
@@ -129,5 +95,5 @@ export function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit
129
95
  if (["overview", "tokens", "nfts", "apps", "settings"].includes(tab)) {
130
96
  setActiveTab?.(tab);
131
97
  }
132
- }, children: [_jsx("div", { className: "px-4", children: _jsxs(TabsListPrimitive, { className: "grid h-auto grid-cols-2 grid-rows-2 gap-3 rounded-none border-none bg-transparent", children: [_jsxs(TabTriggerPrimitive, { value: "overview", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(BarChart3, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Overview" })] }), _jsxs(TabTriggerPrimitive, { value: "tokens", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Coins, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Tokens" })] }), _jsxs(TabTriggerPrimitive, { value: "nfts", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Image, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "NFTs" })] }), _jsxs(TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Settings, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Settings" })] })] }) }), _jsx(TabsContentPrimitive, { value: "overview", className: "px-4 pb-4 pt-2", children: _jsx(BalanceContent, {}) }), _jsx(TabsContentPrimitive, { value: "tokens", className: "px-4 pb-4 pt-2", children: _jsx(ContentTokens, { activeTab: activeTab }) }), _jsx(TabsContentPrimitive, { value: "nfts", className: "px-4 pb-4 pt-2", children: _jsx("div", { className: "grid grid-cols-3 gap-4", children: nfts?.nftResponse ? (_jsx(AccountAssets, { nfts: nfts.nftResponse, isLoading: isLoading })) : (_jsx("div", { className: "col-span-3 py-12 text-center text-gray-500", children: "No NFTs found" })) }) }), _jsx(TabsContentPrimitive, { value: "apps", className: "px-4 pb-4 pt-2", children: _jsx(AppsContent, {}) }), _jsx(TabsContentPrimitive, { value: "settings", className: "px-4 pb-4 pt-2", children: _jsx(SettingsContent, {}) })] }) }) }));
98
+ }, children: [_jsx("div", { className: "px-4", children: _jsxs(TabsListPrimitive, { className: "grid h-auto grid-cols-2 grid-rows-2 gap-3 rounded-none border-none bg-transparent", children: [_jsxs(TabTriggerPrimitive, { value: "overview", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(BarChart3, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Overview" })] }), _jsxs(TabTriggerPrimitive, { value: "tokens", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Coins, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Tokens" })] }), _jsxs(TabTriggerPrimitive, { value: "nfts", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Image, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "NFTs" })] }), _jsxs(TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [_jsx(Settings, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Settings" })] })] }) }), _jsx(TabsContentPrimitive, { value: "overview", className: "px-4 pb-4 pt-2", children: _jsx(BalanceContent, { onLogout: onLogout, partnerId: partnerId }) }), _jsx(TabsContentPrimitive, { value: "tokens", className: "px-4 pb-4 pt-2", children: _jsx(ContentTokens, { activeTab: activeTab }) }), _jsx(TabsContentPrimitive, { value: "nfts", className: "px-4 pb-4 pt-2", children: _jsx("div", { className: "grid grid-cols-3 gap-4", children: nfts?.nftResponse ? (_jsx(AccountAssets, { nfts: nfts.nftResponse, isLoading: isLoading })) : (_jsx("div", { className: "col-span-3 py-12 text-center text-gray-500", children: "No NFTs found" })) }) }), _jsx(TabsContentPrimitive, { value: "apps", className: "px-4 pb-4 pt-2", children: _jsx(AppsContent, {}) }), _jsx(TabsContentPrimitive, { value: "settings", className: "px-4 pb-4 pt-2", children: _jsx(SettingsContent, {}) })] }) }) }));
133
99
  }
@@ -0,0 +1,10 @@
1
+ import { ReactNode } from "react";
2
+ interface TokenBalanceRowProps {
3
+ icon: ReactNode;
4
+ name: string;
5
+ balance: string;
6
+ usdValue: string;
7
+ priceChange?: number | null;
8
+ }
9
+ export declare function TokenBalanceRow({ icon, name, balance, usdValue, priceChange }: TokenBalanceRowProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Triangle } from "lucide-react";
3
+ export function TokenBalanceRow({ icon, name, balance, usdValue, priceChange }) {
4
+ return (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: icon }), _jsxs("div", { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold", children: name }) }), _jsx("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: balance })] })] }), _jsxs("div", { className: "text-right", children: [_jsxs("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", usdValue] }), _jsx("div", { className: "flex items-center gap-1", children: priceChange !== null && priceChange !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Triangle, { className: `size-3 ${priceChange >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), _jsxs("span", { className: `font-neue-montreal-medium text-sm ${priceChange >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [priceChange >= 0 ? "+" : "", priceChange.toFixed(2), "%"] })] })) : (_jsx("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }));
5
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ interface TokenIconProps {
3
+ src: string;
4
+ alt: string;
5
+ className?: string;
6
+ size?: number;
7
+ }
8
+ export declare const TokenIcon: React.FC<TokenIconProps>;
9
+ export declare const B3TokenIcon: React.FC<Omit<TokenIconProps, "src" | "alt">>;
10
+ export declare const EthereumTokenIcon: React.FC<Omit<TokenIconProps, "src" | "alt">>;
11
+ export {};
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../../shared/utils/index.js";
3
+ import { useCallback, useMemo, useState } from "react";
4
+ // Create a global image cache to prevent re-loading
5
+ const imageCache = new Map();
6
+ export const TokenIcon = ({ src, alt, className, size = 40 }) => {
7
+ const [isLoaded, setIsLoaded] = useState(() => imageCache.get(src) || false);
8
+ const [hasError, setHasError] = useState(false);
9
+ const handleLoad = useCallback(() => {
10
+ imageCache.set(src, true);
11
+ setIsLoaded(true);
12
+ }, [src]);
13
+ const handleError = useCallback(() => {
14
+ setHasError(true);
15
+ }, []);
16
+ // Memoize the image element to prevent unnecessary re-renders
17
+ const imageElement = useMemo(() => (_jsx("img", { src: src, alt: alt, className: cn("transition-opacity duration-200", className, {
18
+ "opacity-100": isLoaded && !hasError,
19
+ "opacity-0": !isLoaded || hasError,
20
+ }), onLoad: handleLoad, onError: handleError, loading: "eager" // Load immediately since these are critical UI elements
21
+ , decoding: "async", style: {
22
+ width: size,
23
+ height: size,
24
+ } })), [src, alt, className, isLoaded, hasError, handleLoad, handleError, size]);
25
+ // Show a placeholder while loading or if there's an error
26
+ const placeholder = useMemo(() => (_jsx("div", { className: cn("bg-b3-primary-wash flex items-center justify-center rounded-full transition-opacity duration-200", {
27
+ "opacity-0": isLoaded && !hasError,
28
+ "opacity-100": !isLoaded || hasError,
29
+ }), style: {
30
+ width: size,
31
+ height: size,
32
+ }, children: _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: alt.charAt(0).toUpperCase() }) })), [alt, isLoaded, hasError, size]);
33
+ return (_jsxs("div", { className: "relative inline-block", style: { width: size, height: size }, children: [placeholder, _jsx("div", { className: "absolute inset-0", children: imageElement })] }));
34
+ };
35
+ // Pre-defined token icons for common tokens
36
+ export const B3TokenIcon = props => (_jsx(TokenIcon, { src: "https://cdn.b3.fun/b3-coin-3d.png", alt: "B3", ...props }));
37
+ export const EthereumTokenIcon = props => (_jsx(TokenIcon, { src: "https://cdn.b3.fun/ethereum.svg", alt: "ETH", ...props }));
@@ -0,0 +1,7 @@
1
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
2
+ import * as React from "react";
3
+ declare const Accordion: React.ForwardRefExoticComponent<(AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps) & React.RefAttributes<HTMLDivElement>>;
4
+ declare const AccordionItem: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+ declare const AccordionTrigger: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const AccordionContent: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
4
+ import { ChevronDown } from "lucide-react";
5
+ import * as React from "react";
6
+ import { cn } from "../../../../shared/utils/index.js";
7
+ const Accordion = AccordionPrimitive.Root;
8
+ const AccordionItem = React.forwardRef(({ className, ...props }, ref) => (_jsx(AccordionPrimitive.Item, { ref: ref, className: cn("border-b3-line border-b", className), ...props })));
9
+ AccordionItem.displayName = "AccordionItem";
10
+ const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => (_jsx(AccordionPrimitive.Header, { className: "flex", children: _jsxs(AccordionPrimitive.Trigger, { ref: ref, className: cn("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", className), ...props, children: [children, _jsx(ChevronDown, { className: "h-4 w-4 shrink-0 transition-transform duration-200" })] }) })));
11
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
12
+ const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsx(AccordionPrimitive.Content, { ref: ref, className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm transition-all", ...props, children: _jsx("div", { className: cn("pb-4 pt-0", className), children: children }) })));
13
+ AccordionContent.displayName = AccordionPrimitive.Content.displayName;
14
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -12,7 +12,7 @@ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(D
12
12
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
13
13
  const DialogContent = React.forwardRef(({ className, children, hideCloseButton = false, closeBtnClassName, ...props }, ref) => {
14
14
  const container = typeof window !== "undefined" ? document.getElementById("b3-root") : null;
15
- return (_jsxs(DialogPortal, { container: container, children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("bg-b3-react-background fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border p-6 shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: cn("data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [_jsx(X, { className: "h-5 w-5" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
15
+ return (_jsxs(DialogPortal, { container: container, children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("bg-b3-react-background fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border p-6 shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: cn("modal-close-button data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [_jsx(X, { className: "h-5 w-5" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
16
16
  });
17
17
  DialogContent.displayName = DialogPrimitive.Content.displayName;
18
18
  const DialogHeader = ({ className, ...props }) => (_jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props }));
@@ -9,6 +9,7 @@ import { prepareTransaction, sendTransaction as twSendTransaction } from "thirdw
9
9
  import { useSwitchChain, useWalletClient } from "wagmi";
10
10
  import { useB3 } from "../components/index.js";
11
11
  import { useAccountWallet } from "./useAccountWallet.js";
12
+ import { isAddress } from "viem";
12
13
  const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
13
14
  process.env.NEXT_PUBLIC_THIRDWEB_PARTNER_ID ||
14
15
  process.env.PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID ||
@@ -39,6 +40,7 @@ export function useUnifiedChainSwitchAndExecute() {
39
40
  if (!targetChain) {
40
41
  throw new Error(`Chain ${targetChainId} is not supported`);
41
42
  }
43
+ invariant(isAddress(params.to), "params.to is not a valid address");
42
44
  const hash = await walletClient.sendTransaction({
43
45
  account: signer,
44
46
  chain: targetChain,
@@ -1,3 +1,9 @@
1
+ declare global {
2
+ interface Window {
3
+ gtag: (...args: any[]) => void;
4
+ dataLayer: any[];
5
+ }
6
+ }
1
7
  /**
2
8
  * Load Google Analytics 4 script and initialize
3
9
  */
@@ -1,3 +1,4 @@
1
+ // Global window interface augmentations for B3 SDK
1
2
  const GA4_MEASUREMENT_ID = "G-VER9DKJH87";
2
3
  /**
3
4
  * Initialize Google Analytics 4