@capxul/sdk-react 0.1.0-alpha.1 → 0.1.0-alpha.11

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/index.cjs CHANGED
@@ -5,12 +5,52 @@ var react = require('react');
5
5
  var sdk = require('@capxul/sdk');
6
6
  var reactQuery = require('@tanstack/react-query');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
+ var react$2 = require('convex/react');
8
9
  var errors = require('@capxul/sdk/errors');
9
10
  var react$1 = require('@xstate/react');
10
11
  var viem = require('viem');
11
12
  var accounts = require('viem/accounts');
12
13
 
13
14
  // src/provider.tsx
15
+ var CapxulClientContext = react.createContext(null);
16
+ function CapxulClientProvider({
17
+ client,
18
+ children
19
+ }) {
20
+ return /* @__PURE__ */ jsxRuntime.jsx(CapxulClientContext.Provider, { value: client, children });
21
+ }
22
+ function useCapxul() {
23
+ const client = react.useContext(CapxulClientContext);
24
+ if (!client) {
25
+ throw new Error(
26
+ "useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
27
+ );
28
+ }
29
+ return client;
30
+ }
31
+ var CapxulTransportContext = react.createContext(null);
32
+ function CapxulTransportProvider({
33
+ transport,
34
+ children
35
+ }) {
36
+ return /* @__PURE__ */ jsxRuntime.jsx(CapxulTransportContext.Provider, { value: transport, children });
37
+ }
38
+ function useCapxulStatus() {
39
+ const transport = react.useContext(CapxulTransportContext);
40
+ return react.useSyncExternalStore(
41
+ (listener) => {
42
+ if (!transport) return () => {
43
+ };
44
+ return transport.subscribe(listener);
45
+ },
46
+ () => transport?.getState() ?? FALLBACK_READY,
47
+ () => transport?.getState() ?? FALLBACK_READY
48
+ );
49
+ }
50
+ var FALLBACK_READY = Object.freeze({
51
+ status: "ready",
52
+ runtime: { authBaseUrl: "", convexUrl: "" }
53
+ });
14
54
 
15
55
  // ../config/src/errors.ts
16
56
  var CapxulError = class extends Error {
@@ -41,10 +81,16 @@ var Errors = {
41
81
  `Shield API error (${status}): ${detail}`,
42
82
  { details: { provider: "shield", status } }
43
83
  ),
44
- providerError: (provider, operation, cause) => new CapxulError(
45
- "PROVIDER_ERROR",
46
- `${provider} ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
47
- { cause, details: { provider, operation } }
84
+ providerError: (provider, operation, cause) => (
85
+ // Public `message` is redacted to a fixed shape so provider-side
86
+ // exception text never leaks to the client. The original `cause`
87
+ // is preserved on `Error.cause` for server-side debugging via
88
+ // observability sinks (Sentry, console traces).
89
+ new CapxulError(
90
+ "PROVIDER_ERROR",
91
+ `Provider error: ${provider} ${operation}`,
92
+ { cause, details: { provider, operation } }
93
+ )
48
94
  ),
49
95
  invalidInput: (field, reason) => new CapxulError(
50
96
  "INVALID_INPUT",
@@ -70,8 +116,35 @@ var Errors = {
70
116
  "Idempotency key was already used for a different request",
71
117
  { details }
72
118
  ),
73
- emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`),
74
- internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`)
119
+ emailDeliveryFailed: (detail, details) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
120
+ details
121
+ }),
122
+ rateLimited: (details) => new CapxulError("RATE_LIMITED", "Request was rate limited", {
123
+ details: { ...details }
124
+ }),
125
+ internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`),
126
+ /**
127
+ * Verification gate. Surfaced when a request hits a verification
128
+ * boundary the actor cannot cross under their current state. Two
129
+ * variants share this code:
130
+ *
131
+ * - Rail gate (Withdrawals v1 W2, #465): the resolved
132
+ * `external_account.kind` routes to a withdrawal rail (e.g.
133
+ * `fiat_offramp`, `card_payout`) that is not yet supported. Carries
134
+ * `details.rail` + `details.currentKind`.
135
+ * - KYC tier gate (legacy / future): the actor's KYC tier is below
136
+ * the required tier. Carries `details.requiredTier`.
137
+ *
138
+ * Code is shared because both expose the same UX shape ("you cannot
139
+ * proceed until verification advances"); the `details.*` keys
140
+ * differentiate the route.
141
+ */
142
+ verificationRequired: (details) => {
143
+ const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
144
+ return new CapxulError("VERIFICATION_REQUIRED", message, {
145
+ details: { ...details }
146
+ });
147
+ }
75
148
  };
