@b3dotfun/sdk 0.0.42-alpha.1 → 0.0.42-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/AnySpend.js +2 -2
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +2 -2
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +5 -3
- package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +1 -1
- package/dist/cjs/global-account/react/components/index.d.ts +8 -7
- package/dist/cjs/global-account/react/components/index.js +29 -23
- package/dist/cjs/global-account/react/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/cjs/global-account/react/components/ui/dropdown-menu.js +100 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/cjs/shared/constants/currency.d.ts +1 -0
- package/dist/cjs/shared/constants/currency.js +5 -0
- package/dist/cjs/shared/constants/index.d.ts +1 -0
- package/dist/cjs/shared/constants/index.js +15 -0
- package/dist/cjs/shared/react/components/CurrencySelector.d.ts +7 -0
- package/dist/cjs/shared/react/components/CurrencySelector.js +14 -0
- package/dist/cjs/shared/react/components/FormattedCurrency.d.ts +12 -0
- package/dist/cjs/shared/react/components/FormattedCurrency.js +60 -0
- package/dist/cjs/shared/react/components/index.d.ts +2 -0
- package/dist/cjs/shared/react/components/index.js +18 -0
- package/dist/cjs/shared/react/hooks/__tests__/useCurrencyConversion.test.d.ts +1 -0
- package/dist/cjs/shared/react/hooks/__tests__/useCurrencyConversion.test.js +245 -0
- package/dist/cjs/shared/react/hooks/index.d.ts +1 -0
- package/dist/cjs/shared/react/hooks/index.js +1 -0
- package/dist/cjs/shared/react/hooks/useCurrencyConversion.d.ts +35 -0
- package/dist/cjs/shared/react/hooks/useCurrencyConversion.js +200 -0
- package/dist/cjs/shared/react/index.d.ts +2 -0
- package/dist/cjs/shared/react/index.js +2 -0
- package/dist/cjs/shared/react/stores/currencyModalStore.d.ts +7 -0
- package/dist/cjs/shared/react/stores/currencyModalStore.js +9 -0
- package/dist/cjs/shared/react/stores/currencyStore.d.ts +51 -0
- package/dist/cjs/shared/react/stores/currencyStore.js +57 -0
- package/dist/cjs/shared/react/stores/index.d.ts +2 -0
- package/dist/cjs/shared/react/stores/index.js +18 -0
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +1 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +2 -2
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +1 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +2 -2
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +5 -3
- package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +1 -1
- package/dist/esm/global-account/react/components/index.d.ts +8 -7
- package/dist/esm/global-account/react/components/index.js +8 -7
- package/dist/esm/global-account/react/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/esm/global-account/react/components/ui/dropdown-menu.js +60 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/esm/shared/constants/currency.d.ts +1 -0
- package/dist/esm/shared/constants/currency.js +2 -0
- package/dist/esm/shared/constants/index.d.ts +1 -0
- package/dist/esm/shared/constants/index.js +1 -0
- package/dist/esm/shared/react/components/CurrencySelector.d.ts +7 -0
- package/dist/esm/shared/react/components/CurrencySelector.js +11 -0
- package/dist/esm/shared/react/components/FormattedCurrency.d.ts +12 -0
- package/dist/esm/shared/react/components/FormattedCurrency.js +57 -0
- package/dist/esm/shared/react/components/index.d.ts +2 -0
- package/dist/esm/shared/react/components/index.js +2 -0
- package/dist/esm/shared/react/hooks/__tests__/useCurrencyConversion.test.d.ts +1 -0
- package/dist/esm/shared/react/hooks/__tests__/useCurrencyConversion.test.js +243 -0
- package/dist/esm/shared/react/hooks/index.d.ts +1 -0
- package/dist/esm/shared/react/hooks/index.js +1 -0
- package/dist/esm/shared/react/hooks/useCurrencyConversion.d.ts +35 -0
- package/dist/esm/shared/react/hooks/useCurrencyConversion.js +197 -0
- package/dist/esm/shared/react/index.d.ts +2 -0
- package/dist/esm/shared/react/index.js +2 -0
- package/dist/esm/shared/react/stores/currencyModalStore.d.ts +7 -0
- package/dist/esm/shared/react/stores/currencyModalStore.js +6 -0
- package/dist/esm/shared/react/stores/currencyStore.d.ts +51 -0
- package/dist/esm/shared/react/stores/currencyStore.js +54 -0
- package/dist/esm/shared/react/stores/index.d.ts +2 -0
- package/dist/esm/shared/react/stores/index.js +2 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnySpend.d.ts +1 -0
- package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +1 -0
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/types/global-account/react/components/index.d.ts +8 -7
- package/dist/types/global-account/react/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/types/shared/constants/currency.d.ts +1 -0
- package/dist/types/shared/constants/index.d.ts +1 -0
- package/dist/types/shared/react/components/CurrencySelector.d.ts +7 -0
- package/dist/types/shared/react/components/FormattedCurrency.d.ts +12 -0
- package/dist/types/shared/react/components/index.d.ts +2 -0
- package/dist/types/shared/react/hooks/__tests__/useCurrencyConversion.test.d.ts +1 -0
- package/dist/types/shared/react/hooks/index.d.ts +1 -0
- package/dist/types/shared/react/hooks/useCurrencyConversion.d.ts +35 -0
- package/dist/types/shared/react/index.d.ts +2 -0
- package/dist/types/shared/react/stores/currencyModalStore.d.ts +7 -0
- package/dist/types/shared/react/stores/currencyStore.d.ts +51 -0
- package/dist/types/shared/react/stores/index.d.ts +2 -0
- package/package.json +29 -3
- package/src/anyspend/react/components/AnySpend.tsx +4 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +3 -0
- package/src/anyspend/react/components/common/PanelOnramp.tsx +19 -15
- package/src/global-account/react/components/SignInWithB3/SignIn.tsx +2 -7
- package/src/global-account/react/components/index.ts +19 -12
- package/src/global-account/react/components/ui/dropdown-menu.tsx +132 -0
- package/src/global-account/react/stores/useModalStore.ts +4 -0
- package/src/shared/constants/currency.ts +2 -0
- package/src/shared/constants/index.ts +2 -0
- package/src/shared/react/components/CurrencySelector.tsx +71 -0
- package/src/shared/react/components/FormattedCurrency.tsx +106 -0
- package/src/shared/react/components/index.ts +2 -0
- package/src/shared/react/hooks/__tests__/useCurrencyConversion.test.ts +308 -0
- package/src/shared/react/hooks/index.ts +1 -0
- package/src/shared/react/hooks/useCurrencyConversion.ts +211 -0
- package/src/shared/react/index.ts +2 -0
- package/src/shared/react/stores/currencyModalStore.ts +13 -0
- package/src/shared/react/stores/currencyStore.ts +82 -0
- package/src/shared/react/stores/index.ts +2 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for currency conversion and formatting with real-time exchange rates.
|
|
3
|
+
*
|
|
4
|
+
* This hook provides currency conversion functionality using live exchange rates
|
|
5
|
+
* and formats values according to currency-specific rules (decimals, symbols, etc.).
|
|
6
|
+
*
|
|
7
|
+
* @returns Currency conversion utilities and state
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function PriceDisplay({ amount }: { amount: number }) {
|
|
12
|
+
* const { formatCurrencyValue, selectedCurrency } = useCurrencyConversion();
|
|
13
|
+
* return <div>{formatCurrencyValue(amount)}</div>;
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useCurrencyConversion(): {
|
|
18
|
+
/** Currently selected display currency */
|
|
19
|
+
selectedCurrency: import("../stores/currencyStore").SupportedCurrency;
|
|
20
|
+
/** Base currency used for conversion (typically B3) */
|
|
21
|
+
baseCurrency: import("../stores/currencyStore").SupportedCurrency;
|
|
22
|
+
/** Current exchange rate from base to selected currency (undefined while loading) */
|
|
23
|
+
exchangeRate: number;
|
|
24
|
+
/** Format a value with currency conversion and proper symbol/decimal handling */
|
|
25
|
+
formatCurrencyValue: (value: number, options?: {
|
|
26
|
+
decimals?: number;
|
|
27
|
+
currency?: string;
|
|
28
|
+
}) => string;
|
|
29
|
+
/** Format a tooltip value showing alternate currency representation */
|
|
30
|
+
formatTooltipValue: (value: number, customCurrency?: string) => string;
|
|
31
|
+
/** Symbol for the currently selected currency (e.g., "$", "€", "ETH") */
|
|
32
|
+
selectedCurrencySymbol: string;
|
|
33
|
+
/** Symbol for the base currency */
|
|
34
|
+
baseCurrencySymbol: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported currencies for display and conversion.
|
|
3
|
+
* Includes fiat currencies (USD, EUR, GBP, JPY, CAD, AUD, KRW) and crypto (ETH, SOL, B3).
|
|
4
|
+
*/
|
|
5
|
+
export type SupportedCurrency = "ETH" | "USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD" | "B3" | "SOL" | "KRW";
|
|
6
|
+
/**
|
|
7
|
+
* Currency symbols used for display formatting.
|
|
8
|
+
* Prefix currencies (USD, EUR, GBP, CAD, AUD) show symbol before the amount.
|
|
9
|
+
* Suffix currencies (JPY, KRW, ETH, SOL, B3) show symbol after the amount.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CURRENCY_SYMBOLS: Record<SupportedCurrency, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Human-readable currency names for display in selectors and labels.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CURRENCY_NAMES: Record<SupportedCurrency, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Currency store state interface.
|
|
18
|
+
* @property selectedCurrency - The currency currently selected for display
|
|
19
|
+
* @property baseCurrency - The base currency for conversion (typically B3)
|
|
20
|
+
* @property setSelectedCurrency - Update the selected display currency
|
|
21
|
+
* @property setBaseCurrency - Update the base currency for conversions
|
|
22
|
+
*/
|
|
23
|
+
interface CurrencyState {
|
|
24
|
+
selectedCurrency: SupportedCurrency;
|
|
25
|
+
baseCurrency: SupportedCurrency;
|
|
26
|
+
setSelectedCurrency: (currency: SupportedCurrency) => void;
|
|
27
|
+
setBaseCurrency: (currency: SupportedCurrency) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Zustand store for managing currency selection and conversion.
|
|
31
|
+
* Persists user's selected currency preference in localStorage.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const { selectedCurrency, setSelectedCurrency } = useCurrencyStore();
|
|
36
|
+
* // Change display currency to USD
|
|
37
|
+
* setSelectedCurrency('USD');
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare const useCurrencyStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<CurrencyState>, "persist"> & {
|
|
41
|
+
persist: {
|
|
42
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<CurrencyState, CurrencyState>>) => void;
|
|
43
|
+
clearStorage: () => void;
|
|
44
|
+
rehydrate: () => Promise<void> | void;
|
|
45
|
+
hasHydrated: () => boolean;
|
|
46
|
+
onHydrate: (fn: (state: CurrencyState) => void) => () => void;
|
|
47
|
+
onFinishHydration: (fn: (state: CurrencyState) => void) => () => void;
|
|
48
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<CurrencyState, CurrencyState>>;
|
|
49
|
+
};
|
|
50
|
+
}>;
|
|
51
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b3dotfun/sdk",
|
|
3
|
-
"version": "0.0.42-alpha.
|
|
3
|
+
"version": "0.0.42-alpha.3",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"react-native": "./dist/cjs/index.native.js",
|
|
@@ -205,6 +205,26 @@
|
|
|
205
205
|
"import": "./dist/esm/shared/thirdweb/*.js",
|
|
206
206
|
"require": "./dist/cjs/shared/thirdweb/*.js"
|
|
207
207
|
},
|
|
208
|
+
"./shared/react": {
|
|
209
|
+
"types": "./dist/types/shared/react/index.d.ts",
|
|
210
|
+
"import": "./dist/esm/shared/react/index.js",
|
|
211
|
+
"require": "./dist/cjs/shared/react/index.js"
|
|
212
|
+
},
|
|
213
|
+
"./shared/react/components": {
|
|
214
|
+
"types": "./dist/types/shared/react/components/index.d.ts",
|
|
215
|
+
"import": "./dist/esm/shared/react/components/index.js",
|
|
216
|
+
"require": "./dist/cjs/shared/react/components/index.js"
|
|
217
|
+
},
|
|
218
|
+
"./shared/react/hooks": {
|
|
219
|
+
"types": "./dist/types/shared/react/hooks/index.d.ts",
|
|
220
|
+
"import": "./dist/esm/shared/react/hooks/index.js",
|
|
221
|
+
"require": "./dist/cjs/shared/react/hooks/index.js"
|
|
222
|
+
},
|
|
223
|
+
"./shared/react/stores": {
|
|
224
|
+
"types": "./dist/types/shared/react/stores/index.d.ts",
|
|
225
|
+
"import": "./dist/esm/shared/react/stores/index.js",
|
|
226
|
+
"require": "./dist/cjs/shared/react/stores/index.js"
|
|
227
|
+
},
|
|
208
228
|
"./types/chain-networks": {
|
|
209
229
|
"types": "./dist/types/generated/chain-networks.d.ts",
|
|
210
230
|
"import": "./dist/esm/generated/chain-networks.js",
|
|
@@ -289,6 +309,8 @@
|
|
|
289
309
|
"@feathersjs/feathers": "5.0.33",
|
|
290
310
|
"@feathersjs/socketio-client": "5.0.33",
|
|
291
311
|
"@feathersjs/typebox": "5.0.33",
|
|
312
|
+
"@testing-library/react": "^16.3.0",
|
|
313
|
+
"@testing-library/react-hooks": "^8.0.1",
|
|
292
314
|
"@types/big.js": "^6.2.2",
|
|
293
315
|
"@types/invariant": "2.2.37",
|
|
294
316
|
"@types/js-cookie": "3.0.6",
|
|
@@ -304,6 +326,7 @@
|
|
|
304
326
|
"eslint-plugin-import": "2.x.x",
|
|
305
327
|
"eslint-plugin-react-hooks": "4.6.2",
|
|
306
328
|
"eslint-plugin-tailwindcss": "3.18.0",
|
|
329
|
+
"happy-dom": "^19.0.2",
|
|
307
330
|
"postcss": "8.5.3",
|
|
308
331
|
"postcss-cli": "11.0.1",
|
|
309
332
|
"postcss-nesting": "^13.0.2",
|
|
@@ -311,7 +334,8 @@
|
|
|
311
334
|
"tailwindcss": "3.4.1",
|
|
312
335
|
"tailwindcss-animate": "^1.0.7",
|
|
313
336
|
"tsc-alias": "^1.8.16",
|
|
314
|
-
"tsc-watch": "^7.1.1"
|
|
337
|
+
"tsc-watch": "^7.1.1",
|
|
338
|
+
"vitest": "^3.2.4"
|
|
315
339
|
},
|
|
316
340
|
"typesVersions": {
|
|
317
341
|
"*": {
|
|
@@ -367,6 +391,8 @@
|
|
|
367
391
|
"typecheck": "tsc --noEmit",
|
|
368
392
|
"generate:thirdweb": "npx @hey-api/openapi-ts --file src/thirdweb/openapi-ts.config.ts --input src/thirdweb/insight-service.json",
|
|
369
393
|
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
|
370
|
-
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
|
|
394
|
+
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix",
|
|
395
|
+
"test": "vitest run",
|
|
396
|
+
"test:ui": "vitest --ui"
|
|
371
397
|
}
|
|
372
398
|
}
|
|
@@ -79,6 +79,7 @@ export function AnySpend(props: {
|
|
|
79
79
|
*/
|
|
80
80
|
onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
|
|
81
81
|
onSuccess?: (txHash?: string) => void;
|
|
82
|
+
customUsdInputValues?: string[];
|
|
82
83
|
}) {
|
|
83
84
|
const fingerprintConfig = getFingerprintConfig();
|
|
84
85
|
|
|
@@ -99,6 +100,7 @@ function AnySpendInner({
|
|
|
99
100
|
recipientAddress: recipientAddressFromProps,
|
|
100
101
|
onTokenSelect,
|
|
101
102
|
onSuccess,
|
|
103
|
+
customUsdInputValues,
|
|
102
104
|
}: {
|
|
103
105
|
destinationTokenAddress?: string;
|
|
104
106
|
destinationTokenChainId?: number;
|
|
@@ -109,6 +111,7 @@ function AnySpendInner({
|
|
|
109
111
|
recipientAddress?: string;
|
|
110
112
|
onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
|
|
111
113
|
onSuccess?: (txHash?: string) => void;
|
|
114
|
+
customUsdInputValues?: string[];
|
|
112
115
|
}) {
|
|
113
116
|
const searchParams = useSearchParamsSSR();
|
|
114
117
|
const router = useRouter();
|
|
@@ -924,6 +927,7 @@ function AnySpendInner({
|
|
|
924
927
|
hideDstToken={isBuyMode}
|
|
925
928
|
anyspendQuote={anyspendQuote}
|
|
926
929
|
onShowPointsDetail={() => setActivePanel(PanelView.POINTS_DETAIL)}
|
|
930
|
+
customUsdInputValues={customUsdInputValues}
|
|
927
931
|
/>
|
|
928
932
|
</motion.div>
|
|
929
933
|
)}
|
|
@@ -42,6 +42,7 @@ export interface AnySpendDepositHypeProps {
|
|
|
42
42
|
* Useful for handling special cases like B3 token selection.
|
|
43
43
|
*/
|
|
44
44
|
onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
|
|
45
|
+
customUsdInputValues?: string[];
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export function AnySpendDepositHype(props: AnySpendDepositHypeProps) {
|
|
@@ -64,6 +65,7 @@ function AnySpendDepositHypeInner({
|
|
|
64
65
|
onSuccess,
|
|
65
66
|
mainFooter,
|
|
66
67
|
onTokenSelect,
|
|
68
|
+
customUsdInputValues,
|
|
67
69
|
}: AnySpendDepositHypeProps) {
|
|
68
70
|
// Use shared flow hook
|
|
69
71
|
const {
|
|
@@ -234,6 +236,7 @@ function AnySpendDepositHypeInner({
|
|
|
234
236
|
recipientSelectionPanelIndex={PanelView.RECIPIENT_SELECTION}
|
|
235
237
|
anyspendQuote={anyspendQuote}
|
|
236
238
|
onShowPointsDetail={() => setActivePanel(PanelView.POINTS_DETAIL)}
|
|
239
|
+
customUsdInputValues={customUsdInputValues}
|
|
237
240
|
/>
|
|
238
241
|
</motion.div>
|
|
239
242
|
)}
|
|
@@ -30,6 +30,7 @@ export function PanelOnramp({
|
|
|
30
30
|
hideDstToken = false,
|
|
31
31
|
anyspendQuote,
|
|
32
32
|
onShowPointsDetail,
|
|
33
|
+
customUsdInputValues = ["5", "10", "20", "25"],
|
|
33
34
|
}: {
|
|
34
35
|
srcAmountOnRamp: string;
|
|
35
36
|
setSrcAmountOnRamp: (amount: string) => void;
|
|
@@ -47,6 +48,7 @@ export function PanelOnramp({
|
|
|
47
48
|
hideDstToken?: boolean;
|
|
48
49
|
anyspendQuote?: GetQuoteResponse;
|
|
49
50
|
onShowPointsDetail?: () => void;
|
|
51
|
+
customUsdInputValues?: string[];
|
|
50
52
|
}) {
|
|
51
53
|
const featureFlags = useFeatureFlags();
|
|
52
54
|
// Get geo-based onramp options to access fee information
|
|
@@ -166,7 +168,7 @@ export function PanelOnramp({
|
|
|
166
168
|
value={srcAmountOnRamp}
|
|
167
169
|
onChange={handleAmountChange}
|
|
168
170
|
placeholder="5"
|
|
169
|
-
className="text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-
|
|
171
|
+
className="text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-1 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
170
172
|
style={{
|
|
171
173
|
width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
|
|
172
174
|
}}
|
|
@@ -175,20 +177,22 @@ export function PanelOnramp({
|
|
|
175
177
|
</div>
|
|
176
178
|
|
|
177
179
|
{/* Quick Amount Buttons */}
|
|
178
|
-
<div className={cn("mx-auto mb-6
|
|
179
|
-
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
180
|
+
<div className={cn("mx-auto mb-6 flex justify-center gap-2", hideDstToken && "mb-0")}>
|
|
181
|
+
{customUsdInputValues
|
|
182
|
+
.filter(v => !isNaN(Number(v)))
|
|
183
|
+
.map(value => (
|
|
184
|
+
<button
|
|
185
|
+
key={value}
|
|
186
|
+
onClick={() => handleQuickAmount(value)}
|
|
187
|
+
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 ${
|
|
188
|
+
srcAmountOnRamp === value
|
|
189
|
+
? "border-as-border-secondary bg-as-surface-secondary"
|
|
190
|
+
: "bg-as-surface-secondary hover:bg-as-surface-secondary"
|
|
191
|
+
}`}
|
|
192
|
+
>
|
|
193
|
+
${value}
|
|
194
|
+
</button>
|
|
195
|
+
))}
|
|
192
196
|
</div>
|
|
193
197
|
|
|
194
198
|
{/* Token Display */}
|
|
@@ -159,13 +159,8 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
159
159
|
|
|
160
160
|
<button className="mb-2 w-full space-y-1" onClick={onDisconnect}>
|
|
161
161
|
<div className="hover:bg-b3-react-background group flex h-12 items-center rounded-xl px-4 transition-colors">
|
|
162
|
-
<Icon
|
|
163
|
-
|
|
164
|
-
name="logout"
|
|
165
|
-
/>
|
|
166
|
-
<div className="text-b3-react-background group-hover:text-b3-react-primary mr-auto transition-colors">
|
|
167
|
-
Disconnect
|
|
168
|
-
</div>
|
|
162
|
+
<Icon className="fill-b3-react-primary mr-4 shrink-0 transition-colors" name="logout" />
|
|
163
|
+
<div className="text-b3-react-primary mr-auto transition-colors">Disconnect</div>
|
|
169
164
|
</div>
|
|
170
165
|
</button>
|
|
171
166
|
</div>
|
|
@@ -7,12 +7,12 @@ export { useB3 } from "./B3Provider/useB3";
|
|
|
7
7
|
export { StyleRoot } from "./StyleRoot";
|
|
8
8
|
|
|
9
9
|
// SignInWithB3 Components
|
|
10
|
-
export { SignInWithB3 } from "./SignInWithB3/SignInWithB3";
|
|
11
|
-
export { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow";
|
|
12
|
-
export { SignInWithB3Privy } from "./SignInWithB3/SignInWithB3Privy";
|
|
13
10
|
export { AuthButton } from "./SignInWithB3/components/AuthButton";
|
|
14
11
|
export { PermissionItem } from "./SignInWithB3/components/PermissionItem";
|
|
15
12
|
export { WalletRow } from "./SignInWithB3/components/WalletRow";
|
|
13
|
+
export { SignInWithB3 } from "./SignInWithB3/SignInWithB3";
|
|
14
|
+
export { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow";
|
|
15
|
+
export { SignInWithB3Privy } from "./SignInWithB3/SignInWithB3Privy";
|
|
16
16
|
export { LoginStepContainer } from "./SignInWithB3/steps/LoginStep";
|
|
17
17
|
export { getConnectOptionsFromStrategy, isWalletType, type AllowedStrategy } from "./SignInWithB3/utils/signInUtils";
|
|
18
18
|
|
|
@@ -43,15 +43,6 @@ export { StaggeredFadeLoader } from "./custom/StaggeredFadeLoader";
|
|
|
43
43
|
export { WalletConnectorIcon } from "./custom/WalletConnectorIcon";
|
|
44
44
|
|
|
45
45
|
// UI Components
|
|
46
|
-
export { Loading } from "./ui/Loading";
|
|
47
|
-
export { ShinyButton } from "./ui/ShinyButton";
|
|
48
|
-
export { TabTrigger, Tabs, TabsContent, TabsList, TabsTransitionWrapper } from "./ui/TabSystem";
|
|
49
|
-
export {
|
|
50
|
-
TabTrigger as TabTriggerPrimitive,
|
|
51
|
-
TabsContent as TabsContentPrimitive,
|
|
52
|
-
TabsList as TabsListPrimitive,
|
|
53
|
-
Tabs as TabsPrimitive,
|
|
54
|
-
} from "./ui/Tabs";
|
|
55
46
|
export { Badge, badgeVariants } from "./ui/badge";
|
|
56
47
|
export { Button, buttonVariants } from "./ui/button";
|
|
57
48
|
export {
|
|
@@ -89,12 +80,28 @@ export {
|
|
|
89
80
|
DrawerTitle,
|
|
90
81
|
DrawerTrigger,
|
|
91
82
|
} from "./ui/drawer";
|
|
83
|
+
export {
|
|
84
|
+
DropdownMenu,
|
|
85
|
+
DropdownMenuContent,
|
|
86
|
+
DropdownMenuItem,
|
|
87
|
+
DropdownMenuSeparator,
|
|
88
|
+
DropdownMenuTrigger,
|
|
89
|
+
} from "./ui/dropdown-menu";
|
|
92
90
|
export { GlareCard } from "./ui/glare-card";
|
|
93
91
|
export { GlareCardRounded } from "./ui/glare-card-rounded";
|
|
94
92
|
export { Input } from "./ui/input";
|
|
93
|
+
export { Loading } from "./ui/Loading";
|
|
95
94
|
export { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
|
96
95
|
export { ScrollArea, ScrollBar } from "./ui/scroll-area";
|
|
96
|
+
export { ShinyButton } from "./ui/ShinyButton";
|
|
97
97
|
export { Skeleton } from "./ui/skeleton";
|
|
98
|
+
export {
|
|
99
|
+
TabTrigger as TabTriggerPrimitive,
|
|
100
|
+
TabsContent as TabsContentPrimitive,
|
|
101
|
+
TabsList as TabsListPrimitive,
|
|
102
|
+
Tabs as TabsPrimitive,
|
|
103
|
+
} from "./ui/Tabs";
|
|
104
|
+
export { TabTrigger, Tabs, TabsContent, TabsList, TabsTransitionWrapper } from "./ui/TabSystem";
|
|
98
105
|
export { TextLoop } from "./ui/text-loop";
|
|
99
106
|
export { TextShimmer } from "./ui/text-shimmer";
|
|
100
107
|
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@b3dotfun/sdk/shared/utils";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
|
|
6
|
+
interface DropdownMenuProps {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface DropdownMenuContentProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
align?: "start" | "center" | "end";
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DropdownMenuItemProps {
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
onClick?: () => void;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface DropdownMenuSeparatorProps {
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface DropdownMenuTriggerProps {
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
asChild?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const DropdownMenuContext = React.createContext<{
|
|
32
|
+
isOpen: boolean;
|
|
33
|
+
setIsOpen: (open: boolean) => void;
|
|
34
|
+
}>({
|
|
35
|
+
isOpen: false,
|
|
36
|
+
setIsOpen: () => {},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export function DropdownMenu({ children }: DropdownMenuProps) {
|
|
40
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
41
|
+
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
44
|
+
const target = event.target as Element;
|
|
45
|
+
if (!target.closest("[data-dropdown-menu]")) {
|
|
46
|
+
setIsOpen(false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (isOpen) {
|
|
51
|
+
document.addEventListener("click", handleClickOutside);
|
|
52
|
+
return () => document.removeEventListener("click", handleClickOutside);
|
|
53
|
+
}
|
|
54
|
+
}, [isOpen]);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<DropdownMenuContext.Provider value={{ isOpen, setIsOpen }}>
|
|
58
|
+
<div className="relative" data-dropdown-menu>
|
|
59
|
+
{children}
|
|
60
|
+
</div>
|
|
61
|
+
</DropdownMenuContext.Provider>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function DropdownMenuTrigger({ children, asChild }: DropdownMenuTriggerProps) {
|
|
66
|
+
const { isOpen, setIsOpen } = React.useContext(DropdownMenuContext);
|
|
67
|
+
|
|
68
|
+
const handleClick = () => {
|
|
69
|
+
setIsOpen(!isOpen);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (asChild) {
|
|
73
|
+
if (React.isValidElement(children)) {
|
|
74
|
+
return React.cloneElement(children as React.ReactElement<{ onClick?: () => void }>, {
|
|
75
|
+
onClick: handleClick,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return <button onClick={handleClick}>{children}</button>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function DropdownMenuContent({ children, align = "start", className }: DropdownMenuContentProps) {
|
|
84
|
+
const { isOpen } = React.useContext(DropdownMenuContext);
|
|
85
|
+
|
|
86
|
+
if (!isOpen) return null;
|
|
87
|
+
|
|
88
|
+
const alignmentClasses = {
|
|
89
|
+
start: "left-0",
|
|
90
|
+
center: "left-1/2 -translate-x-1/2",
|
|
91
|
+
end: "right-0",
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
className={cn(
|
|
97
|
+
"bg-popover text-popover-foreground absolute top-full z-50 mt-1 min-w-32 overflow-hidden rounded-md border p-1 shadow-md",
|
|
98
|
+
"border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800",
|
|
99
|
+
alignmentClasses[align],
|
|
100
|
+
className,
|
|
101
|
+
)}
|
|
102
|
+
>
|
|
103
|
+
{children}
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function DropdownMenuItem({ children, onClick, className }: DropdownMenuItemProps) {
|
|
109
|
+
const { setIsOpen } = React.useContext(DropdownMenuContext);
|
|
110
|
+
|
|
111
|
+
const handleClick = () => {
|
|
112
|
+
onClick?.();
|
|
113
|
+
setIsOpen(false);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<div
|
|
118
|
+
className={cn(
|
|
119
|
+
"hover:bg-accent hover:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
120
|
+
"hover:bg-gray-100 dark:hover:bg-gray-700",
|
|
121
|
+
className,
|
|
122
|
+
)}
|
|
123
|
+
onClick={handleClick}
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function DropdownMenuSeparator({ className }: DropdownMenuSeparatorProps) {
|
|
131
|
+
return <div className={cn("bg-muted -mx-1 my-1 h-px", "bg-gray-200 dark:bg-gray-600", className)} />;
|
|
132
|
+
}
|
|
@@ -128,6 +128,8 @@ export interface AnySpendModalProps extends BaseModalProps {
|
|
|
128
128
|
destinationTokenAddress?: string;
|
|
129
129
|
/** Chain ID where the destination token exists (enables buy mode) */
|
|
130
130
|
destinationTokenChainId?: number;
|
|
131
|
+
/** Custom USD input values for quick amount buttons in fiat onramp */
|
|
132
|
+
customUsdInputValues?: string[];
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
/**
|
|
@@ -307,6 +309,8 @@ export interface AnySpendDepositHypeProps extends BaseModalProps {
|
|
|
307
309
|
mainFooter?: React.ReactNode;
|
|
308
310
|
/** Callback function called when the deposit is successful */
|
|
309
311
|
onSuccess?: (amount?: string) => void;
|
|
312
|
+
/** Custom USD input values for quick amount buttons in fiat onramp */
|
|
313
|
+
customUsdInputValues?: string[];
|
|
310
314
|
}
|
|
311
315
|
|
|
312
316
|
export interface AvatarEditorModalProps extends BaseModalProps {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@b3dotfun/sdk/shared/utils";
|
|
4
|
+
import { Button } from "../../../global-account/react/components/ui/button";
|
|
5
|
+
import {
|
|
6
|
+
DropdownMenu,
|
|
7
|
+
DropdownMenuContent,
|
|
8
|
+
DropdownMenuItem,
|
|
9
|
+
DropdownMenuSeparator,
|
|
10
|
+
DropdownMenuTrigger,
|
|
11
|
+
} from "../../../global-account/react/components/ui/dropdown-menu";
|
|
12
|
+
import { CURRENCY_NAMES, CURRENCY_SYMBOLS, SupportedCurrency, useCurrencyStore } from "../stores/currencyStore";
|
|
13
|
+
|
|
14
|
+
const currencies: SupportedCurrency[] = ["B3", "ETH", "SOL", "USD", "EUR", "GBP", "KRW", "JPY", "CAD", "AUD"];
|
|
15
|
+
|
|
16
|
+
interface CurrencySelectorProps {
|
|
17
|
+
labelClassName?: string;
|
|
18
|
+
buttonVariant?: "dark" | "primary" | "ghost" | "gold";
|
|
19
|
+
label?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function CurrencySelector({ labelClassName, buttonVariant = "dark", label }: CurrencySelectorProps) {
|
|
23
|
+
const { selectedCurrency, setSelectedCurrency } = useCurrencyStore();
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="flex items-center gap-2">
|
|
27
|
+
<DropdownMenu>
|
|
28
|
+
<DropdownMenuTrigger asChild>
|
|
29
|
+
<div className="flex items-center gap-3">
|
|
30
|
+
{label && (
|
|
31
|
+
<span
|
|
32
|
+
className={cn(
|
|
33
|
+
"text-foreground text-sm font-medium leading-none tracking-tight sm:text-base",
|
|
34
|
+
labelClassName,
|
|
35
|
+
)}
|
|
36
|
+
>
|
|
37
|
+
{label}
|
|
38
|
+
</span>
|
|
39
|
+
)}
|
|
40
|
+
<Button variant={buttonVariant as any} className="flex items-center gap-2">
|
|
41
|
+
<span className="text-sm font-medium">{CURRENCY_NAMES[selectedCurrency]}</span>
|
|
42
|
+
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
|
|
43
|
+
<path
|
|
44
|
+
fillRule="evenodd"
|
|
45
|
+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
46
|
+
clipRule="evenodd"
|
|
47
|
+
/>
|
|
48
|
+
</svg>
|
|
49
|
+
</Button>
|
|
50
|
+
</div>
|
|
51
|
+
</DropdownMenuTrigger>
|
|
52
|
+
<DropdownMenuContent align="end" className="z-[100] min-w-[200px]">
|
|
53
|
+
{currencies.map(currency => (
|
|
54
|
+
<div key={currency}>
|
|
55
|
+
<DropdownMenuItem
|
|
56
|
+
onClick={() => setSelectedCurrency(currency)}
|
|
57
|
+
className={`flex cursor-pointer items-center justify-between gap-3 px-3 py-2.5 transition-colors ${
|
|
58
|
+
selectedCurrency === currency ? "bg-accent" : "hover:bg-accent/50"
|
|
59
|
+
}`}
|
|
60
|
+
>
|
|
61
|
+
<span className="text-foreground text-sm font-medium">{CURRENCY_NAMES[currency]}</span>
|
|
62
|
+
<span className="text-muted-foreground text-xs font-medium">{CURRENCY_SYMBOLS[currency]}</span>
|
|
63
|
+
</DropdownMenuItem>
|
|
64
|
+
{currency === "SOL" && <DropdownMenuSeparator key="separator" className="bg-border my-1" />}
|
|
65
|
+
</div>
|
|
66
|
+
))}
|
|
67
|
+
</DropdownMenuContent>
|
|
68
|
+
</DropdownMenu>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|