@b3dotfun/sdk 0.0.90-test.1 → 0.1.0-alpha.1

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 (52) hide show
  1. package/dist/cjs/anyspend/constants/rpc.d.ts +22 -0
  2. package/dist/cjs/anyspend/constants/rpc.js +38 -0
  3. package/dist/cjs/anyspend/utils/chain.d.ts +23 -0
  4. package/dist/cjs/anyspend/utils/chain.js +56 -12
  5. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  6. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +37 -0
  7. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -19
  8. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.native.js +4 -31
  9. package/dist/cjs/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  10. package/dist/cjs/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  11. package/dist/cjs/global-account/react/components/B3Provider/useB3Config.js +2 -21
  12. package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +2 -2
  13. package/dist/cjs/global-account/react/hooks/useTokenBalancesByChain.js +3 -0
  14. package/dist/cjs/global-account/react/stores/index.d.ts +0 -1
  15. package/dist/cjs/global-account/react/stores/index.js +1 -3
  16. package/dist/esm/anyspend/constants/rpc.d.ts +22 -0
  17. package/dist/esm/anyspend/constants/rpc.js +35 -0
  18. package/dist/esm/anyspend/utils/chain.d.ts +23 -0
  19. package/dist/esm/anyspend/utils/chain.js +53 -12
  20. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  21. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +33 -0
  22. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -19
  23. package/dist/esm/global-account/react/components/B3Provider/B3Provider.native.js +3 -30
  24. package/dist/esm/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  25. package/dist/esm/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  26. package/dist/esm/global-account/react/components/B3Provider/useB3Config.js +1 -20
  27. package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +2 -2
  28. package/dist/esm/global-account/react/hooks/useTokenBalancesByChain.js +3 -0
  29. package/dist/esm/global-account/react/stores/index.d.ts +0 -1
  30. package/dist/esm/global-account/react/stores/index.js +0 -1
  31. package/dist/types/anyspend/constants/rpc.d.ts +22 -0
  32. package/dist/types/anyspend/utils/chain.d.ts +23 -0
  33. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  34. package/dist/types/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  35. package/dist/types/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  36. package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +2 -2
  37. package/dist/types/global-account/react/stores/index.d.ts +0 -1
  38. package/package.json +1 -1
  39. package/src/anyspend/constants/rpc.ts +38 -0
  40. package/src/anyspend/utils/chain.ts +70 -36
  41. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +84 -0
  42. package/src/global-account/react/components/B3Provider/B3Provider.native.tsx +28 -36
  43. package/src/global-account/react/components/B3Provider/B3Provider.tsx +21 -27
  44. package/src/global-account/react/components/B3Provider/useB3Config.ts +1 -21
  45. package/src/global-account/react/hooks/useTokenBalancesByChain.tsx +3 -0
  46. package/src/global-account/react/stores/index.ts +0 -1
  47. package/dist/cjs/global-account/react/stores/configStore.d.ts +0 -24
  48. package/dist/cjs/global-account/react/stores/configStore.js +0 -30
  49. package/dist/esm/global-account/react/stores/configStore.d.ts +0 -24
  50. package/dist/esm/global-account/react/stores/configStore.js +0 -27
  51. package/dist/types/global-account/react/stores/configStore.d.ts +0 -24
  52. package/src/global-account/react/stores/configStore.ts +0 -51
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Public RPC endpoints for EVM chains.
3
+ * These are free, public endpoints that can be used without API keys.
4
+ *
5
+ * Sources:
6
+ * - https://publicnode.com
7
+ * - https://chainlist.org
8
+ */
9
+
10
+ // PublicNode endpoints
11
+ export const ETHEREUM_PUBLIC_RPC = "https://ethereum-rpc.publicnode.com";
12
+ export const ARBITRUM_PUBLIC_RPC = "https://arbitrum-one-rpc.publicnode.com";
13
+ export const BASE_PUBLIC_RPC = "https://base-rpc.publicnode.com";
14
+ export const OPTIMISM_PUBLIC_RPC = "https://optimism-rpc.publicnode.com";
15
+ export const POLYGON_PUBLIC_RPC = "https://polygon-bor-rpc.publicnode.com";
16
+ export const AVALANCHE_PUBLIC_RPC = "https://avalanche-c-chain-rpc.publicnode.com";
17
+ export const BSC_PUBLIC_RPC = "https://bsc-rpc.publicnode.com";
18
+
19
+ // Chain-specific public endpoints
20
+ export const B3_PUBLIC_RPC = "https://mainnet-rpc.b3.fun/http";
21
+ export const ABSTRACT_PUBLIC_RPC = "https://api.mainnet.abs.xyz";
22
+ export const HYPEREVM_PUBLIC_RPC = "https://rpc.hyperliquid.xyz/evm";
23
+
24
+ /**
25
+ * Map of chain IDs to their default public RPC URLs.
26
+ */
27
+ export const PUBLIC_RPC_URLS: Record<number, string> = {
28
+ 1: ETHEREUM_PUBLIC_RPC, // Ethereum Mainnet
29
+ 42161: ARBITRUM_PUBLIC_RPC, // Arbitrum One
30
+ 8453: BASE_PUBLIC_RPC, // Base
31
+ 10: OPTIMISM_PUBLIC_RPC, // Optimism
32
+ 137: POLYGON_PUBLIC_RPC, // Polygon
33
+ 43114: AVALANCHE_PUBLIC_RPC, // Avalanche C-Chain
34
+ 56: BSC_PUBLIC_RPC, // BNB Smart Chain
35
+ 8333: B3_PUBLIC_RPC, // B3
36
+ 2741: ABSTRACT_PUBLIC_RPC, // Abstract
37
+ 999: HYPEREVM_PUBLIC_RPC, // HyperEVM
38
+ };
@@ -1,4 +1,16 @@
1
1
  import { RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend/constants";
2
+ import {
3
+ ABSTRACT_PUBLIC_RPC,
4
+ ARBITRUM_PUBLIC_RPC,
5
+ AVALANCHE_PUBLIC_RPC,
6
+ B3_PUBLIC_RPC,
7
+ BASE_PUBLIC_RPC,
8
+ BSC_PUBLIC_RPC,
9
+ ETHEREUM_PUBLIC_RPC,
10
+ HYPEREVM_PUBLIC_RPC,
11
+ OPTIMISM_PUBLIC_RPC,
12
+ POLYGON_PUBLIC_RPC,
13
+ } from "@b3dotfun/sdk/anyspend/constants/rpc";
2
14
  import { components } from "@b3dotfun/sdk/anyspend/types/api";
3
15
  import invariant from "invariant";
4
16
  import {
@@ -31,11 +43,49 @@ function getCustomEvmChain(chain: Chain, rpcUrl: string): Chain {
31
43
  return defineChain({ ...chain, rpcUrls: { default: { http: [rpcUrl] } } });
32
44
  }
33
45
 
46
+ /**
47
+ * Global RPC URL overrides for EVM chains.
48
+ * Use setChainRpcOverrides() to configure custom RPC endpoints.
49
+ */
50
+ let chainRpcOverrides: Record<number, string> = {};
51
+
52
+ /**
53
+ * Set custom RPC URL overrides for specific chains.
54
+ * These overrides are used by chainIdToPublicClient and chainIdToWalletClient.
55
+ *
56
+ * @param overrides - A record mapping chain IDs to custom RPC URLs
57
+ *
58
+ * @example
59
+ * // Set once at app initialization using environment variables
60
+ * setChainRpcOverrides({
61
+ * 1: process.env.ETHEREUM_RPC_URL,
62
+ * 8453: process.env.BASE_RPC_URL,
63
+ * 42161: process.env.ARBITRUM_RPC_URL,
64
+ * });
65
+ */
66
+ export function setChainRpcOverrides(overrides: Record<number, string>): void {
67
+ chainRpcOverrides = { ...overrides };
68
+ }
69
+
70
+ /**
71
+ * Get the current RPC URL overrides.
72
+ */
73
+ export function getChainRpcOverrides(): Record<number, string> {
74
+ return { ...chainRpcOverrides };
75
+ }
76
+
77
+ /**
78
+ * Clear all RPC URL overrides.
79
+ */
80
+ export function clearChainRpcOverrides(): void {
81
+ chainRpcOverrides = {};
82
+ }
83
+
34
84
  export const hyperEVM = defineChain({
35
85
  id: HYPEREVM_CHAIN_ID,
36
86
  name: "HyperEVM",
37
87
  nativeCurrency: { name: "HyperEVM", symbol: "HYPE", decimals: 18 },
38
- rpcUrls: { default: { http: ["https://rpc.hyperliquid.xyz/evm"] } },
88
+ rpcUrls: { default: { http: [HYPEREVM_PUBLIC_RPC] } },
39
89
  blockExplorers: { default: { name: "HyperEVM Explorer", url: "https://hyperevmscan.io/" } },
40
90
  });
41
91
 
@@ -57,10 +107,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
57
107
  canDepositNative: true,
58
108
  defaultToken: getEthToken(mainnet.id),
59
109
  nativeToken: getEthToken(mainnet.id),
60
- viem: getCustomEvmChain(
61
- mainnet,
62
- "https://quick-chaotic-film.quiknode.pro/39a7aae6a7078f9f36c435e6f34c071c641cf863/",
63
- ),
110
+ viem: getCustomEvmChain(mainnet, ETHEREUM_PUBLIC_RPC),
64
111
  pollingInterval: 4000, // 4 seconds for Ethereum mainnet
65
112
  zapperEnum: "ETHEREUM_MAINNET",
66
113
  coingeckoName: "eth",
@@ -75,10 +122,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
75
122
  canDepositNative: true,
76
123
  defaultToken: getEthToken(arbitrum.id),
77
124
  nativeToken: getEthToken(arbitrum.id),
78
- viem: getCustomEvmChain(
79
- arbitrum,
80
- "https://proportionate-twilight-patina.arbitrum-mainnet.quiknode.pro/60e4825626515233a0f566f5915601af6043127b/",
81
- ),
125
+ viem: getCustomEvmChain(arbitrum, ARBITRUM_PUBLIC_RPC),
82
126
  pollingInterval: 500, // 500ms for Arbitrum's fast blocks
83
127
  zapperEnum: "ARBITRUM_MAINNET",
84
128
  coingeckoName: "arbitrum",
@@ -93,10 +137,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
93
137
  canDepositNative: true,
94
138
  defaultToken: getEthToken(base.id),
95
139
  nativeToken: getEthToken(base.id),
96
- viem: getCustomEvmChain(
97
- base,
98
- "https://sly-indulgent-bird.base-mainnet.quiknode.pro/4e31fab6845eb29a2764723a43896999fe962e48/",
99
- ),
140
+ viem: getCustomEvmChain(base, BASE_PUBLIC_RPC),
100
141
  pollingInterval: 1000, // 1 second for Base
101
142
  zapperEnum: "BASE_MAINNET",
102
143
  coingeckoName: "base",
@@ -111,10 +152,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
111
152
  canDepositNative: true,
112
153
  defaultToken: getEthToken(optimism.id),
113
154
  nativeToken: getEthToken(optimism.id),
114
- viem: getCustomEvmChain(
115
- optimism,
116
- "https://black-cosmopolitan-hexagon.optimism.quiknode.pro/18382925841f9d09f9e76eef954bf189aa234523/",
117
- ),
155
+ viem: getCustomEvmChain(optimism, OPTIMISM_PUBLIC_RPC),
118
156
  pollingInterval: 1000, // 1 second for Optimism
119
157
  zapperEnum: "OPTIMISM_MAINNET",
120
158
  coingeckoName: "optimism",
@@ -129,10 +167,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
129
167
  canDepositNative: true,
130
168
  defaultToken: getPolToken(),
131
169
  nativeToken: getPolToken(),
132
- viem: getCustomEvmChain(
133
- polygon,
134
- "https://purple-young-field.matic.quiknode.pro/ca54f365c1a4c7f970223eb8087e0fc579feba12/",
135
- ),
170
+ viem: getCustomEvmChain(polygon, POLYGON_PUBLIC_RPC),
136
171
  pollingInterval: 1000, // 1 second for Polygon
137
172
  zapperEnum: "POLYGON_MAINNET",
138
173
  coingeckoName: "polygon_pos",
@@ -147,7 +182,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
147
182
  canDepositNative: true,
148
183
  defaultToken: getAvaxToken(),
149
184
  nativeToken: getAvaxToken(),
150
- viem: getCustomEvmChain(avalanche, "https://avalanche-c-chain-rpc.publicnode.com"),
185
+ viem: getCustomEvmChain(avalanche, AVALANCHE_PUBLIC_RPC),
151
186
  pollingInterval: 1000, // 1 second for Avalanche
152
187
  zapperEnum: "AVALANCHE_MAINNET",
153
188
  coingeckoName: "avax",
@@ -162,10 +197,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
162
197
  canDepositNative: true,
163
198
  defaultToken: getBnbToken(),
164
199
  nativeToken: getBnbToken(),
165
- viem: getCustomEvmChain(
166
- bsc,
167
- "https://methodical-divine-flower.bsc.quiknode.pro/9fc7efd3c34cc016cceacc27ee95850629b7cd21/",
168
- ),
200
+ viem: getCustomEvmChain(bsc, BSC_PUBLIC_RPC),
169
201
  pollingInterval: 1000, // 1 second for BSC
170
202
  zapperEnum: "BSC_MAINNET",
171
203
  coingeckoName: "bsc",
@@ -180,10 +212,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
180
212
  canDepositNative: true,
181
213
  defaultToken: getEthToken(b3.id),
182
214
  nativeToken: getEthToken(b3.id),
183
- viem: getCustomEvmChain(
184
- b3,
185
- "https://late-dimensional-yard.b3-mainnet.quiknode.pro/461dbdbd44158cd7a7a764a58ffb01a67eef77f2/",
186
- ),
215
+ viem: getCustomEvmChain(b3, B3_PUBLIC_RPC),
187
216
  pollingInterval: 1000, // 1 second for B3
188
217
  zapperEnum: "B3_MAINNET",
189
218
  coingeckoName: "b3",
@@ -198,10 +227,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
198
227
  canDepositNative: true,
199
228
  defaultToken: getEthToken(abstract.id),
200
229
  nativeToken: getEthToken(abstract.id),
201
- viem: getCustomEvmChain(
202
- abstract,
203
- "https://cosmopolitan-nameless-mountain.abstract-mainnet.quiknode.pro/863853304b986b582bdacf625ce3350397c560f8/",
204
- ),
230
+ viem: getCustomEvmChain(abstract, ABSTRACT_PUBLIC_RPC),
205
231
  pollingInterval: 3000, // 3 seconds for Abstract
206
232
  zapperEnum: "ABSTRACT_MAINNET",
207
233
  coingeckoName: "abstract",
@@ -328,8 +354,12 @@ export function getChainType(chainId: number): ChainType {
328
354
  export function chainIdToPublicClient(chainId: number): PublicClient {
329
355
  invariant(EVM_CHAINS[chainId], `Chain ${chainId} is not an EVM chain`);
330
356
 
357
+ // Use override RPC if configured, otherwise use the default chain RPC
358
+ const rpcOverride = chainRpcOverrides[chainId];
359
+ const chain = rpcOverride ? getCustomEvmChain(EVM_CHAINS[chainId].viem, rpcOverride) : EVM_CHAINS[chainId].viem;
360
+
331
361
  return createPublicClient({
332
- chain: EVM_CHAINS[chainId].viem,
362
+ chain,
333
363
  transport: http(),
334
364
  pollingInterval: EVM_CHAINS[chainId].pollingInterval,
335
365
  });
@@ -338,8 +368,12 @@ export function chainIdToPublicClient(chainId: number): PublicClient {
338
368
  export function chainIdToWalletClient(chainId: number, account?: Account): WalletClient<Transport, Chain> {
339
369
  invariant(EVM_CHAINS[chainId], `Chain ${chainId} is not an EVM chain`);
340
370
 
371
+ // Use override RPC if configured, otherwise use the default chain RPC
372
+ const rpcOverride = chainRpcOverrides[chainId];
373
+ const chain = rpcOverride ? getCustomEvmChain(EVM_CHAINS[chainId].viem, rpcOverride) : EVM_CHAINS[chainId].viem;
374
+
341
375
  return createWalletClient({
342
- chain: EVM_CHAINS[chainId].viem,
376
+ chain,
343
377
  transport: http(),
344
378
  account,
345
379
  pollingInterval: EVM_CHAINS[chainId].pollingInterval,
@@ -0,0 +1,84 @@
1
+ import { CreateOnrampOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
+ import { CreateOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOrder";
3
+ import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
4
+ import { createContext, useContext } from "react";
5
+ import { Account } from "thirdweb/wallets";
6
+ import { ClientType } from "../../../client-manager";
7
+
8
+ /**
9
+ * Default permissions configuration for B3 provider
10
+ */
11
+ const DEFAULT_PERMISSIONS: PermissionsConfig = {
12
+ approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
13
+ nativeTokenLimitPerTransaction: 0.1,
14
+ startDate: new Date(),
15
+ endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
16
+ };
17
+
18
+ export interface B3ConfigContextType {
19
+ accountOverride?: Account;
20
+ automaticallySetFirstEoa: boolean;
21
+ environment: "development" | "production";
22
+ defaultPermissions: PermissionsConfig;
23
+ theme: "light" | "dark";
24
+ clientType: ClientType;
25
+ partnerId: string;
26
+ stripePublishableKey?: string;
27
+ createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
28
+ enableTurnkey: boolean;
29
+ }
30
+
31
+ const B3ConfigContext = createContext<B3ConfigContextType | null>(null);
32
+
33
+ export function B3ConfigProvider({
34
+ children,
35
+ accountOverride,
36
+ environment = "development",
37
+ defaultPermissions = DEFAULT_PERMISSIONS,
38
+ automaticallySetFirstEoa = false,
39
+ theme = "light",
40
+ clientType = "rest",
41
+ partnerId,
42
+ stripePublishableKey,
43
+ createClientReferenceId,
44
+ enableTurnkey = false,
45
+ }: {
46
+ children: React.ReactNode;
47
+ accountOverride?: Account;
48
+ environment?: "development" | "production";
49
+ defaultPermissions?: PermissionsConfig;
50
+ automaticallySetFirstEoa?: boolean;
51
+ theme?: "light" | "dark";
52
+ clientType?: ClientType;
53
+ partnerId: string;
54
+ stripePublishableKey?: string;
55
+ createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
56
+ enableTurnkey?: boolean;
57
+ }) {
58
+ return (
59
+ <B3ConfigContext.Provider
60
+ value={{
61
+ accountOverride,
62
+ environment,
63
+ defaultPermissions,
64
+ automaticallySetFirstEoa,
65
+ theme,
66
+ clientType,
67
+ partnerId,
68
+ stripePublishableKey,
69
+ createClientReferenceId,
70
+ enableTurnkey,
71
+ }}
72
+ >
73
+ {children}
74
+ </B3ConfigContext.Provider>
75
+ );
76
+ }
77
+
78
+ export function useB3Config(): B3ConfigContextType {
79
+ const context = useContext(B3ConfigContext);
80
+ if (!context) {
81
+ throw new Error("useB3Config must be used within a B3ConfigProvider");
82
+ }
83
+ return context;
84
+ }
@@ -1,15 +1,14 @@
1
1
  import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
2
2
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
- import { useEffect } from "react";
4
3
  import { ThirdwebProvider } from "thirdweb/react";
5
4
  import { Account, Wallet } from "thirdweb/wallets";
6
5
 
7
6
  import { ClientType } from "../../../client-manager";
8
7
 
9
8
  import { WagmiProvider } from "wagmi";
10
- import { useB3ConfigStore } from "../../stores/configStore";
11
9
  import { createWagmiConfig } from "../../utils/createWagmiConfig";
12
10
  import AuthenticationProvider from "./AuthenticationProvider";
11
+ import { B3ConfigProvider } from "./B3ConfigProvider";
13
12
  import { LocalSDKProvider } from "./LocalSDKProvider";
14
13
 
15
14
  // Create queryClient instance
@@ -39,28 +38,23 @@ export function B3Provider({
39
38
  onConnect?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
40
39
  defaultPermissions?: PermissionsConfig;
41
40
  }) {
42
- const setConfig = useB3ConfigStore(state => state.setConfig);
43
-
44
- // Initialize config store on mount - props are static and never change
45
- useEffect(() => {
46
- setConfig({
47
- accountOverride,
48
- environment: environment ?? "development",
49
- automaticallySetFirstEoa: false,
50
- theme,
51
- clientType,
52
- partnerId,
53
- defaultPermissions,
54
- });
55
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
56
-
57
41
  return (
58
42
  <ThirdwebProvider>
59
43
  <LocalSDKProvider onConnectCallback={onConnect}>
60
- {/* <RelayKitProviderWrapper> */}
61
- {children}
62
- <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={false} />
63
- {/* </RelayKitProviderWrapper> */}
44
+ <B3ConfigProvider
45
+ accountOverride={accountOverride}
46
+ environment={environment}
47
+ automaticallySetFirstEoa={false}
48
+ theme={theme}
49
+ clientType={clientType}
50
+ partnerId={partnerId}
51
+ defaultPermissions={defaultPermissions}
52
+ >
53
+ {/* <RelayKitProviderWrapper> */}
54
+ {children}
55
+ <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={false} />
56
+ {/* </RelayKitProviderWrapper> */}
57
+ </B3ConfigProvider>
64
58
  </LocalSDKProvider>
65
59
  </ThirdwebProvider>
66
60
  );
@@ -88,25 +82,23 @@ export function InnerProvider({
88
82
  partnerId: string;
89
83
  rpcUrls?: Record<number, string>;
90
84
  }) {
91
- const setConfig = useB3ConfigStore(state => state.setConfig);
92
85
  const wagmiConfig = createWagmiConfig({ partnerId, rpcUrls });
93
86
 
94
- // Initialize config store on mount - props are static and never change
95
- useEffect(() => {
96
- setConfig({
97
- accountOverride,
98
- environment: environment ?? "development",
99
- automaticallySetFirstEoa: false,
100
- theme,
101
- clientType,
102
- partnerId,
103
- defaultPermissions,
104
- });
105
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
106
-
107
87
  return (
108
88
  <WagmiProvider config={wagmiConfig}>
109
- <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
89
+ <QueryClientProvider client={queryClient}>
90
+ <B3ConfigProvider
91
+ accountOverride={accountOverride}
92
+ environment={environment}
93
+ automaticallySetFirstEoa={false}
94
+ theme={theme}
95
+ clientType={clientType}
96
+ partnerId={partnerId}
97
+ defaultPermissions={defaultPermissions}
98
+ >
99
+ {children}
100
+ </B3ConfigProvider>
101
+ </QueryClientProvider>
110
102
  </WagmiProvider>
111
103
  );
112
104
  }
@@ -11,10 +11,10 @@ import { ThirdwebProvider } from "thirdweb/react";
11
11
  import { Account, Wallet } from "thirdweb/wallets";
12
12
  import { CreateConnectorFn, WagmiProvider } from "wagmi";
13
13
  import { ClientType, setClientType } from "../../../client-manager";
14
- import { useB3ConfigStore } from "../../stores/configStore";
15
14
  import { StyleRoot } from "../StyleRoot";
16
15
  import { setToastContext, ToastProvider, useToastContext } from "../Toast/index";
17
16
  import AuthenticationProvider from "./AuthenticationProvider";
17
+ import { B3ConfigProvider } from "./B3ConfigProvider";
18
18
  import { LocalSDKProvider } from "./LocalSDKProvider";
19
19
 
20
20
  // Create queryClient instance
@@ -65,25 +65,6 @@ export function B3Provider({
65
65
  enableTurnkey?: boolean;
66
66
  defaultPermissions?: PermissionsConfig;
67
67
  }) {
68
- const setConfig = useB3ConfigStore(state => state.setConfig);
69
-
70
- // Initialize config store on mount
71
- useEffect(() => {
72
- setConfig({
73
- accountOverride,
74
- environment: environment ?? "development",
75
- automaticallySetFirstEoa: !!automaticallySetFirstEoa,
76
- theme,
77
- clientType,
78
- partnerId,
79
- stripePublishableKey,
80
- createClientReferenceId,
81
- enableTurnkey,
82
- defaultPermissions,
83
- });
84
- // eslint-disable-next-line react-hooks/exhaustive-deps
85
- }, []);
86
-
87
68
  // Initialize Google Analytics on mount
88
69
  useEffect(() => {
89
70
  loadGA4Script();
@@ -106,13 +87,26 @@ export function B3Provider({
106
87
  <TooltipProvider>
107
88
  <ToastProvider>
108
89
  <LocalSDKProvider onConnectCallback={onConnect}>
109
- <ToastContextConnector />
110
- <RelayKitProviderWrapper simDuneApiKey={simDuneApiKey}>
111
- {children}
112
- {/* For the modal https://github.com/b3-fun/b3/blob/main/packages/sdk/src/global-account/react/components/ui/dialog.tsx#L46 */}
113
- <StyleRoot id="b3-root" />
114
- </RelayKitProviderWrapper>
115
- <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={!!automaticallySetFirstEoa} />
90
+ <B3ConfigProvider
91
+ accountOverride={accountOverride}
92
+ environment={environment}
93
+ automaticallySetFirstEoa={!!automaticallySetFirstEoa}
94
+ theme={theme}
95
+ clientType={clientType}
96
+ partnerId={partnerId}
97
+ stripePublishableKey={stripePublishableKey}
98
+ createClientReferenceId={createClientReferenceId}
99
+ enableTurnkey={enableTurnkey}
100
+ defaultPermissions={defaultPermissions}
101
+ >
102
+ <ToastContextConnector />
103
+ <RelayKitProviderWrapper simDuneApiKey={simDuneApiKey}>
104
+ {children}
105
+ {/* For the modal https://github.com/b3-fun/b3/blob/main/packages/sdk/src/global-account/react/components/ui/dialog.tsx#L46 */}
106
+ <StyleRoot id="b3-root" />
107
+ </RelayKitProviderWrapper>
108
+ <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={!!automaticallySetFirstEoa} />
109
+ </B3ConfigProvider>
116
110
  </LocalSDKProvider>
117
111
  </ToastProvider>
118
112
  </TooltipProvider>
@@ -1,21 +1 @@
1
- import { useB3ConfigStore } from "../../stores/configStore";
2
-
3
- /**
4
- * Hook to access B3 configuration
5
- * Returns all config values from the Zustand store
6
- * Since config is static (set once at initialization), destructuring is fine here
7
- */
8
- export const useB3Config = () => {
9
- return useB3ConfigStore(state => ({
10
- automaticallySetFirstEoa: state.automaticallySetFirstEoa,
11
- environment: state.environment,
12
- theme: state.theme,
13
- clientType: state.clientType,
14
- partnerId: state.partnerId,
15
- createClientReferenceId: state.createClientReferenceId,
16
- enableTurnkey: state.enableTurnkey,
17
- stripePublishableKey: state.stripePublishableKey,
18
- defaultPermissions: state.defaultPermissions,
19
- accountOverride: state.accountOverride,
20
- }));
21
- };
1
+ export { useB3Config } from "./B3ConfigProvider";
@@ -83,6 +83,9 @@ export function useTokenBalancesByChain({
83
83
  staleTime: 30000, // Consider data fresh for 30 seconds
84
84
  gcTime: 5 * 60 * 1000, // Keep in cache for 5 minutes
85
85
  retry: 2, // Limit retries on failure
86
+ // Enable structural sharing to prevent infinite loops
87
+ // This ensures we only get new references when data actually changes
88
+ structuralSharing: true,
86
89
  });
87
90
 
88
91
  return {
@@ -1,5 +1,4 @@
1
1
  export { useAuthStore } from "./useAuthStore";
2
- export { useB3ConfigStore } from "./configStore";
3
2
  export { useModalStore } from "./useModalStore";
4
3
  export { useRecentAddressesStore } from "./useRecentAddressesStore";
5
4
 
@@ -1,24 +0,0 @@
1
- import { CreateOnrampOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
- import { CreateOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOrder";
3
- import { PermissionsConfig } from "../../../global-account/types/permissions";
4
- import { Account } from "thirdweb/wallets";
5
- import { ClientType } from "../../client-manager";
6
- interface ConfigStore {
7
- accountOverride?: Account;
8
- automaticallySetFirstEoa: boolean;
9
- environment: "development" | "production";
10
- defaultPermissions: PermissionsConfig;
11
- theme: "light" | "dark";
12
- clientType: ClientType;
13
- partnerId: string;
14
- stripePublishableKey?: string;
15
- createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
16
- enableTurnkey: boolean;
17
- setConfig: (config: Partial<Omit<ConfigStore, "setConfig">>) => void;
18
- }
19
- /**
20
- * Zustand store for B3 configuration
21
- * NOT persisted - these are developer-set configuration values
22
- */
23
- export declare const useB3ConfigStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConfigStore>>;
24
- export {};
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useB3ConfigStore = void 0;
4
- const zustand_1 = require("zustand");
5
- /**
6
- * Default permissions configuration for B3 provider
7
- */
8
- const DEFAULT_PERMISSIONS = {
9
- approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
10
- nativeTokenLimitPerTransaction: 0.1,
11
- startDate: new Date(),
12
- endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
13
- };
14
- /**
15
- * Zustand store for B3 configuration
16
- * NOT persisted - these are developer-set configuration values
17
- */
18
- exports.useB3ConfigStore = (0, zustand_1.create)(set => ({
19
- accountOverride: undefined,
20
- automaticallySetFirstEoa: false,
21
- environment: "development",
22
- defaultPermissions: DEFAULT_PERMISSIONS,
23
- theme: "light",
24
- clientType: "rest",
25
- partnerId: "",
26
- stripePublishableKey: undefined,
27
- createClientReferenceId: undefined,
28
- enableTurnkey: false,
29
- setConfig: config => set(state => ({ ...state, ...config })),
30
- }));
@@ -1,24 +0,0 @@
1
- import { CreateOnrampOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
- import { CreateOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOrder";
3
- import { PermissionsConfig } from "../../../global-account/types/permissions";
4
- import { Account } from "thirdweb/wallets";
5
- import { ClientType } from "../../client-manager";
6
- interface ConfigStore {
7
- accountOverride?: Account;
8
- automaticallySetFirstEoa: boolean;
9
- environment: "development" | "production";
10
- defaultPermissions: PermissionsConfig;
11
- theme: "light" | "dark";
12
- clientType: ClientType;
13
- partnerId: string;
14
- stripePublishableKey?: string;
15
- createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
16
- enableTurnkey: boolean;
17
- setConfig: (config: Partial<Omit<ConfigStore, "setConfig">>) => void;
18
- }
19
- /**
20
- * Zustand store for B3 configuration
21
- * NOT persisted - these are developer-set configuration values
22
- */
23
- export declare const useB3ConfigStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConfigStore>>;
24
- export {};
@@ -1,27 +0,0 @@
1
- import { create } from "zustand";
2
- /**
3
- * Default permissions configuration for B3 provider
4
- */
5
- const DEFAULT_PERMISSIONS = {
6
- approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
7
- nativeTokenLimitPerTransaction: 0.1,
8
- startDate: new Date(),
9
- endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
10
- };
11
- /**
12
- * Zustand store for B3 configuration
13
- * NOT persisted - these are developer-set configuration values
14
- */
15
- export const useB3ConfigStore = create(set => ({
16
- accountOverride: undefined,
17
- automaticallySetFirstEoa: false,
18
- environment: "development",
19
- defaultPermissions: DEFAULT_PERMISSIONS,
20
- theme: "light",
21
- clientType: "rest",
22
- partnerId: "",
23
- stripePublishableKey: undefined,
24
- createClientReferenceId: undefined,
25
- enableTurnkey: false,
26
- setConfig: config => set(state => ({ ...state, ...config })),
27
- }));
@@ -1,24 +0,0 @@
1
- import { CreateOnrampOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
- import { CreateOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOrder";
3
- import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
4
- import { Account } from "thirdweb/wallets";
5
- import { ClientType } from "../../client-manager";
6
- interface ConfigStore {
7
- accountOverride?: Account;
8
- automaticallySetFirstEoa: boolean;
9
- environment: "development" | "production";
10
- defaultPermissions: PermissionsConfig;
11
- theme: "light" | "dark";
12
- clientType: ClientType;
13
- partnerId: string;
14
- stripePublishableKey?: string;
15
- createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
16
- enableTurnkey: boolean;
17
- setConfig: (config: Partial<Omit<ConfigStore, "setConfig">>) => void;
18
- }
19
- /**
20
- * Zustand store for B3 configuration
21
- * NOT persisted - these are developer-set configuration values
22
- */
23
- export declare const useB3ConfigStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConfigStore>>;
24
- export {};