@capxul/sdk-react 0.1.0-alpha.0 → 0.1.0-alpha.10

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