@capxul/sdk-react 0.2.0-alpha.3 → 0.2.0-alpha.5

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 DELETED
@@ -1,1086 +0,0 @@
1
- "use client";
2
- import { createContext, useContext, useSyncExternalStore, useMemo, useEffect, useState, useCallback } from 'react';
3
- import { makeHttpTransport, createCapxulClient, AuthService, CapxulError as CapxulError$1, SignerProvisioner, toUsername } from '@capxul/sdk';
4
- import { QueryClient, QueryClientProvider, useQuery, useMutation } from '@tanstack/react-query';
5
- import { jsx } from 'react/jsx-runtime';
6
- import { ConvexReactClient } from 'convex/react';
7
- import { CapxulError as CapxulError$2 } from '@capxul/sdk/errors';
8
- import { useActor } from '@xstate/react';
9
- import { getAddress } from 'viem';
10
- import { privateKeyToAccount } from 'viem/accounts';
11
-
12
- // src/provider.tsx
13
- var AuthServiceContext = createContext(null);
14
- function AuthServiceProvider({
15
- authService,
16
- children
17
- }) {
18
- return /* @__PURE__ */ jsx(AuthServiceContext.Provider, { value: authService, children });
19
- }
20
- function useAuthService() {
21
- const authService = useContext(AuthServiceContext);
22
- if (!authService) {
23
- throw new Error(
24
- "useAuthService() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
25
- );
26
- }
27
- return authService;
28
- }
29
- var CapxulClientContext = createContext(null);
30
- function CapxulClientProvider({
31
- client,
32
- children
33
- }) {
34
- return /* @__PURE__ */ jsx(CapxulClientContext.Provider, { value: client, children });
35
- }
36
- function useCapxul() {
37
- const client = useContext(CapxulClientContext);
38
- if (!client) {
39
- throw new Error(
40
- "useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
41
- );
42
- }
43
- return client;
44
- }
45
- var CapxulTransportContext = createContext(null);
46
- function CapxulTransportProvider({
47
- transport,
48
- children
49
- }) {
50
- return /* @__PURE__ */ jsx(CapxulTransportContext.Provider, { value: transport, children });
51
- }
52
- function useCapxulStatus() {
53
- const transport = useContext(CapxulTransportContext);
54
- return useSyncExternalStore(
55
- (listener) => {
56
- if (!transport) return () => {
57
- };
58
- return transport.subscribe(listener);
59
- },
60
- () => transport?.getState() ?? FALLBACK_READY,
61
- () => transport?.getState() ?? FALLBACK_READY
62
- );
63
- }
64
- var FALLBACK_READY = Object.freeze({
65
- status: "ready",
66
- runtime: { authBaseUrl: "", convexUrl: "" }
67
- });
68
-
69
- // ../config/src/errors.ts
70
- var CapxulError = class extends Error {
71
- code;
72
- details;
73
- correlationId;
74
- layer;
75
- constructor(code, message, options) {
76
- super(message, options?.cause ? { cause: options.cause } : void 0);
77
- this.code = code;
78
- this.details = options?.details;
79
- this.correlationId = options?.correlationId;
80
- this.layer = options?.layer;
81
- }
82
- };
83
- var Errors = {
84
- notAuthenticated: () => new CapxulError("NOT_AUTHENTICATED", "Not authenticated"),
85
- profileNotFound: (authUserId) => new CapxulError("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`),
86
- smartAccountMissing: (authUserId) => new CapxulError("SMART_ACCOUNT_MISSING", `Smart account not provisioned for user ${authUserId}`),
87
- envMissing: (name) => new CapxulError("ENV_MISSING", `Environment variable ${name} not configured`),
88
- openfortApi: (operation, cause) => new CapxulError(
89
- "PROVIDER_ERROR",
90
- `Openfort ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
91
- { cause, details: { provider: "openfort", operation } }
92
- ),
93
- shieldApi: (status, detail) => new CapxulError(
94
- "PROVIDER_ERROR",
95
- `Shield API error (${status}): ${detail}`,
96
- { details: { provider: "shield", status } }
97
- ),
98
- providerError: (provider, operation, cause) => (
99
- // Public `message` is redacted to a fixed shape so provider-side
100
- // exception text never leaks to the client. The original `cause`
101
- // is preserved on `Error.cause` for server-side debugging via
102
- // observability sinks (Sentry, console traces).
103
- new CapxulError(
104
- "PROVIDER_ERROR",
105
- `Provider error: ${provider} ${operation}`,
106
- { cause, details: { provider, operation } }
107
- )
108
- ),
109
- invalidInput: (field, reason) => new CapxulError(
110
- "INVALID_INPUT",
111
- `Invalid ${field}: ${reason}`,
112
- { details: { field, reason } }
113
- ),
114
- playerNotFound: (playerId) => new CapxulError(
115
- "PLAYER_NOT_FOUND",
116
- playerId ? `Openfort player ${playerId} not found` : "Openfort player not found"
117
- ),
118
- accountNotFound: (accountId) => new CapxulError(
119
- "ACCOUNT_NOT_FOUND",
120
- accountId ? `Openfort account ${accountId} not found` : "Openfort smart account not found"
121
- ),
122
- invalidRecipient: (reason) => new CapxulError("INVALID_RECIPIENT", reason),
123
- permissionDenied: (reason = "Permission denied") => new CapxulError("PERMISSION_DENIED", reason),
124
- notFound: (resource, id) => new CapxulError(
125
- "NOT_FOUND",
126
- id ? `${resource} ${id} not found` : `${resource} not found`
127
- ),
128
- idempotencyConflict: (details) => new CapxulError(
129
- "IDEMPOTENCY_CONFLICT",
130
- "Idempotency key was already used for a different request",
131
- { details }
132
- ),
133
- emailDeliveryFailed: (detail, details) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
134
- details
135
- }),
136
- rateLimited: (details) => new CapxulError("RATE_LIMITED", "Request was rate limited", {
137
- details: { ...details }
138
- }),
139
- internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`),
140
- /**
141
- * Verification gate. Surfaced when a request hits a verification
142
- * boundary the actor cannot cross under their current state. Two
143
- * variants share this code:
144
- *
145
- * - Rail gate (Withdrawals v1 W2, #465): the resolved
146
- * `external_account.kind` routes to a withdrawal rail (e.g.
147
- * `fiat_offramp`, `card_payout`) that is not yet supported. Carries
148
- * `details.rail` + `details.currentKind`.
149
- * - KYC tier gate (legacy / future): the actor's KYC tier is below
150
- * the required tier. Carries `details.requiredTier`.
151
- *
152
- * Code is shared because both expose the same UX shape ("you cannot
153
- * proceed until verification advances"); the `details.*` keys
154
- * differentiate the route.
155
- */
156
- verificationRequired: (details) => {
157
- const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
158
- return new CapxulError("VERIFICATION_REQUIRED", message, {
159
- details: { ...details }
160
- });
161
- }
162
- };
163
-
164
- // ../config/src/org-roles.ts
165
- function roleKeyFromLabel(label) {
166
- const bytes = new TextEncoder().encode(label);
167
- const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
168
- return "0x" + hex.padEnd(64, "0");
169
- }
170
- roleKeyFromLabel("OWNER");
171
- roleKeyFromLabel("FINANCE_MANAGER");
172
- roleKeyFromLabel("PAYMENTS_OPERATOR");
173
-
174
- // src/config.ts
175
- function createCapxulConfig(input) {
176
- assertOnlyKnownKeys(input);
177
- assertModeRequiredFields(input);
178
- return Object.freeze({ ...input });
179
- }
180
- var ALLOWED_BROWSER_CONFIG_KEYS = [
181
- "mode",
182
- "authBaseUrl",
183
- "convexUrl",
184
- "publishableKey",
185
- "bootstrapUrl",
186
- "fetchImpl"
187
- ];
188
- function assertOnlyKnownKeys(input) {
189
- const candidate = input;
190
- const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
191
- const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
192
- if (unknown.length === 0) return;
193
- throw Errors.invalidInput(
194
- "config",
195
- `Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
196
- );
197
- }
198
- function assertModeRequiredFields(input) {
199
- switch (input.mode) {
200
- case "build-time-urls": {
201
- if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
202
- throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
203
- }
204
- if (!input.convexUrl || input.convexUrl.trim().length === 0) {
205
- throw Errors.invalidInput("convexUrl", "non-empty string required.");
206
- }
207
- return;
208
- }
209
- case "publishable-key": {
210
- if (!input.publishableKey || input.publishableKey.trim().length === 0) {
211
- throw Errors.invalidInput("publishableKey", "non-empty string required.");
212
- }
213
- return;
214
- }
215
- default: {
216
- const value = input;
217
- throw Errors.internalError(
218
- `Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
219
- );
220
- }
221
- }
222
- }
223
- function createReactDataClient(convexUrl, sessionStore) {
224
- const client = new ConvexReactClient(convexUrl);
225
- const refreshAuth = () => {
226
- const session = sessionStore.get();
227
- const jwt = session?.convexJwt;
228
- if (jwt) {
229
- client.setAuth(() => Promise.resolve(jwt));
230
- } else {
231
- client.clearAuth();
232
- }
233
- };
234
- refreshAuth();
235
- return {
236
- query: (name, args) => client.query(name, args),
237
- mutation: (name, args) => client.mutation(name, args),
238
- action: (name, args) => client.action(name, args),
239
- refreshAuth,
240
- close: () => {
241
- void client.close();
242
- }
243
- };
244
- }
245
- function createLazyReactDataClient(transport, sessionStore, createClient = createReactDataClient) {
246
- let client = null;
247
- let initializeClient = null;
248
- let closed = false;
249
- function closedError() {
250
- return new Error("Capxul React data client is closed");
251
- }
252
- async function getClient() {
253
- if (closed) throw closedError();
254
- if (client) return client;
255
- initializeClient ??= (async () => {
256
- const runtime = await transport.ensureRuntime();
257
- if (closed) throw closedError();
258
- const nextClient = createClient(runtime.convexUrl, sessionStore);
259
- if (closed) {
260
- nextClient.close();
261
- throw closedError();
262
- }
263
- client = nextClient;
264
- return nextClient;
265
- })().catch((error) => {
266
- if (!closed) {
267
- initializeClient = null;
268
- }
269
- throw error;
270
- });
271
- return initializeClient;
272
- }
273
- return {
274
- query: async (name, args) => (await getClient()).query(name, args),
275
- mutation: async (name, args) => (await getClient()).mutation(name, args),
276
- action: async (name, args) => (await getClient()).action?.(name, args),
277
- refreshAuth: () => {
278
- client?.refreshAuth();
279
- },
280
- close: () => {
281
- closed = true;
282
- client?.close();
283
- client = null;
284
- }
285
- };
286
- }
287
- function CapxulProvider({
288
- config,
289
- sessionStore,
290
- queryClient,
291
- children
292
- }) {
293
- const defaultSessionStore = useMemo(() => createMemorySessionStore(), []);
294
- const effectiveSessionStore = sessionStore ?? defaultSessionStore;
295
- const wiring = useMemo(
296
- () => buildWiring(config, effectiveSessionStore),
297
- [config, effectiveSessionStore]
298
- );
299
- useEffect(() => {
300
- return () => {
301
- wiring.dataClient?.close();
302
- };
303
- }, [wiring]);
304
- const defaultClient = useMemo(
305
- () => new QueryClient({
306
- defaultOptions: { queries: { staleTime: 3e4 } }
307
- }),
308
- []
309
- );
310
- const effectiveClient = queryClient ?? defaultClient;
311
- return /* @__PURE__ */ jsx(QueryClientProvider, { client: effectiveClient, children: /* @__PURE__ */ jsx(CapxulTransportProvider, { transport: wiring.transport, children: /* @__PURE__ */ jsx(CapxulClientProvider, { client: wiring.client, children: /* @__PURE__ */ jsx(AuthServiceProvider, { authService: wiring.authService, children }) }) }) });
312
- }
313
- function buildWiring(config, sessionStore) {
314
- const validated = createCapxulConfig(config);
315
- const transport = makeHttpTransport(validated);
316
- const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) : createLazyReactDataClient(transport, sessionStore);
317
- const sdkConfig = {
318
- _transport: transport,
319
- publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0,
320
- _data: dataClient ?? void 0,
321
- auth: validated.mode === "build-time-urls" || validated.mode === "publishable-key" ? {
322
- // The auth client builds the BetterAuth root URL from this
323
- // value. Convex's `.cloud` URL is the wrong host (BetterAuth
324
- // is mounted on the `.site` URL), but the build-time-urls
325
- // transport already encodes the correct `authBaseUrl` via
326
- // its discriminated union. We pass `convexUrl` here only so
327
- // `core/auth.ts`'s `createTransportProvider` short-circuits
328
- // to the externally-injected `_transport` cache slot.
329
- baseUrl: transport.authBaseUrl,
330
- sessionStore
331
- } : void 0
332
- };
333
- const client = createCapxulClient(sdkConfig);
334
- const authService = new AuthService(sdkConfig);
335
- return {
336
- client,
337
- transport,
338
- dataClient,
339
- authService
340
- };
341
- }
342
- function createMemorySessionStore() {
343
- let current = null;
344
- return {
345
- get: () => current,
346
- set: (session) => {
347
- current = session;
348
- },
349
- clear: () => {
350
- current = null;
351
- }
352
- };
353
- }
354
- function notImplementedQuery(hookName) {
355
- return {
356
- status: "error",
357
- error: new CapxulError$2({
358
- code: "NOT_IMPLEMENTED",
359
- message: `${hookName} is not yet implemented in @capxul/sdk-react. The hook remains a reset placeholder until its vertical lands per sdk-surface.md \xA73b.`
360
- })
361
- };
362
- }
363
- function useSdkQuery(read, dependencies) {
364
- const [state, setState] = useState({
365
- dependencies,
366
- result: { status: "loading" }
367
- });
368
- const dependenciesChanged = didDependenciesChange(
369
- state.dependencies,
370
- dependencies
371
- );
372
- useEffect(() => {
373
- let active = true;
374
- setState({ dependencies, result: { status: "loading" } });
375
- void read().then(([error, data]) => {
376
- if (!active) {
377
- return;
378
- }
379
- if (error) {
380
- setState({ dependencies, result: { status: "error", error } });
381
- return;
382
- }
383
- setState({ dependencies, result: { status: "data", data } });
384
- }).catch((cause) => {
385
- if (!active) {
386
- return;
387
- }
388
- setState({
389
- dependencies,
390
- result: {
391
- status: "error",
392
- error: cause instanceof CapxulError$2 ? cause : new CapxulError$2({
393
- code: "UNKNOWN",
394
- message: "SDK read failed before returning a CapxulResult.",
395
- cause
396
- })
397
- }
398
- });
399
- });
400
- return () => {
401
- active = false;
402
- };
403
- }, dependencies);
404
- if (dependenciesChanged) {
405
- return { status: "loading" };
406
- }
407
- return state.result;
408
- }
409
- function didDependenciesChange(previous, next) {
410
- if (previous.length !== next.length) {
411
- return true;
412
- }
413
- return previous.some((previousDependency, index) => {
414
- return !Object.is(previousDependency, next[index]);
415
- });
416
- }
417
-
418
- // src/hooks/singular.ts
419
- function useMe() {
420
- const capxul = useCapxul();
421
- return useQuery({
422
- queryKey: [capxul.id, "capxul", "me"],
423
- queryFn: () => capxul.me.get().then(([error, data]) => {
424
- if (error) {
425
- throw error;
426
- }
427
- return data;
428
- }).catch((cause) => {
429
- if (cause instanceof CapxulError$1) {
430
- throw cause;
431
- }
432
- throw new CapxulError$1({
433
- code: "UNKNOWN",
434
- message: "SDK read failed before returning a CapxulResult.",
435
- cause
436
- });
437
- }),
438
- staleTime: 3e4
439
- });
440
- }
441
- function useAccount(accountId) {
442
- const capxul = useCapxul();
443
- return useSdkQuery(
444
- () => accountId !== void 0 ? capxul.accounts.retrieve(accountId) : capxul.me.get(),
445
- [capxul, accountId]
446
- );
447
- }
448
- function useOrganization(organizationId) {
449
- const capxul = useCapxul();
450
- return useQuery({
451
- queryKey: [capxul.id, "capxul", "organizations", organizationId],
452
- queryFn: () => capxul.organizations.retrieve(organizationId).then(([error, data]) => {
453
- if (error) {
454
- throw error;
455
- }
456
- return data;
457
- }).catch((cause) => {
458
- if (cause instanceof CapxulError$1) {
459
- throw cause;
460
- }
461
- throw new CapxulError$1({
462
- code: "UNKNOWN",
463
- message: "SDK read failed before returning a CapxulResult.",
464
- cause
465
- });
466
- }),
467
- staleTime: 3e4
468
- });
469
- }
470
- function useMember(args) {
471
- const capxul = useCapxul();
472
- return useQuery({
473
- queryKey: [
474
- capxul.id,
475
- "capxul",
476
- "organizations",
477
- args.organizationId,
478
- "members",
479
- args.memberId
480
- ],
481
- queryFn: () => capxul.organizations.members.retrieve({
482
- organizationId: args.organizationId,
483
- memberId: args.memberId
484
- }).then(([error, data]) => {
485
- if (error) {
486
- throw error;
487
- }
488
- return data;
489
- }).catch((cause) => {
490
- if (cause instanceof CapxulError$1) {
491
- throw cause;
492
- }
493
- throw new CapxulError$1({
494
- code: "UNKNOWN",
495
- message: "SDK read failed before returning a CapxulResult.",
496
- cause
497
- });
498
- }),
499
- staleTime: 3e4
500
- });
501
- }
502
- function useSafe(safeId) {
503
- const capxul = useCapxul();
504
- return useSdkQuery(
505
- () => capxul.accounts.safes.retrieve(safeId),
506
- [capxul, safeId]
507
- );
508
- }
509
- function useTreasury(organizationId) {
510
- const capxul = useCapxul();
511
- return useQuery({
512
- queryKey: [
513
- capxul.id,
514
- "capxul",
515
- "organizations",
516
- organizationId,
517
- "treasury"
518
- ],
519
- queryFn: () => capxul.organizations.treasury.retrieve(organizationId).then(([error, data]) => {
520
- if (error) {
521
- throw error;
522
- }
523
- return data;
524
- }).catch((cause) => {
525
- if (cause instanceof CapxulError$1) {
526
- throw cause;
527
- }
528
- throw new CapxulError$1({
529
- code: "UNKNOWN",
530
- message: "SDK read failed before returning a CapxulResult.",
531
- cause
532
- });
533
- }),
534
- staleTime: 3e4
535
- });
536
- }
537
- function useApiKey(_args) {
538
- return notImplementedQuery("useApiKey");
539
- }
540
- function useKycProfile(_accountId) {
541
- return notImplementedQuery("useKycProfile");
542
- }
543
- function useExternalAccount(args) {
544
- const capxul = useCapxul();
545
- return useSdkQuery(
546
- () => args.ownerKind === "account" ? capxul.externalAccounts.retrieve(args.externalAccountId) : capxul.organizations.externalAccounts.retrieve({
547
- organizationId: args.ownerId,
548
- externalAccountId: args.externalAccountId
549
- }),
550
- [capxul, args.ownerKind, args.ownerId, args.externalAccountId]
551
- );
552
- }
553
- function useSubAccount(subAccountId) {
554
- const capxul = useCapxul();
555
- return useSdkQuery(
556
- () => capxul.subAccounts.retrieve(subAccountId),
557
- [capxul, subAccountId]
558
- );
559
- }
560
- function useVirtualAccount(_virtualAccountId) {
561
- return notImplementedQuery("useVirtualAccount");
562
- }
563
- function useVirtualCard(_virtualCardId) {
564
- return notImplementedQuery("useVirtualCard");
565
- }
566
- function usePayment(paymentId) {
567
- const capxul = useCapxul();
568
- return useQuery({
569
- queryKey: [capxul.id, "capxul", "payments", paymentId],
570
- queryFn: () => capxul.payments.retrieve(paymentId).then(([error, data]) => {
571
- if (error) {
572
- throw error;
573
- }
574
- return data;
575
- }).catch((cause) => {
576
- if (cause instanceof CapxulError$1) {
577
- throw cause;
578
- }
579
- throw new CapxulError$1({
580
- code: "UNKNOWN",
581
- message: "SDK read failed before returning a CapxulResult.",
582
- cause
583
- });
584
- }),
585
- staleTime: 3e4
586
- });
587
- }
588
- function useTransfer(_transferId) {
589
- return notImplementedQuery("useTransfer");
590
- }
591
- function useTokenTransfer(args) {
592
- const capxul = useCapxul();
593
- return useSdkQuery(
594
- () => capxul.tokenTransfers.retrieve(args),
595
- [capxul, args.txHash, args.logIndex, args.chainId]
596
- );
597
- }
598
- function useBalanceLedgerEntry(args) {
599
- const capxul = useCapxul();
600
- return useSdkQuery(
601
- () => args.ownerKind === "account" ? capxul.accounts.balanceLedger.retrieve(args.entryId) : capxul.organizations.balanceLedger.retrieve({
602
- organizationId: args.ownerId,
603
- entryId: args.entryId
604
- }),
605
- [capxul, args.ownerKind, args.ownerId, args.entryId]
606
- );
607
- }
608
- function useDocument(_documentId) {
609
- return notImplementedQuery("useDocument");
610
- }
611
- function useWithdrawal(withdrawalId) {
612
- const capxul = useCapxul();
613
- return useSdkQuery(
614
- () => capxul.withdrawals.retrieve(withdrawalId),
615
- [capxul, withdrawalId]
616
- );
617
- }
618
- function useOperation(operationId) {
619
- const capxul = useCapxul();
620
- return useSdkQuery(
621
- () => capxul.operations.retrieve(operationId),
622
- [capxul, operationId]
623
- );
624
- }
625
- function useWebhookEndpoint(_endpointId) {
626
- return notImplementedQuery("useWebhookEndpoint");
627
- }
628
- function useWebhookEvent(_eventId) {
629
- return notImplementedQuery("useWebhookEvent");
630
- }
631
- function useOrganizations(filters) {
632
- const capxul = useCapxul();
633
- return useQuery({
634
- queryKey: [capxul.id, "capxul", "organizations", "list", filters],
635
- queryFn: () => capxul.organizations.list(filters).then(([error, data]) => {
636
- if (error) {
637
- throw error;
638
- }
639
- return data;
640
- }).catch((cause) => {
641
- if (cause instanceof CapxulError$1) {
642
- throw cause;
643
- }
644
- throw new CapxulError$1({
645
- code: "UNKNOWN",
646
- message: "SDK read failed before returning a CapxulResult.",
647
- cause
648
- });
649
- }),
650
- staleTime: 3e4
651
- });
652
- }
653
- function useMembers(organizationId, filters) {
654
- const capxul = useCapxul();
655
- return useQuery({
656
- queryKey: [
657
- capxul.id,
658
- "capxul",
659
- "organizations",
660
- organizationId,
661
- "members",
662
- "list",
663
- filters?.status
664
- ],
665
- queryFn: () => capxul.organizations.members.list({ organizationId, status: filters?.status }).then(([error, data]) => {
666
- if (error) {
667
- throw error;
668
- }
669
- return data;
670
- }).catch((cause) => {
671
- if (cause instanceof CapxulError$1) {
672
- throw cause;
673
- }
674
- throw new CapxulError$1({
675
- code: "UNKNOWN",
676
- message: "SDK read failed before returning a CapxulResult.",
677
- cause
678
- });
679
- }),
680
- staleTime: 3e4
681
- });
682
- }
683
- function useExternalAccounts(args) {
684
- const capxul = useCapxul();
685
- return useSdkQuery(
686
- () => args.ownerKind === "account" ? capxul.accounts.externalAccounts.list({ accountId: args.ownerId }) : capxul.organizations.externalAccounts.list({
687
- organizationId: args.ownerId
688
- }),
689
- [capxul, args.ownerKind, args.ownerId]
690
- );
691
- }
692
- function useSubAccounts(args) {
693
- const capxul = useCapxul();
694
- return useSdkQuery(
695
- () => args.ownerKind === "account" ? capxul.accounts.subAccounts.list({ accountId: args.ownerId }) : capxul.organizations.subAccounts.list({
696
- organizationId: args.ownerId
697
- }),
698
- [capxul, args.ownerKind, args.ownerId]
699
- );
700
- }
701
- function useVirtualAccounts(_filters) {
702
- return notImplementedQuery("useVirtualAccounts");
703
- }
704
- function useVirtualCards(_filters) {
705
- return notImplementedQuery("useVirtualCards");
706
- }
707
- function usePayments(filters) {
708
- const capxul = useCapxul();
709
- return useQuery({
710
- queryKey: [capxul.id, "capxul", "payments", "list", filters],
711
- queryFn: () => capxul.payments.list(filters).then(([error, data]) => {
712
- if (error) {
713
- throw error;
714
- }
715
- return data;
716
- }).catch((cause) => {
717
- if (cause instanceof CapxulError$1) {
718
- throw cause;
719
- }
720
- throw new CapxulError$1({
721
- code: "UNKNOWN",
722
- message: "SDK read failed before returning a CapxulResult.",
723
- cause
724
- });
725
- }),
726
- staleTime: 3e4
727
- });
728
- }
729
- function useOrgPayments(_args) {
730
- return notImplementedQuery("useOrgPayments");
731
- }
732
- function useTransfers(_filters) {
733
- return notImplementedQuery("useTransfers");
734
- }
735
- function useOrgTransfers(_args) {
736
- return notImplementedQuery("useOrgTransfers");
737
- }
738
- function useTokenTransfers(filters) {
739
- const capxul = useCapxul();
740
- return useSdkQuery(
741
- () => capxul.tokenTransfers.list(filters),
742
- [capxul, filters?.limit, filters?.cursor, filters?.direction]
743
- );
744
- }
745
- function useBalanceLedger(args) {
746
- const capxul = useCapxul();
747
- return useSdkQuery(
748
- () => args.ownerKind === "account" ? capxul.accounts.balanceLedger.list({
749
- accountId: args.ownerId,
750
- limit: args.limit,
751
- cursor: args.cursor
752
- }) : capxul.organizations.balanceLedger.list({
753
- organizationId: args.ownerId,
754
- limit: args.limit,
755
- cursor: args.cursor
756
- }),
757
- [capxul, args.ownerKind, args.ownerId, args.limit, args.cursor]
758
- );
759
- }
760
- function useAccountBalanceLedger(accountId, filters) {
761
- const capxul = useCapxul();
762
- return useSdkQuery(
763
- () => capxul.accounts.balanceLedger.list({ accountId, ...filters }),
764
- [capxul, accountId, filters?.limit, filters?.cursor]
765
- );
766
- }
767
- function useOrgBalanceLedger(args) {
768
- const capxul = useCapxul();
769
- return useSdkQuery(
770
- () => capxul.organizations.balanceLedger.list(args),
771
- [capxul, args.organizationId, args.limit, args.cursor]
772
- );
773
- }
774
- function useDocuments(_filters) {
775
- return notImplementedQuery("useDocuments");
776
- }
777
- function useOrgDocuments(_args) {
778
- return notImplementedQuery("useOrgDocuments");
779
- }
780
- function useWithdrawals(filters) {
781
- const capxul = useCapxul();
782
- return useSdkQuery(
783
- () => capxul.withdrawals.list(filters),
784
- [capxul, filters?.limit, filters?.cursor]
785
- );
786
- }
787
- function useOrgWithdrawals(args) {
788
- const capxul = useCapxul();
789
- return useSdkQuery(
790
- () => capxul.organizations.withdrawals.list(args),
791
- [capxul, args.organizationId, args.limit, args.cursor]
792
- );
793
- }
794
- function useApiKeys(_organizationId) {
795
- return notImplementedQuery("useApiKeys");
796
- }
797
- function useWebhookEndpoints() {
798
- return notImplementedQuery("useWebhookEndpoints");
799
- }
800
- function useInviteMember() {
801
- const capxul = useCapxul();
802
- return useMutation({
803
- mutationFn: async (args) => {
804
- const [error, data] = await capxul.organizations.members.invite(args);
805
- if (error) throw error;
806
- return data;
807
- }
808
- });
809
- }
810
- function useAcceptInvitation() {
811
- const capxul = useCapxul();
812
- return useMutation({
813
- mutationFn: async (args) => {
814
- const [error, data] = await capxul.organizations.members.accept(args);
815
- if (error) throw error;
816
- return data;
817
- }
818
- });
819
- }
820
- function useUpdateMemberRole() {
821
- const capxul = useCapxul();
822
- return useMutation({
823
- mutationFn: async (args) => {
824
- const [error, data] = await capxul.organizations.members.updateRole(args);
825
- if (error) throw error;
826
- return data;
827
- }
828
- });
829
- }
830
- function useRevokeMember() {
831
- const capxul = useCapxul();
832
- return useMutation({
833
- mutationFn: async (args) => {
834
- const [error, data] = await capxul.organizations.members.revoke(args);
835
- if (error) throw error;
836
- return data;
837
- }
838
- });
839
- }
840
- function useRemoveMember() {
841
- const capxul = useCapxul();
842
- return useMutation({
843
- mutationFn: async (args) => {
844
- const [error, data] = await capxul.organizations.members.remove(args);
845
- if (error) throw error;
846
- return data;
847
- }
848
- });
849
- }
850
- function useResendInvitation() {
851
- const capxul = useCapxul();
852
- return useMutation({
853
- mutationFn: async (args) => {
854
- const [error, data] = await capxul.organizations.members.resend(args);
855
- if (error) throw error;
856
- return data;
857
- }
858
- });
859
- }
860
- function useAuth(options) {
861
- const authService = useAuthService();
862
- const signerProvisioner = useMemoizedSignerProvisioner();
863
- const injectedSigner = options?.signer;
864
- const [state, setState] = useState("idle");
865
- const [user, setUser] = useState(null);
866
- const [error, setError] = useState(null);
867
- const signIn = useCallback(
868
- async (email) => {
869
- setState("sendingOtp");
870
- setError(null);
871
- try {
872
- await authService.sendOtp(email);
873
- setState("awaitingOtp");
874
- } catch (err) {
875
- const wrapped = err instanceof Error ? err : new Error(String(err));
876
- setError(wrapped);
877
- setState("error");
878
- throw wrapped;
879
- }
880
- },
881
- [authService]
882
- );
883
- const verifyOtp = useCallback(
884
- async (email, otp) => {
885
- setState("awaitingOtp");
886
- setError(null);
887
- try {
888
- const result = await authService.verifyOtp(email, otp);
889
- if (result.kind === "existing_member") {
890
- const nextUser2 = {
891
- account: result.account,
892
- username: result.username,
893
- safe: result.safe,
894
- session: result.session
895
- };
896
- setUser(nextUser2);
897
- setState("authenticated");
898
- return result.session;
899
- }
900
- setState("bootstrapping");
901
- const signer = injectedSigner ?? signerProvisioner.provision().signer;
902
- const username = result.username ?? generateUsernameFromEmail(result.email);
903
- const bootstrapResult = await authService.completeBootstrap(
904
- {
905
- bootstrapToken: result.bootstrapToken,
906
- username
907
- },
908
- signer
909
- );
910
- const nextUser = {
911
- account: bootstrapResult.account,
912
- username: bootstrapResult.username,
913
- safe: bootstrapResult.safe,
914
- session: bootstrapResult.session
915
- };
916
- setUser(nextUser);
917
- setState("authenticated");
918
- return bootstrapResult.session;
919
- } catch (err) {
920
- const wrapped = err instanceof Error ? err : new Error(String(err));
921
- setError(wrapped);
922
- setState("error");
923
- throw wrapped;
924
- }
925
- },
926
- [authService, signerProvisioner, injectedSigner]
927
- );
928
- const signOut = useCallback(async () => {
929
- setError(null);
930
- try {
931
- await authService.signOut();
932
- setUser(null);
933
- setState("idle");
934
- } catch (err) {
935
- const wrapped = err instanceof Error ? err : new Error(String(err));
936
- setError(wrapped);
937
- setState("error");
938
- throw wrapped;
939
- }
940
- }, [authService]);
941
- return useMemo(
942
- () => ({
943
- state,
944
- user,
945
- error,
946
- signIn,
947
- verifyOtp,
948
- signOut
949
- }),
950
- [state, user, error, signIn, verifyOtp, signOut]
951
- );
952
- }
953
- function useMemoizedSignerProvisioner() {
954
- const [provisioner] = useState(() => new SignerProvisioner());
955
- return provisioner;
956
- }
957
- function generateUsernameFromEmail(email) {
958
- const local = email.split("@")[0]?.toLowerCase() ?? "user";
959
- let sanitized = local.replace(/[^a-z0-9_-]/g, "_");
960
- if (/^[0-9]/.test(sanitized)) {
961
- sanitized = "u" + sanitized;
962
- }
963
- if (sanitized.length < 3) {
964
- sanitized = sanitized + "_".repeat(3 - sanitized.length);
965
- }
966
- if (sanitized.length > 30) {
967
- sanitized = sanitized.slice(0, 30);
968
- }
969
- try {
970
- return toUsername(sanitized);
971
- } catch {
972
- const fallback = `user_${Date.now() % 1e6}`;
973
- return toUsername(fallback);
974
- }
975
- }
976
- function useAuthFlow() {
977
- const client = useCapxul();
978
- const machine = useMemo(() => client.flows.auth(), [client]);
979
- const [snapshot, send] = useActor(machine);
980
- return { snapshot, send };
981
- }
982
- function useAuthBootstrapFlow() {
983
- const client = useCapxul();
984
- const machine = useMemo(() => client.flows.authBootstrap(), [client]);
985
- const [snapshot, send] = useActor(machine);
986
- return { snapshot, send };
987
- }
988
- function useOnboardingFlow() {
989
- const client = useCapxul();
990
- const machine = useMemo(() => client.flows.onboarding(), [client]);
991
- const [snapshot, send] = useActor(machine);
992
- return { snapshot, send };
993
- }
994
- function useProvisioningFlow() {
995
- const client = useCapxul();
996
- const machine = useMemo(() => client.flows.provisioning(), [client]);
997
- const [snapshot, send] = useActor(machine);
998
- return { snapshot, send };
999
- }
1000
- var PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
1001
- var EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;
1002
- function injectedConnector(options = {}) {
1003
- const id = options.id ?? "injected";
1004
- return {
1005
- id,
1006
- name: options.name ?? "Injected wallet",
1007
- kind: "injected",
1008
- async connect() {
1009
- const provider = readInjectedProvider();
1010
- const result = await provider.request({
1011
- method: "eth_requestAccounts"
1012
- });
1013
- const accounts = Array.isArray(result) ? result : void 0;
1014
- const rawSignerAddress = accounts?.[0];
1015
- if (rawSignerAddress === void 0 || rawSignerAddress === null) {
1016
- throw Errors.providerError(
1017
- "connector",
1018
- "injected",
1019
- new Error("Injected wallet did not return an account.")
1020
- );
1021
- }
1022
- const signerAddress = validateAndNormalizeEvmAddress(
1023
- "signerAddress",
1024
- rawSignerAddress
1025
- );
1026
- return {
1027
- connectorId: id,
1028
- connectorKind: "injected",
1029
- signerAddress
1030
- };
1031
- }
1032
- };
1033
- }
1034
- function localPrivateKeyConnector(options) {
1035
- if (!options.privateKey || !PRIVATE_KEY_PATTERN.test(options.privateKey)) {
1036
- throw Errors.invalidInput(
1037
- "privateKey",
1038
- "must be a 0x-prefixed 32-byte (64 hex chars) string."
1039
- );
1040
- }
1041
- const id = options.id ?? "local-private-key";
1042
- return {
1043
- id,
1044
- name: options.name ?? "Local private key",
1045
- kind: "local-private-key",
1046
- autoConnect: true,
1047
- async connect() {
1048
- const account = privateKeyToAccount(options.privateKey);
1049
- return {
1050
- connectorId: id,
1051
- connectorKind: "local-private-key",
1052
- signerAddress: account.address
1053
- };
1054
- }
1055
- };
1056
- }
1057
- function readInjectedProvider() {
1058
- const provider = globalThis.ethereum;
1059
- if (!provider || typeof provider.request !== "function") {
1060
- throw Errors.providerError(
1061
- "connector",
1062
- "injected",
1063
- new Error("No injected EIP-1193 wallet was found.")
1064
- );
1065
- }
1066
- return provider;
1067
- }
1068
- function validateAndNormalizeEvmAddress(field, raw) {
1069
- if (typeof raw !== "string" || !EVM_ADDRESS_PATTERN.test(raw)) {
1070
- const display = typeof raw === "string" ? raw.slice(0, 64) : String(raw);
1071
- throw Errors.invalidInput(
1072
- field,
1073
- `must be a 0x-prefixed 40 hex char address, got ${display}.`
1074
- );
1075
- }
1076
- try {
1077
- return getAddress(raw);
1078
- } catch (cause) {
1079
- throw Errors.invalidInput(
1080
- field,
1081
- `failed EIP-55 checksum: ${cause instanceof Error ? cause.message : String(cause)}.`
1082
- );
1083
- }
1084
- }
1085
-
1086
- export { CapxulClientProvider, CapxulProvider, CapxulTransportProvider, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAcceptInvitation, useAccount, useAccountBalanceLedger, useApiKey, useApiKeys, useAuth, useAuthBootstrapFlow, useAuthFlow, useBalanceLedger, useBalanceLedgerEntry, useCapxul, useCapxulStatus, useDocument, useDocuments, useExternalAccount, useExternalAccounts, useInviteMember, useKycProfile, useMe, useMember, useMembers, useOnboardingFlow, useOperation, useOrgBalanceLedger, useOrgDocuments, useOrgPayments, useOrgTransfers, useOrgWithdrawals, useOrganization, useOrganizations, usePayment, usePayments, useProvisioningFlow, useRemoveMember, useResendInvitation, useRevokeMember, useSafe, useSubAccount, useSubAccounts, useTokenTransfer, useTokenTransfers, useTransfer, useTransfers, useTreasury, useUpdateMemberRole, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };