@b3dotfun/sdk 0.1.69-alpha.11 → 0.1.69-alpha.13

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 (59) hide show
  1. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.d.ts +3 -1
  2. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.js +5 -1
  3. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  4. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +8 -12
  5. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.native.js +6 -9
  6. package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +4 -13
  7. package/dist/cjs/global-account/react/utils/createWagmiConfig.js +5 -7
  8. package/dist/cjs/wallet/react/components/ConnectWallet.d.ts +11 -0
  9. package/dist/cjs/wallet/react/components/ConnectWallet.js +467 -0
  10. package/dist/cjs/wallet/react/components/WalletProvider.d.ts +35 -0
  11. package/dist/cjs/wallet/react/components/WalletProvider.js +20 -0
  12. package/dist/cjs/wallet/react/hooks/useWalletDisconnect.d.ts +13 -0
  13. package/dist/cjs/wallet/react/hooks/useWalletDisconnect.js +22 -0
  14. package/dist/cjs/wallet/react/hooks/useWalletState.d.ts +31 -0
  15. package/dist/cjs/wallet/react/hooks/useWalletState.js +63 -0
  16. package/dist/cjs/wallet/react/index.d.ts +5 -0
  17. package/dist/cjs/wallet/react/index.js +16 -0
  18. package/dist/cjs/wallet/utils/createWalletConfig.d.ts +21 -0
  19. package/dist/cjs/wallet/utils/createWalletConfig.js +24 -0
  20. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.d.ts +3 -1
  21. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.js +5 -1
  22. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  23. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +3 -7
  24. package/dist/esm/global-account/react/components/B3Provider/B3Provider.native.js +2 -5
  25. package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +4 -13
  26. package/dist/esm/global-account/react/utils/createWagmiConfig.js +5 -7
  27. package/dist/esm/wallet/react/components/ConnectWallet.d.ts +11 -0
  28. package/dist/esm/wallet/react/components/ConnectWallet.js +431 -0
  29. package/dist/esm/wallet/react/components/WalletProvider.d.ts +35 -0
  30. package/dist/esm/wallet/react/components/WalletProvider.js +17 -0
  31. package/dist/esm/wallet/react/hooks/useWalletDisconnect.d.ts +13 -0
  32. package/dist/esm/wallet/react/hooks/useWalletDisconnect.js +19 -0
  33. package/dist/esm/wallet/react/hooks/useWalletState.d.ts +31 -0
  34. package/dist/esm/wallet/react/hooks/useWalletState.js +60 -0
  35. package/dist/esm/wallet/react/index.d.ts +5 -0
  36. package/dist/esm/wallet/react/index.js +8 -0
  37. package/dist/esm/wallet/utils/createWalletConfig.d.ts +21 -0
  38. package/dist/esm/wallet/utils/createWalletConfig.js +21 -0
  39. package/dist/types/anyspend/react/components/checkout/AnySpendCheckout.d.ts +3 -1
  40. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  41. package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +4 -13
  42. package/dist/types/wallet/react/components/ConnectWallet.d.ts +11 -0
  43. package/dist/types/wallet/react/components/WalletProvider.d.ts +35 -0
  44. package/dist/types/wallet/react/hooks/useWalletDisconnect.d.ts +13 -0
  45. package/dist/types/wallet/react/hooks/useWalletState.d.ts +31 -0
  46. package/dist/types/wallet/react/index.d.ts +5 -0
  47. package/dist/types/wallet/utils/createWalletConfig.d.ts +21 -0
  48. package/package.json +12 -1
  49. package/src/anyspend/react/components/checkout/AnySpendCheckout.tsx +6 -0
  50. package/src/global-account/react/components/B3Provider/B3Provider.native.tsx +14 -20
  51. package/src/global-account/react/components/B3Provider/B3Provider.tsx +41 -45
  52. package/src/global-account/react/utils/createWagmiConfig.tsx +6 -7
  53. package/src/wallet/__tests__/createWalletConfig.test.ts +39 -0
  54. package/src/wallet/react/components/ConnectWallet.tsx +665 -0
  55. package/src/wallet/react/components/WalletProvider.tsx +64 -0
  56. package/src/wallet/react/hooks/useWalletDisconnect.ts +22 -0
  57. package/src/wallet/react/hooks/useWalletState.ts +93 -0
  58. package/src/wallet/react/index.ts +10 -0
  59. package/src/wallet/utils/createWalletConfig.ts +39 -0
@@ -0,0 +1,64 @@
1
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
2
+ import { useMemo, useState } from "react";
3
+ import { ThirdwebProvider } from "thirdweb/react";
4
+ import { type Config, WagmiProvider, type CreateConnectorFn } from "wagmi";
5
+ import type { Chain } from "viem";
6
+ import { createWalletConfig } from "../../utils/createWalletConfig";
7
+
8
+ export interface WalletProviderProps {
9
+ children: React.ReactNode;
10
+ /**
11
+ * Chains to support. Defaults to SDK's supportedChains.
12
+ * Must be memoized or defined outside the component — inline arrays cause the
13
+ * wagmi config to rebuild on every render, losing wallet connection state.
14
+ */
15
+ chains?: Chain[];
16
+ /**
17
+ * Wagmi connectors. Must be memoized or defined outside the component — inline
18
+ * arrays cause the wagmi config to rebuild on every render, losing wallet connection state.
19
+ */
20
+ connectors?: CreateConnectorFn[];
21
+ /**
22
+ * Optional RPC URL overrides per chain ID.
23
+ * Must be memoized or defined outside the component — inline objects cause the
24
+ * wagmi config to rebuild on every render, losing wallet connection state.
25
+ */
26
+ rpcUrls?: Record<number, string>;
27
+ /** Escape hatch: pass a fully custom wagmi config. Overrides chains/connectors/rpcUrls. */
28
+ wagmiConfig?: Config;
29
+ /** Provide your own QueryClient for React Query. Defaults to an internal instance. */
30
+ queryClient?: QueryClient;
31
+ /** Whether to auto-reconnect the last wallet on mount. Defaults to false. */
32
+ reconnectOnMount?: boolean;
33
+ }
34
+
35
+ /**
36
+ * Standalone wallet connection provider.
37
+ * Wraps ThirdwebProvider, WagmiProvider, and QueryClientProvider.
38
+ * Use wagmi hooks (useAccount, useConnect, useDisconnect) directly inside.
39
+ */
40
+ export function WalletProvider({
41
+ children,
42
+ chains,
43
+ connectors,
44
+ rpcUrls,
45
+ wagmiConfig: wagmiConfigProp,
46
+ queryClient: queryClientProp,
47
+ reconnectOnMount = false,
48
+ }: WalletProviderProps) {
49
+ const [defaultQueryClient] = useState(() => new QueryClient());
50
+ const queryClient = queryClientProp ?? defaultQueryClient;
51
+
52
+ const wagmiConfig = useMemo(
53
+ () => wagmiConfigProp ?? createWalletConfig({ chains, connectors, rpcUrls }),
54
+ [wagmiConfigProp, chains, connectors, rpcUrls],
55
+ );
56
+
57
+ return (
58
+ <ThirdwebProvider>
59
+ <WagmiProvider config={wagmiConfig} reconnectOnMount={reconnectOnMount}>
60
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
61
+ </WagmiProvider>
62
+ </ThirdwebProvider>
63
+ );
64
+ }
@@ -0,0 +1,22 @@
1
+ import { useCallback } from "react";
2
+ import { useDisconnect } from "wagmi";
3
+
4
+ /**
5
+ * Disconnect the current wallet via wagmi.
6
+ * Consumers should use this instead of wagmi's useDisconnect directly
7
+ * to ensure a consistent disconnect API across the wallet module.
8
+ *
9
+ * Note: this only disconnects the wagmi layer. When used inside B3Provider,
10
+ * the thirdweb auth session is managed separately by B3Provider's own logout
11
+ * flow (useAuthentication). ConnectWallet is intended for standalone
12
+ * WalletProvider usage where thirdweb auth is not involved.
13
+ */
14
+ export function useWalletDisconnect() {
15
+ const { disconnect: wagmiDisconnect } = useDisconnect();
16
+
17
+ const disconnect = useCallback(() => {
18
+ wagmiDisconnect();
19
+ }, [wagmiDisconnect]);
20
+
21
+ return { disconnect };
22
+ }
@@ -0,0 +1,93 @@
1
+ import { useEffect, useMemo, useRef } from "react";
2
+ import { useAccount, useConnect, useConnectors } from "wagmi";
3
+ import type { Chain } from "viem";
4
+ import type { Connector } from "wagmi";
5
+
6
+ export interface WalletConnector {
7
+ /** Display name of the wallet */
8
+ name: string;
9
+ /** Unique identifier for this connector instance */
10
+ uid: string;
11
+ /** Whether the wallet extension/app is detected in the browser */
12
+ isInstalled: boolean;
13
+ /** Connect using this connector. Returns a promise that resolves on success or rejects on failure/rejection. */
14
+ connect: () => Promise<void>;
15
+ /** Raw wagmi connector for advanced use */
16
+ connector: Connector;
17
+ }
18
+
19
+ export interface WalletState {
20
+ /** Connected wallet address, or undefined if not connected */
21
+ address: string | undefined;
22
+ /** Whether a wallet is currently connected */
23
+ isConnected: boolean;
24
+ /** Current chain the wallet is connected to */
25
+ chain: Chain | undefined;
26
+ /** Whether a connection attempt is in progress */
27
+ isPending: boolean;
28
+ /** Available wallet connectors, deduplicated by name */
29
+ connectors: WalletConnector[];
30
+ }
31
+
32
+ /**
33
+ * Unified wallet state from both thirdweb and wagmi layers.
34
+ * Provides available connectors with install status and connect functions.
35
+ */
36
+ export function useWalletState(): WalletState {
37
+ const { address, isConnected, chain } = useAccount();
38
+ const { connectAsync, isPending } = useConnect();
39
+ const wagmiConnectors = useConnectors();
40
+
41
+ // Ref to avoid connectAsync in useMemo deps — wagmi returns a new reference on state
42
+ // changes, which would recreate the connectors array on every render.
43
+ const connectAsyncRef = useRef(connectAsync);
44
+ useEffect(() => {
45
+ connectAsyncRef.current = connectAsync;
46
+ });
47
+
48
+ const connectors: WalletConnector[] = useMemo(() => {
49
+ const seen = new Set<string>();
50
+ const mapped = wagmiConnectors
51
+ .filter(c => {
52
+ // Hide generic "Injected" — it duplicates the actual wallet (MetaMask, Rabby, etc.)
53
+ if (c.name === "Injected") return false;
54
+ if (seen.has(c.name)) return false;
55
+ seen.add(c.name);
56
+ return true;
57
+ })
58
+ .map(connector => ({
59
+ name: connector.name,
60
+ uid: connector.uid,
61
+ isInstalled: isConnectorInstalled(connector),
62
+ connect: async () => {
63
+ await connectAsyncRef.current({ connector });
64
+ },
65
+ connector,
66
+ }));
67
+
68
+ // Sort: installed connectors first
69
+ return mapped.sort((a, b) => (a.isInstalled === b.isInstalled ? 0 : a.isInstalled ? -1 : 1));
70
+ }, [wagmiConnectors]);
71
+
72
+ return { address, isConnected, chain, isPending, connectors };
73
+ }
74
+
75
+ /** Check if a wallet connector's provider is available in the browser. */
76
+ function isConnectorInstalled(connector: Connector): boolean {
77
+ // WalletConnect is always "available" (uses QR code, no extension needed)
78
+ if (connector.id === "walletConnect") return true;
79
+
80
+ // For injected connectors, check if any provider exists. This may report
81
+ // false positives (e.g., Rabby shows as installed when only MetaMask is)
82
+ // because multiple injected connectors share window.ethereum. This is
83
+ // intentional — we surface all options and let the wallet handle conflicts.
84
+ if (connector.type === "injected") {
85
+ return typeof window !== "undefined" && !!window.ethereum;
86
+ }
87
+
88
+ // Coinbase Wallet SDK works without extension (has mobile/QR fallback)
89
+ if (connector.id === "coinbaseWalletSDK") return true;
90
+
91
+ // Default: assume available (better UX than hiding connectors)
92
+ return true;
93
+ }
@@ -0,0 +1,10 @@
1
+ // Provider
2
+ export { WalletProvider, type WalletProviderProps } from "./components/WalletProvider";
3
+ export { createWalletConfig, type CreateWalletConfigOptions } from "../utils/createWalletConfig";
4
+
5
+ // Hooks
6
+ export { useWalletDisconnect } from "./hooks/useWalletDisconnect";
7
+ export { useWalletState, type WalletConnector, type WalletState } from "./hooks/useWalletState";
8
+
9
+ // Components
10
+ export { ConnectWallet, type ConnectWalletProps } from "./components/ConnectWallet";
@@ -0,0 +1,39 @@
1
+ import { supportedChains } from "@b3dotfun/sdk/shared/constants/chains/supported";
2
+ import { http } from "viem";
3
+ import { createConfig, type CreateConnectorFn } from "wagmi";
4
+ import { coinbaseWallet, injected } from "wagmi/connectors";
5
+ import type { Chain } from "viem";
6
+
7
+ /** Default connectors: injected (MetaMask, Rabby, Brave, etc.) + Coinbase Wallet. */
8
+ const DEFAULT_CONNECTORS: CreateConnectorFn[] = [injected(), coinbaseWallet({ appName: "B3" })];
9
+
10
+ export interface CreateWalletConfigOptions {
11
+ /** Chains to support. Defaults to SDK's supportedChains. Must be non-empty. */
12
+ chains?: Chain[];
13
+ /**
14
+ * Wagmi connectors. Defaults to injected + Coinbase Wallet.
15
+ * Must be memoized if passed to WalletProvider — inline arrays
16
+ * will cause the config to rebuild on every render, losing wallet connection state.
17
+ */
18
+ connectors?: CreateConnectorFn[];
19
+ /** Optional RPC URL overrides per chain ID. */
20
+ rpcUrls?: Record<number, string>;
21
+ }
22
+
23
+ /**
24
+ * Creates a generic wagmi config with sensible defaults.
25
+ * No ecosystem wallet, no B3-specific concerns.
26
+ */
27
+ export function createWalletConfig(options: CreateWalletConfigOptions = {}) {
28
+ const { chains = supportedChains, connectors = DEFAULT_CONNECTORS, rpcUrls } = options;
29
+
30
+ if (chains.length === 0) {
31
+ throw new Error("createWalletConfig: at least one chain must be provided");
32
+ }
33
+
34
+ return createConfig({
35
+ chains: [chains[0], ...chains.slice(1)],
36
+ transports: Object.fromEntries(chains.map(chain => [chain.id, http(rpcUrls?.[chain.id])])),
37
+ connectors,
38
+ });
39
+ }