@b3dotfun/sdk 0.0.58 → 0.0.59-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 (47) hide show
  1. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +4 -0
  2. package/dist/cjs/anyspend/utils/accountStore.d.ts +7 -0
  3. package/dist/cjs/anyspend/utils/accountStore.js +8 -0
  4. package/dist/cjs/anyspend/utils/index.d.ts +1 -0
  5. package/dist/cjs/anyspend/utils/index.js +1 -0
  6. package/dist/cjs/global-account/react/components/B3DynamicModal.js +17 -0
  7. package/dist/cjs/global-account/react/hooks/useWagmiConfig.d.ts +441 -1
  8. package/dist/cjs/global-account/react/hooks/useWagmiConfig.js +2 -0
  9. package/dist/cjs/shared/react/components/CurrencySelector.js +8 -3
  10. package/dist/cjs/shared/react/components/FormattedCurrency.d.ts +3 -3
  11. package/dist/cjs/shared/react/components/FormattedCurrency.js +31 -26
  12. package/dist/cjs/shared/react/hooks/useCurrencyConversion.d.ts +8 -5
  13. package/dist/cjs/shared/react/hooks/useCurrencyConversion.js +153 -94
  14. package/dist/cjs/shared/react/stores/currencyStore.d.ts +83 -8
  15. package/dist/cjs/shared/react/stores/currencyStore.js +147 -5
  16. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +5 -1
  17. package/dist/esm/anyspend/utils/accountStore.d.ts +7 -0
  18. package/dist/esm/anyspend/utils/accountStore.js +5 -0
  19. package/dist/esm/anyspend/utils/index.d.ts +1 -0
  20. package/dist/esm/anyspend/utils/index.js +1 -0
  21. package/dist/esm/global-account/react/components/B3DynamicModal.js +17 -0
  22. package/dist/esm/global-account/react/hooks/useWagmiConfig.d.ts +441 -1
  23. package/dist/esm/global-account/react/hooks/useWagmiConfig.js +2 -0
  24. package/dist/esm/shared/react/components/CurrencySelector.js +10 -5
  25. package/dist/esm/shared/react/components/FormattedCurrency.d.ts +3 -3
  26. package/dist/esm/shared/react/components/FormattedCurrency.js +31 -26
  27. package/dist/esm/shared/react/hooks/useCurrencyConversion.d.ts +8 -5
  28. package/dist/esm/shared/react/hooks/useCurrencyConversion.js +154 -95
  29. package/dist/esm/shared/react/stores/currencyStore.d.ts +83 -8
  30. package/dist/esm/shared/react/stores/currencyStore.js +143 -5
  31. package/dist/types/anyspend/utils/accountStore.d.ts +7 -0
  32. package/dist/types/anyspend/utils/index.d.ts +1 -0
  33. package/dist/types/global-account/react/hooks/useWagmiConfig.d.ts +441 -1
  34. package/dist/types/shared/react/components/FormattedCurrency.d.ts +3 -3
  35. package/dist/types/shared/react/hooks/useCurrencyConversion.d.ts +8 -5
  36. package/dist/types/shared/react/stores/currencyStore.d.ts +83 -8
  37. package/package.json +4 -3
  38. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +6 -2
  39. package/src/anyspend/utils/accountStore.ts +12 -0
  40. package/src/anyspend/utils/index.ts +1 -0
  41. package/src/global-account/react/components/B3DynamicModal.tsx +20 -0
  42. package/src/global-account/react/hooks/useWagmiConfig.tsx +2 -0
  43. package/src/shared/react/components/CurrencySelector.tsx +36 -5
  44. package/src/shared/react/components/FormattedCurrency.tsx +36 -30
  45. package/src/shared/react/hooks/__tests__/useCurrencyConversion.test.ts +14 -14
  46. package/src/shared/react/hooks/useCurrencyConversion.ts +163 -96
  47. package/src/shared/react/stores/currencyStore.ts +216 -10
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCurrencyStore = exports.CURRENCY_NAMES = exports.CURRENCY_SYMBOLS = void 0;
4
+ exports.getCurrencySymbol = getCurrencySymbol;
5
+ exports.getCurrencyName = getCurrencyName;
6
+ exports.getCurrencyMetadata = getCurrencyMetadata;
7
+ exports.getCurrencyDecimalPlaces = getCurrencyDecimalPlaces;
4
8
  const zustand_1 = require("zustand");
5
9
  const middleware_1 = require("zustand/middleware");
6
10
  /**
@@ -38,20 +42,158 @@ exports.CURRENCY_NAMES = {
38
42
  /**
39
43
  * Zustand store for managing currency selection and conversion.
40
44
  * Persists user's selected currency preference in localStorage.
45
+ * Supports dynamic currency registration and custom exchange rates.
41
46
  *
42
47
  * @example
43
48
  * ```tsx
44
- * const { selectedCurrency, setSelectedCurrency } = useCurrencyStore();
45
- * // Change display currency to USD
46
- * setSelectedCurrency('USD');
49
+ * const { selectedCurrency, setSelectedCurrency, addCurrency, setExchangeRate } = useCurrencyStore();
50
+ *
51
+ * // Add a new currency
52
+ * addCurrency({
53
+ * code: "BTC",
54
+ * symbol: "₿",
55
+ * name: "Bitcoin",
56
+ * showSubscripts: true,
57
+ * });
58
+ *
59
+ * // Set exchange rate: 1 BTC = 50000 USD
60
+ * setExchangeRate("BTC", "USD", 50000);
61
+ *
62
+ * // Change display currency
63
+ * setSelectedCurrency('BTC');
47
64
  * ```
48
65
  */
49
- exports.useCurrencyStore = (0, zustand_1.create)()((0, middleware_1.persist)(set => ({
66
+ exports.useCurrencyStore = (0, zustand_1.create)()((0, middleware_1.persist)((set, get) => ({
50
67
  selectedCurrency: "B3",
51
68
  baseCurrency: "B3",
69
+ customCurrencies: {},
70
+ customExchangeRates: {},
52
71
  setSelectedCurrency: currency => set({ selectedCurrency: currency }),
53
72
  setBaseCurrency: currency => set({ baseCurrency: currency }),
73
+ addCurrency: metadata => {
74
+ set(state => ({
75
+ customCurrencies: {
76
+ ...state.customCurrencies,
77
+ [metadata.code]: metadata,
78
+ },
79
+ }));
80
+ },
81
+ removeCurrency: code => {
82
+ set(state => {
83
+ // Remove the currency
84
+ const { [code]: _removed, ...remaining } = state.customCurrencies;
85
+ // Remove all exchange rates involving this currency
86
+ const filteredRates = {};
87
+ for (const [key, rate] of Object.entries(state.customExchangeRates)) {
88
+ // Key format is "FROM-TO", skip if either matches the removed code
89
+ const [from, to] = key.split("-");
90
+ if (from !== code && to !== code) {
91
+ filteredRates[key] = rate;
92
+ }
93
+ }
94
+ return {
95
+ customCurrencies: remaining,
96
+ customExchangeRates: filteredRates,
97
+ };
98
+ });
99
+ },
100
+ setExchangeRate: (from, to, rate) => {
101
+ set(state => {
102
+ const key = `${from}-${to}`;
103
+ const inverseKey = `${to}-${from}`;
104
+ // Only set inverse rate if rate is not 0 (to avoid Infinity)
105
+ const newRates = {
106
+ ...state.customExchangeRates,
107
+ [key]: rate,
108
+ };
109
+ if (rate !== 0) {
110
+ newRates[inverseKey] = 1 / rate;
111
+ }
112
+ return {
113
+ customExchangeRates: newRates,
114
+ };
115
+ });
116
+ },
117
+ getExchangeRate: (from, to) => {
118
+ const key = `${from}-${to}`;
119
+ return get().customExchangeRates[key];
120
+ },
121
+ getAllCurrencies: () => {
122
+ const builtIn = Object.keys(exports.CURRENCY_SYMBOLS);
123
+ const custom = Object.keys(get().customCurrencies);
124
+ return [...builtIn, ...custom];
125
+ },
54
126
  }), {
55
127
  name: "currency-storage",
56
- version: 2,
128
+ version: 3,
57
129
  }));
130
+ /**
131
+ * Get the symbol for any currency (built-in or custom).
132
+ */
133
+ function getCurrencySymbol(currency) {
134
+ // Check built-in currencies first
135
+ if (currency in exports.CURRENCY_SYMBOLS) {
136
+ return exports.CURRENCY_SYMBOLS[currency];
137
+ }
138
+ // Check custom currencies
139
+ const customCurrencies = exports.useCurrencyStore.getState().customCurrencies;
140
+ const customCurrency = customCurrencies[currency];
141
+ if (customCurrency) {
142
+ return customCurrency.symbol;
143
+ }
144
+ // Fallback to currency code
145
+ return currency;
146
+ }
147
+ /**
148
+ * Get the name for any currency (built-in or custom).
149
+ */
150
+ function getCurrencyName(currency) {
151
+ // Check built-in currencies first
152
+ if (currency in exports.CURRENCY_NAMES) {
153
+ return exports.CURRENCY_NAMES[currency];
154
+ }
155
+ // Check custom currencies
156
+ const customCurrencies = exports.useCurrencyStore.getState().customCurrencies;
157
+ const customCurrency = customCurrencies[currency];
158
+ if (customCurrency) {
159
+ return customCurrency.name;
160
+ }
161
+ // Fallback to currency code
162
+ return currency;
163
+ }
164
+ /**
165
+ * Get metadata for a custom currency.
166
+ */
167
+ function getCurrencyMetadata(currency) {
168
+ const customCurrencies = exports.useCurrencyStore.getState().customCurrencies;
169
+ return customCurrencies[currency];
170
+ }
171
+ /**
172
+ * Get the number of decimal places for a currency (for converting from smallest unit).
173
+ * Used when parsing amounts from wei/smallest unit format.
174
+ *
175
+ * @param currency - Currency code
176
+ * @returns Number of decimal places (e.g., 18 for ETH/wei, 2 for USD cents, 0 for JPY)
177
+ */
178
+ function getCurrencyDecimalPlaces(currency) {
179
+ // Check custom currencies first
180
+ const customCurrencies = exports.useCurrencyStore.getState().customCurrencies;
181
+ const customMetadata = customCurrencies[currency];
182
+ if (customMetadata?.decimals !== undefined) {
183
+ return customMetadata.decimals;
184
+ }
185
+ // Built-in currencies with 18 decimals (wei-like)
186
+ if (currency === "WIN" || currency === "ETH" || currency === "SOL" || currency === "B3") {
187
+ return 18;
188
+ }
189
+ // Fiat currencies with cent-like decimals
190
+ if (currency === "USD" || currency === "EUR" || currency === "GBP" || currency === "CAD" || currency === "AUD") {
191
+ return 2;
192
+ }
193
+ // Currencies without fractional units
194
+ if (currency === "JPY" || currency === "KRW") {
195
+ return 0;
196
+ }
197
+ // Default to 18 decimals (wei-like)
198
+ return 18;
199
+ }
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useGlobalWalletState } from "../../../../anyspend/utils/index.js";
3
4
  import { useAccountWallet } from "../../../../global-account/react/index.js";
4
5
  import { cn } from "../../../../shared/utils/cn.js";
5
6
  import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
@@ -9,7 +10,7 @@ import { ChevronLeft, ChevronRightCircle, Wallet, X, ZapIcon } from "lucide-reac
9
10
  import { useState } from "react";
10
11
  import { createPortal } from "react-dom";
11
12
  import { toast } from "sonner";
12
- import { useSetActiveWallet, useWalletInfo } from "thirdweb/react";
13
+ import { useActiveWallet, useSetActiveWallet, useWalletInfo } from "thirdweb/react";
13
14
  import { createWallet } from "thirdweb/wallets";
14
15
  import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
15
16
  export var CryptoPaymentMethodType;
@@ -28,6 +29,8 @@ export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentM
28
29
  const [showWalletModal, setShowWalletModal] = useState(false);
29
30
  const setActiveWallet = useSetActiveWallet();
30
31
  const { data: eoaWalletInfo } = useWalletInfo(connectedEOAWallet?.id);
32
+ const activeWallet = useActiveWallet();
33
+ const setGlobalAccountWallet = useGlobalWalletState(state => state.setGlobalAccountWallet);
31
34
  const isConnected = !!connectedEOAWallet;
32
35
  const globalAddress = connectedSmartWallet?.getAccount()?.address;
33
36
  // Helper function to check if two addresses are the same
@@ -169,6 +172,7 @@ export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentM
169
172
  return (_jsxs("div", { className: "crypto-payment-method mx-auto h-fit w-[460px] max-w-full", children: [_jsxs("div", { className: cn("relative flex flex-col gap-10"), children: [_jsx("button", { onClick: onBack, className: "text-as-quaternary hover:text-as-primary absolute flex h-8 w-8 items-center justify-center rounded-lg transition-colors", children: _jsx(ChevronLeft, { className: "h-6 w-6" }) }), _jsx("div", { className: "flex items-center justify-around gap-4", children: _jsx("div", { className: "flex-1 text-center", children: _jsx("h2", { className: "text-as-primary text-lg font-semibold", children: "Select a payment method" }) }) }), _jsxs("div", { className: "crypto-payment-methods flex flex-col gap-4", children: [(shouldShowConnectedEOA || shouldShowWagmiWallet || globalAddress) && (_jsxs("div", { className: "installed-wallets", children: [_jsx("h3", { className: "text-as-primary/80 mb-3 text-sm font-medium", children: "Connected wallets" }), _jsxs("div", { className: "space-y-2", children: [shouldShowConnectedEOA && (_jsx("button", { onClick: () => {
170
173
  setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
171
174
  onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
175
+ setGlobalAccountWallet(activeWallet);
172
176
  setActiveWallet(connectedEOAWallet);
173
177
  toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
174
178
  }, className: cn("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
@@ -0,0 +1,7 @@
1
+ import type { Wallet } from "thirdweb/wallets";
2
+ interface GlobalWalletState {
3
+ globalAccountWallet?: Wallet;
4
+ setGlobalAccountWallet: (account?: Wallet) => void;
5
+ }
6
+ export declare const useGlobalWalletState: import("zustand").UseBoundStore<import("zustand").StoreApi<GlobalWalletState>>;
7
+ export {};
@@ -0,0 +1,5 @@
1
+ import { create } from "zustand";
2
+ export const useGlobalWalletState = create(set => ({
3
+ globalAccountWallet: undefined,
4
+ setGlobalAccountWallet: account => set({ globalAccountWallet: account }),
5
+ }));
@@ -1,3 +1,4 @@
1
+ export * from "./accountStore";
1
2
  export * from "./address";
2
3
  export * from "./chain";
3
4
  export * from "./format";
@@ -1,3 +1,4 @@
1
+ export * from "./accountStore.js";
1
2
  export * from "./address.js";
2
3
  export * from "./chain.js";
3
4
  export * from "./format.js";
@@ -2,9 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
3
3
  import { AnySpendDepositHype } from "../../../anyspend/react/components/AnyspendDepositHype.js";
4
4
  import { AnySpendStakeUpside } from "../../../anyspend/react/components/AnySpendStakeUpside.js";
5
+ import { useGlobalWalletState } from "../../../anyspend/utils/index.js";
5
6
  import { useIsMobile, useModalStore } from "../../../global-account/react/index.js";
6
7
  import { cn } from "../../../shared/utils/cn.js";
7
8
  import { debugB3React } from "../../../shared/utils/debug.js";
9
+ import { useEffect, useRef } from "react";
8
10
  import { AvatarEditor } from "./AvatarEditor/AvatarEditor.js";
9
11
  import { useB3 } from "./B3Provider/useB3.js";
10
12
  import { LinkAccount } from "./LinkAccount/LinkAccount.js";
@@ -13,11 +15,26 @@ import { RequestPermissions } from "./RequestPermissions/RequestPermissions.js";
13
15
  import { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow.js";
14
16
  import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./ui/dialog.js";
15
17
  import { Drawer, DrawerContent, DrawerDescription, DrawerTitle } from "./ui/drawer.js";
18
+ import { useSetActiveWallet } from "thirdweb/react";
16
19
  const debug = debugB3React("B3DynamicModal");
17
20
  export function B3DynamicModal() {
18
21
  const { isOpen, setB3ModalOpen, contentType, history, navigateBack } = useModalStore();
19
22
  const { theme } = useB3();
20
23
  const isMobile = useIsMobile();
24
+ const prevIsOpenRef = useRef(isOpen);
25
+ const globalAccountWallet = useGlobalWalletState(state => state.globalAccountWallet);
26
+ const setGlobalAccountWallet = useGlobalWalletState(state => state.setGlobalAccountWallet);
27
+ const setActiveWallet = useSetActiveWallet();
28
+ // anyspend cleanup global account chnages by setting account back
29
+ useEffect(() => {
30
+ if (prevIsOpenRef.current && !isOpen) {
31
+ if (globalAccountWallet) {
32
+ setActiveWallet(globalAccountWallet);
33
+ setGlobalAccountWallet(undefined);
34
+ }
35
+ }
36
+ prevIsOpenRef.current = isOpen;
37
+ }, [isOpen, globalAccountWallet, setActiveWallet, setGlobalAccountWallet]);
21
38
  // Define arrays for different modal type groups
22
39
  const fullWidthTypes = [
23
40
  "anySpend",