76
149
 
77
150
  // ../config/src/org-roles.ts
@@ -83,56 +156,137 @@ function roleKeyFromLabel(label) {
83
156
  roleKeyFromLabel("OWNER");
84
157
  roleKeyFromLabel("FINANCE_MANAGER");
85
158
  roleKeyFromLabel("TEAM_LEAD");
86
- var CapxulClientContext = react.createContext(null);
87
- function CapxulClientProvider({
88
- client,
89
- children
90
- }) {
91
- return /* @__PURE__ */ jsxRuntime.jsx(CapxulClientContext.Provider, { value: client, children });
159
+
160
+ // src/config.ts
161
+ function createCapxulConfig(input) {
162
+ assertOnlyKnownKeys(input);
163
+ assertModeRequiredFields(input);
164
+ return Object.freeze({ ...input });
92
165
  }
93
- function useCapxul() {
94
- const client = react.useContext(CapxulClientContext);
95
- if (!client) {
96
- throw new Error(
97
- "useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
98
- );
166
+ var ALLOWED_BROWSER_CONFIG_KEYS = [
167
+ "mode",
168
+ "authBaseUrl",
169
+ "convexUrl",
170
+ "publishableKey",
171
+ "bootstrapUrl",
172
+ "fetchImpl"
173
+ ];
174
+ function assertOnlyKnownKeys(input) {
175
+ const candidate = input;
176
+ const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
177
+ const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
178
+ if (unknown.length === 0) return;
179
+ throw Errors.invalidInput(
180
+ "config",
181
+ `Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
182
+ );
183
+ }
184
+ function assertModeRequiredFields(input) {
185
+ switch (input.mode) {
186
+ case "build-time-urls": {
187
+ if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
188
+ throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
189
+ }
190
+ if (!input.convexUrl || input.convexUrl.trim().length === 0) {
191
+ throw Errors.invalidInput("convexUrl", "non-empty string required.");
192
+ }
193
+ return;
194
+ }
195
+ case "publishable-key": {
196
+ if (!input.publishableKey || input.publishableKey.trim().length === 0) {
197
+ throw Errors.invalidInput("publishableKey", "non-empty string required.");
198
+ }
199
+ return;
200
+ }
201
+ default: {
202
+ const value = input;
203
+ throw Errors.internalError(
204
+ `Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
205
+ );
206
+ }
99
207
  }
100
- return client;
101
208
  }
102
- var CapxulTransportContext = react.createContext(null);
103
- function CapxulTransportProvider({
104
- transport,
105
- children
106
- }) {
107
- return /* @__PURE__ */ jsxRuntime.jsx(CapxulTransportContext.Provider, { value: transport, children });
209
+ function createReactDataClient(convexUrl, sessionStore) {
210
+ const client = new react$2.ConvexReactClient(convexUrl);
211
+ const refreshAuth = () => {
212
+ const session = sessionStore.get();
213
+ const jwt = session?.convexJwt;
214
+ if (jwt) {
215
+ client.setAuth(() => Promise.resolve(jwt));
216
+ } else {
217
+ client.clearAuth();
218
+ }
219
+ };
220
+ refreshAuth();
221
+ return {
222
+ query: (name, args) => client.query(name, args),
223
+ mutation: (name, args) => client.mutation(name, args),
224
+ action: (name, args) => client.action(name, args),
225
+ refreshAuth,
226
+ close: () => {
227
+ void client.close();
228
+ }
229
+ };
108
230
  }
109
- function useCapxulStatus() {
110
- const transport = react.useContext(CapxulTransportContext);
111
- return react.useSyncExternalStore(
112
- (listener) => {
113
- if (!transport) return () => {
114
- };
115
- return transport.subscribe(listener);
231
+ function createLazyReactDataClient(transport, sessionStore, createClient = createReactDataClient) {
232
+ let client = null;
233
+ let initializeClient = null;
234
+ let closed = false;
235
+ function closedError() {
236
+ return new Error("Capxul React data client is closed");
237
+ }
238
+ async function getClient() {
239
+ if (closed) throw closedError();
240
+ if (client) return client;
241
+ initializeClient ??= (async () => {
242
+ const runtime = await transport.ensureRuntime();
243
+ if (closed) throw closedError();
244
+ const nextClient = createClient(runtime.convexUrl, sessionStore);
245
+ if (closed) {
246
+ nextClient.close();
247
+ throw closedError();
248
+ }
249
+ client = nextClient;
250
+ return nextClient;
251
+ })().catch((error) => {
252
+ if (!closed) {
253
+ initializeClient = null;
254
+ }
255
+ throw error;
256
+ });
257
+ return initializeClient;
258
+ }
259
+ return {
260
+ query: async (name, args) => (await getClient()).query(name, args),
261
+ mutation: async (name, args) => (await getClient()).mutation(name, args),
262
+ action: async (name, args) => (await getClient()).action?.(name, args),
263
+ refreshAuth: () => {
264
+ client?.refreshAuth();
116
265
  },
117
- () => transport?.getState() ?? FALLBACK_READY,
118
- () => transport?.getState() ?? FALLBACK_READY
119
- );
266
+ close: () => {
267
+ closed = true;
268
+ client?.close();
269
+ client = null;
270
+ }
271
+ };
120
272
  }
121
- var FALLBACK_READY = Object.freeze({
122
- status: "ready",
123
- runtime: { authBaseUrl: "", convexUrl: "" }
124
- });
125
273
  function CapxulProvider({
126
274
  config,
127
- publishableKey,
128
- browserConfig,
275
+ sessionStore,
129
276
  queryClient,
130
277
  children
131
278
  }) {
279
+ const defaultSessionStore = react.useMemo(() => createMemorySessionStore(), []);
280
+ const effectiveSessionStore = sessionStore ?? defaultSessionStore;
132
281
  const wiring = react.useMemo(
133
- () => buildWiring({ config, publishableKey, browserConfig }),
134
- [config, publishableKey, browserConfig]
282
+ () => buildWiring(config, effectiveSessionStore),
283
+ [config, effectiveSessionStore]
135
284
  );
285
+ react.useEffect(() => {
286
+ return () => {
287
+ wiring.dataClient?.close();
288
+ };
289
+ }, [wiring]);
136
290
  const defaultClient = react.useMemo(
137
291
  () => new reactQuery.QueryClient({
138
292
  defaultOptions: { queries: { staleTime: 3e4 } }
@@ -140,51 +294,60 @@ function CapxulProvider({
140
294
  []
141
295
  );
142
296
  const effectiveClient = queryClient ?? defaultClient;
143
- const inner = /* @__PURE__ */ jsxRuntime.jsx(CapxulClientProvider, { client: wiring.client, children });
144
- return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: effectiveClient, children: wiring.transport ? /* @__PURE__ */ jsxRuntime.jsx(CapxulTransportProvider, { transport: wiring.transport, children: inner }) : inner });
297
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: effectiveClient, children: /* @__PURE__ */ jsxRuntime.jsx(CapxulTransportProvider, { transport: wiring.transport, children: /* @__PURE__ */ jsxRuntime.jsx(CapxulClientProvider, { client: wiring.client, children }) }) });
145
298
  }
146
- function buildWiring({
147
- config,
148
- publishableKey,
149
- browserConfig
150
- }) {
151
- const sources = [
152
- config !== void 0,
153
- publishableKey !== void 0,
154
- browserConfig !== void 0
155
- ].filter(Boolean).length;
156
- if (sources === 0) {
157
- throw Errors.invalidInput(
158
- "CapxulProvider",
159
- "Pass exactly one of `config`, `publishableKey`, or `browserConfig`."
160
- );
161
- }
162
- if (sources > 1) {
163
- throw Errors.invalidInput(
164
- "CapxulProvider",
165
- "`config`, `publishableKey`, and `browserConfig` are mutually exclusive \u2014 pass exactly one."
166
- );
167
- }
168
- if (config !== void 0) {
169
- return {
170
- client: sdk.createCapxulClient(config),
171
- transport: null
172
- };
173
- }
174
- const browserCfg = browserConfig ?? {
175
- mode: "publishable-key",
176
- // The narrowing above (`sources === 0` rejected; `config` not
177
- // present) guarantees `publishableKey` is set on this branch.
178
- publishableKey
179
- };
180
- const transport = sdk.makeHttpTransport(browserCfg);
299
+ function buildWiring(config, sessionStore) {
300
+ const validated = createCapxulConfig(config);
301
+ const transport = sdk.makeHttpTransport(validated);
302
+ const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) : createLazyReactDataClient(transport, sessionStore);
181
303
  const sdkConfig = {
182
304
  _transport: transport,
183
- publishableKey: browserCfg.mode === "publishable-key" ? browserCfg.publishableKey : void 0
305
+ publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0,
306
+ data: dataClient ?? void 0,
307
+ auth: validated.mode === "build-time-urls" || validated.mode === "publishable-key" ? {
308
+ // The auth client builds the BetterAuth root URL from this
309
+ // value. Convex's `.cloud` URL is the wrong host (BetterAuth
310
+ // is mounted on the `.site` URL), but the build-time-urls
311
+ // transport already encodes the correct `authBaseUrl` via
312
+ // its discriminated union. We pass `convexUrl` here only so
313
+ // `core/auth.ts`'s `createTransportProvider` short-circuits
314
+ // to the externally-injected `_transport` cache slot.
315
+ baseUrl: transport.authBaseUrl,
316
+ sessionStore,
317
+ createDataClient: async (_session) => {
318
+ dataClient.refreshAuth();
319
+ return dataClient;
320
+ }
321
+ } : void 0
322
+ };
323
+ const client = sdk.createCapxulClient(sdkConfig);
324
+ if (dataClient) {
325
+ const originalSignOut = client.auth.signOut;
326
+ Object.assign(client.auth, {
327
+ signOut: async () => {
328
+ const result = await originalSignOut();
329
+ dataClient.refreshAuth();
330
+ sdkConfig.data = dataClient;
331
+ return result;
332
+ }
333
+ });
334
+ }
335
+ return {
336
+ client,
337
+ transport,
338
+ dataClient
184
339
  };
340
+ }
341
+ function createMemorySessionStore() {
342
+ let current = null;
185
343
  return {
186
- client: sdk.createCapxulClient(sdkConfig),
187
- transport
344
+ get: () => current,
345
+ set: (session) => {
346
+ current = session;
347
+ },
348
+ clear: () => {
349
+ current = null;
350
+ }
188
351
  };
189
352
  }
190
353
  function notImplementedQuery(hookName) {
@@ -274,8 +437,12 @@ function useMe() {
274
437
  staleTime: 3e4
275
438
  });
276
439
  }
277
- function useAccount(_accountId) {
278
- return notImplementedQuery("useAccount");
440
+ function useAccount(accountId) {
441
+ const capxul = useCapxul();
442
+ return useSdkQuery(
443
+ () => accountId !== void 0 ? capxul.accounts.retrieve(accountId) : capxul.me.get(),
444
+ [capxul, accountId]
445
+ );
279
446
  }
280
447
  function useOrganization(_organizationId) {
281
448
  return notImplementedQuery("useOrganization");
@@ -283,8 +450,12 @@ function useOrganization(_organizationId) {
283
450
  function useMember(_args) {
284
451
  return notImplementedQuery("useMember");
285
452
  }
286
- function useSafe(_safeId) {
287
- return notImplementedQuery("useSafe");
453
+ function useSafe(safeId) {
454
+ const capxul = useCapxul();
455
+ return useSdkQuery(
456
+ () => capxul.accounts.safes.retrieve(safeId),
457
+ [capxul, safeId]
458
+ );
288
459
  }
289
460
  function useTreasury(_organizationId) {
290
461
  return notImplementedQuery("useTreasury");
@@ -298,11 +469,22 @@ function useKycProfile(_accountId) {
298
469
  function useKybProfile(_organizationId) {
299
470
  return notImplementedQuery("useKybProfile");
300
471
  }
301
- function useExternalAccount(_args) {
302
- return notImplementedQuery("useExternalAccount");
472
+ function useExternalAccount(args) {
473
+ const capxul = useCapxul();
474
+ return useSdkQuery(
475
+ () => args.ownerKind === "account" ? capxul.externalAccounts.retrieve(args.externalAccountId) : capxul.organizations.externalAccounts.retrieve({
476
+ organizationId: args.ownerId,
477
+ externalAccountId: args.externalAccountId
478
+ }),
479
+ [capxul, args.ownerKind, args.ownerId, args.externalAccountId]
480
+ );
303
481
  }
304
- function useSubAccount(_subAccountId) {
305
- return notImplementedQuery("useSubAccount");
482
+ function useSubAccount(subAccountId) {
483
+ const capxul = useCapxul();
484
+ return useSdkQuery(
485
+ () => capxul.subAccounts.retrieve(subAccountId),
486
+ [capxul, subAccountId]
487
+ );
306
488
  }
307
489
  function useVirtualAccount(_virtualAccountId) {
308
490
  return notImplementedQuery("useVirtualAccount");
@@ -316,6 +498,13 @@ function usePayment(_paymentId) {
316
498
  function useTransfer(_transferId) {
317
499
  return notImplementedQuery("useTransfer");
318
500
  }
501
+ function useTokenTransfer(args) {
502
+ const capxul = useCapxul();
503
+ return useSdkQuery(
504
+ () => capxul.tokenTransfers.retrieve(args),
505
+ [capxul, args.txHash, args.logIndex, args.chainId]
506
+ );
507
+ }
319
508
  function useBalanceLedgerEntry(_args) {
320
509
  return notImplementedQuery("useBalanceLedgerEntry");
321
510
  }
@@ -350,11 +539,23 @@ function useOrganizations() {
350
539
  function useMembers(_organizationId) {
351
540
  return notImplementedQuery("useMembers");
352
541
  }
353
- function useExternalAccounts(_args) {
354
- return notImplementedQuery("useExternalAccounts");
542
+ function useExternalAccounts(args) {
543
+ const capxul = useCapxul();
544
+ return useSdkQuery(
545
+ () => args.ownerKind === "account" ? capxul.accounts.externalAccounts.list({ accountId: args.ownerId }) : capxul.organizations.externalAccounts.list({
546
+ organizationId: args.ownerId
547
+ }),
548
+ [capxul, args.ownerKind, args.ownerId]
549
+ );
355
550
  }
356
- function useSubAccounts(_args) {
357
- return notImplementedQuery("useSubAccounts");
551
+ function useSubAccounts(args) {
552
+ const capxul = useCapxul();
553
+ return useSdkQuery(
554
+ () => args.ownerKind === "account" ? capxul.accounts.subAccounts.list({ accountId: args.ownerId }) : capxul.organizations.subAccounts.list({
555
+ organizationId: args.ownerId
556
+ }),
557
+ [capxul, args.ownerKind, args.ownerId]
558
+ );
358
559
  }
359
560
  function useVirtualAccounts(_filters) {
360
561
  return notImplementedQuery("useVirtualAccounts");
@@ -374,6 +575,13 @@ function useTransfers(_filters) {
374
575
  function useOrgTransfers(_args) {
375
576
  return notImplementedQuery("useOrgTransfers");
376
577
  }
578
+ function useTokenTransfers(filters) {
579
+ const capxul = useCapxul();
580
+ return useSdkQuery(
581
+ () => capxul.tokenTransfers.list(filters),
582
+ [capxul, filters?.limit, filters?.cursor, filters?.direction]
583
+ );
584
+ }
377
585
  function useBalanceLedger(_args) {
378
586
  return notImplementedQuery("useBalanceLedger");
379
587
  }
@@ -409,6 +617,12 @@ function useAuthFlow() {
409
617
  const [snapshot, send] = react$1.useActor(machine);
410
618
  return { snapshot, send };
411
619
  }
620
+ function useAuthBootstrapFlow() {
621
+ const client = useCapxul();
622
+ const machine = react.useMemo(() => client.flows.authBootstrap(), [client]);
623
+ const [snapshot, send] = react$1.useActor(machine);
624
+ return { snapshot, send };
625
+ }
412
626
  function useOnboardingFlow() {
413
627
  const client = useCapxul();
414
628
  const machine = react.useMemo(() => client.flows.onboarding(), [client]);
@@ -421,56 +635,6 @@ function useProvisioningFlow() {
421
635
  const [snapshot, send] = react$1.useActor(machine);
422
636
  return { snapshot, send };
423
637
  }
424
-
425
- // src/config.ts
426
- function createCapxulConfig(input) {
427
- assertOnlyKnownKeys(input);
428
- assertModeRequiredFields(input);
429
- return Object.freeze({ ...input });
430
- }
431
- var ALLOWED_BROWSER_CONFIG_KEYS = [
432
- "mode",
433
- "authBaseUrl",
434
- "convexUrl",
435
- "publishableKey",
436
- "bootstrapUrl",
437
- "fetchImpl"
438
- ];
439
- function assertOnlyKnownKeys(input) {
440
- const candidate = input;
441
- const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
442
- const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
443
- if (unknown.length === 0) return;
444
- throw Errors.invalidInput(
445
- "config",
446
- `Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
447
- );
448
- }
449
- function assertModeRequiredFields(input) {
450
- switch (input.mode) {
451
- case "build-time-urls": {
452
- if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
453
- throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
454
- }
455
- if (!input.convexUrl || input.convexUrl.trim().length === 0) {
456
- throw Errors.invalidInput("convexUrl", "non-empty string required.");
457
- }
458
- return;
459
- }
460
- case "publishable-key": {
461
- if (!input.publishableKey || input.publishableKey.trim().length === 0) {
462
- throw Errors.invalidInput("publishableKey", "non-empty string required.");
463
- }
464
- return;
465
- }
466
- default: {
467
- const value = input;
468
- throw Errors.internalError(
469
- `Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
470
- );
471
- }
472
- }
473
- }
474
638
  var PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
475
639
  var EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;
476
640
  function injectedConnector(options = {}) {
@@ -576,6 +740,7 @@ exports.localPrivateKeyConnector = localPrivateKeyConnector;
576
740
  exports.useAccount = useAccount;
577
741
  exports.useApiKey = useApiKey;
578
742
  exports.useApiKeys = useApiKeys;
743
+ exports.useAuthBootstrapFlow = useAuthBootstrapFlow;
579
744
  exports.useAuthFlow = useAuthFlow;
580
745
  exports.useBalanceLedger = useBalanceLedger;
581
746
  exports.useBalanceLedgerEntry = useBalanceLedgerEntry;
@@ -604,6 +769,8 @@ exports.useProvisioningFlow = useProvisioningFlow;
604
769
  exports.useSafe = useSafe;
605
770
  exports.useSubAccount = useSubAccount;
606
771
  exports.useSubAccounts = useSubAccounts;
772
+ exports.useTokenTransfer = useTokenTransfer;
773
+ exports.useTokenTransfers = useTokenTransfers;
607
774
  exports.useTransfer = useTransfer;
608
775
  exports.useTransfers = useTransfers;
609
776
  exports.useTreasury = useTreasury;