@capxul/sdk-react 0.1.0-alpha.6 → 0.1.0-alpha.9
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/CHANGELOG.md +21 -16
- package/README.md +21 -1
- package/dist/index.cjs +57 -3
- package/dist/index.d.cts +99 -2
- package/dist/index.d.ts +99 -2
- package/dist/index.js +57 -4
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# @capxul/sdk-react
|
|
2
2
|
|
|
3
|
-
## 0.1.0-alpha.
|
|
3
|
+
## 0.1.0-alpha.9
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add the canonical auth bootstrap flow.
|
|
8
|
+
|
|
9
|
+
`verifyOtp()` now resolves a verified email session into either an
|
|
10
|
+
`existing_member` identity or a `bootstrap_required` continuation. New and
|
|
11
|
+
incomplete members continue through `completeBootstrap()`, which validates a
|
|
12
|
+
server-issued bootstrap token, claims the username, provisions the account/Safe
|
|
13
|
+
through the backend bootstrap path, and returns the authenticated product
|
|
14
|
+
identity. The React SDK adds `useAuthBootstrapFlow()` as the typed first-run
|
|
15
|
+
flow wrapper.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
- @capxul/sdk@0.1.0-alpha.9
|
|
21
|
+
|
|
22
|
+
## 0.1.0-alpha.8
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
|
6
25
|
|
|
@@ -32,21 +51,7 @@
|
|
|
32
51
|
### Patch Changes
|
|
33
52
|
|
|
34
53
|
- Updated dependencies [57203a4]
|
|
35
|
-
- @capxul/sdk@0.1.0-alpha.
|
|
36
|
-
|
|
37
|
-
## 0.1.0-alpha.5
|
|
38
|
-
|
|
39
|
-
### Patch Changes
|
|
40
|
-
|
|
41
|
-
- Widen the React peer dependency to `>=18.2.0 <20` so React 18-era Ink 5
|
|
42
|
-
CLI apps can install `@capxul/sdk-react` without forcing React 19 into
|
|
43
|
-
Ink's React reconciler. The provider and hooks only use React 18-compatible
|
|
44
|
-
APIs (`createContext`, `useContext`, `useMemo`, `useEffect`, `useState`, and
|
|
45
|
-
`useSyncExternalStore`), preserving React 19 compatibility while unblocking
|
|
46
|
-
React 18 hosts.
|
|
47
|
-
|
|
48
|
-
- Updated dependencies
|
|
49
|
-
- @capxul/sdk@0.1.0-alpha.5
|
|
54
|
+
- @capxul/sdk@0.1.0-alpha.8
|
|
50
55
|
|
|
51
56
|
## 0.1.0-alpha.4
|
|
52
57
|
|
package/README.md
CHANGED
|
@@ -40,7 +40,12 @@ import { CapxulProvider } from "@capxul/sdk-react";
|
|
|
40
40
|
|
|
41
41
|
export default function RootLayout({ children }) {
|
|
42
42
|
return (
|
|
43
|
-
<CapxulProvider
|
|
43
|
+
<CapxulProvider
|
|
44
|
+
config={{
|
|
45
|
+
mode: "publishable-key",
|
|
46
|
+
publishableKey: process.env.NEXT_PUBLIC_CAPXUL_PUBLISHABLE_KEY!,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
44
49
|
{children}
|
|
45
50
|
</CapxulProvider>
|
|
46
51
|
);
|
|
@@ -119,6 +124,21 @@ subscription against the transport singleton — only the components
|
|
|
119
124
|
that actually call it re-render when state changes. The provider
|
|
120
125
|
itself never re-renders.
|
|
121
126
|
|
|
127
|
+
## Publishable-key proof status
|
|
128
|
+
|
|
129
|
+
The publishable-key path is runtime-proven where the repo can run it
|
|
130
|
+
without secrets:
|
|
131
|
+
|
|
132
|
+
| Surface | Runtime proof | Expected safe signal |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| Provider + `useMe()` | `corepack pnpm --filter @capxul/sdk-react check-types` plus the headless proof tests under `packages/sdk-react/ops/proof` | provider reaches `useCapxulStatus().status === "ready"` after one bootstrap request |
|
|
135
|
+
| Reference CLI mock | `corepack pnpm --filter @capxul/reference-cli build && node apps/reference-cli/dist/cli.js bootstrap probe --mock --json` | `ok:true`, `mode:"publishable-key"`, `bootstrapRequests:1`, `authRequests:1`, `keyLengthClass:"provided"` |
|
|
136
|
+
| Reference CLI live | same command without `--mock`, with `CAPXUL_REF_PUBLISHABLE_KEY` and optional `CAPXUL_REF_BOOTSTRAP_URL` set locally | success only when the key/origin/runtime are valid; otherwise sanitized SDK error JSON |
|
|
137
|
+
|
|
138
|
+
Do not paste or commit publishable keys, session tokens, Convex JWTs,
|
|
139
|
+
cookies, or provider payloads. Proof output reports only
|
|
140
|
+
`keyLengthClass`.
|
|
141
|
+
|
|
122
142
|
## Hooks catalogue
|
|
123
143
|
|
|
124
144
|
| Surface | Hook |
|
package/dist/index.cjs
CHANGED
|
@@ -110,7 +110,12 @@ var Errors = {
|
|
|
110
110
|
"Idempotency key was already used for a different request",
|
|
111
111
|
{ details }
|
|
112
112
|
),
|
|
113
|
-
emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}
|
|
113
|
+
emailDeliveryFailed: (detail, details) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
|
|
114
|
+
details
|
|
115
|
+
}),
|
|
116
|
+
rateLimited: (details) => new CapxulError("RATE_LIMITED", "Request was rate limited", {
|
|
117
|
+
details: { ...details }
|
|
118
|
+
}),
|
|
114
119
|
internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
115
120
|
/**
|
|
116
121
|
* Verification gate. Surfaced when a request hits a verification
|
|
@@ -217,6 +222,48 @@ function createReactDataClient(convexUrl, sessionStore) {
|
|
|
217
222
|
}
|
|
218
223
|
};
|
|
219
224
|
}
|
|
225
|
+
function createLazyReactDataClient(transport, sessionStore, createClient = createReactDataClient) {
|
|
226
|
+
let client = null;
|
|
227
|
+
let initializeClient = null;
|
|
228
|
+
let closed = false;
|
|
229
|
+
function closedError() {
|
|
230
|
+
return new Error("Capxul React data client is closed");
|
|
231
|
+
}
|
|
232
|
+
async function getClient() {
|
|
233
|
+
if (closed) throw closedError();
|
|
234
|
+
if (client) return client;
|
|
235
|
+
initializeClient ??= (async () => {
|
|
236
|
+
const runtime = await transport.ensureRuntime();
|
|
237
|
+
if (closed) throw closedError();
|
|
238
|
+
const nextClient = createClient(runtime.convexUrl, sessionStore);
|
|
239
|
+
if (closed) {
|
|
240
|
+
nextClient.close();
|
|
241
|
+
throw closedError();
|
|
242
|
+
}
|
|
243
|
+
client = nextClient;
|
|
244
|
+
return nextClient;
|
|
245
|
+
})().catch((error) => {
|
|
246
|
+
if (!closed) {
|
|
247
|
+
initializeClient = null;
|
|
248
|
+
}
|
|
249
|
+
throw error;
|
|
250
|
+
});
|
|
251
|
+
return initializeClient;
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
query: async (name, args) => (await getClient()).query(name, args),
|
|
255
|
+
mutation: async (name, args) => (await getClient()).mutation(name, args),
|
|
256
|
+
action: async (name, args) => (await getClient()).action?.(name, args),
|
|
257
|
+
refreshAuth: () => {
|
|
258
|
+
client?.refreshAuth();
|
|
259
|
+
},
|
|
260
|
+
close: () => {
|
|
261
|
+
closed = true;
|
|
262
|
+
client?.close();
|
|
263
|
+
client = null;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
220
267
|
function CapxulProvider({
|
|
221
268
|
config,
|
|
222
269
|
sessionStore,
|
|
@@ -246,12 +293,12 @@ function CapxulProvider({
|
|
|
246
293
|
function buildWiring(config, sessionStore) {
|
|
247
294
|
const validated = createCapxulConfig(config);
|
|
248
295
|
const transport = sdk.makeHttpTransport(validated);
|
|
249
|
-
const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) :
|
|
296
|
+
const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) : createLazyReactDataClient(transport, sessionStore);
|
|
250
297
|
const sdkConfig = {
|
|
251
298
|
_transport: transport,
|
|
252
299
|
publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0,
|
|
253
300
|
data: dataClient ?? void 0,
|
|
254
|
-
auth:
|
|
301
|
+
auth: validated.mode === "build-time-urls" || validated.mode === "publishable-key" ? {
|
|
255
302
|
// The auth client builds the BetterAuth root URL from this
|
|
256
303
|
// value. Convex's `.cloud` URL is the wrong host (BetterAuth
|
|
257
304
|
// is mounted on the `.site` URL), but the build-time-urls
|
|
@@ -554,6 +601,12 @@ function useAuthFlow() {
|
|
|
554
601
|
const [snapshot, send] = react$1.useActor(machine);
|
|
555
602
|
return { snapshot, send };
|
|
556
603
|
}
|
|
604
|
+
function useAuthBootstrapFlow() {
|
|
605
|
+
const client = useCapxul();
|
|
606
|
+
const machine = react.useMemo(() => client.flows.authBootstrap(), [client]);
|
|
607
|
+
const [snapshot, send] = react$1.useActor(machine);
|
|
608
|
+
return { snapshot, send };
|
|
609
|
+
}
|
|
557
610
|
function useOnboardingFlow() {
|
|
558
611
|
const client = useCapxul();
|
|
559
612
|
const machine = react.useMemo(() => client.flows.onboarding(), [client]);
|
|
@@ -671,6 +724,7 @@ exports.localPrivateKeyConnector = localPrivateKeyConnector;
|
|
|
671
724
|
exports.useAccount = useAccount;
|
|
672
725
|
exports.useApiKey = useApiKey;
|
|
673
726
|
exports.useApiKeys = useApiKeys;
|
|
727
|
+
exports.useAuthBootstrapFlow = useAuthBootstrapFlow;
|
|
674
728
|
exports.useAuthFlow = useAuthFlow;
|
|
675
729
|
exports.useBalanceLedger = useBalanceLedger;
|
|
676
730
|
exports.useBalanceLedgerEntry = useBalanceLedgerEntry;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import * as _capxul_sdk from '@capxul/sdk';
|
|
2
3
|
import { HttpTransport, TransportState, BrowserCapxulConfig, AuthSessionStore, AccountId, OrganizationId, ApiKeyId, BalanceLedgerEntryId, ExternalAccountId, MemberId, Account, ApiKey, BalanceLedgerEntry, DocumentId, Document, ExternalAccount, KybProfile, KycProfile, CapxulError as CapxulError$1, Member, OperationId, Operation, Organization, PaymentId, Payment, SafeId, Safe, SubAccountId, SubAccount, TokenTransfer, TransferId, Transfer, Treasury, VirtualAccountId, VirtualAccount, VirtualCardId, VirtualCard, WebhookEndpointId, WebhookEndpoint, WebhookEventId, WebhookEvent, WithdrawalId, Withdrawal, List, TokenTransfersListInput, TokenTransfersListPage, LocalPrivateKeySignerProvider } from '@capxul/sdk';
|
|
3
|
-
export { AuthFlowContext, AuthFlowEvent, BrowserCapxulConfig, OnboardingFlowContext, OnboardingFlowEvent, ProvisioningFlowContext, ProvisioningFlowEvent } from '@capxul/sdk';
|
|
4
|
+
export { AuthBootstrapFlowContext, AuthBootstrapFlowEvent, AuthFlowContext, AuthFlowEvent, BrowserCapxulConfig, OnboardingFlowContext, OnboardingFlowEvent, ProvisioningFlowContext, ProvisioningFlowEvent } from '@capxul/sdk';
|
|
4
5
|
import { QueryClient, UseQueryResult } from '@tanstack/react-query';
|
|
5
6
|
import { CapxulClient } from '@capxul/sdk/client';
|
|
6
7
|
import { CapxulError } from '@capxul/sdk/errors';
|
|
@@ -444,10 +445,106 @@ declare function useApiKeys(_organizationId: OrganizationId): QueryResult<List<A
|
|
|
444
445
|
*/
|
|
445
446
|
declare function useWebhookEndpoints(): QueryResult<List<WebhookEndpoint>>;
|
|
446
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Lowercased, shape-validated email address. Brand prevents swapping
|
|
450
|
+
* with `phoneNumber`, `username`, or other string identifiers (per
|
|
451
|
+
* `CANON.md` §4.54 and `sdk-surface.md` §5h).
|
|
452
|
+
*/
|
|
453
|
+
type Email = string & {
|
|
454
|
+
readonly __capxulEmailBrand: "Email";
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* Public Capxul username. 3–30 chars, letter-first, lowercased,
|
|
458
|
+
* remaining chars from `[a-z0-9_-]` (per `CANON.md` §4.54 and
|
|
459
|
+
* `sdk-surface.md` §5h). Constructor lowercases before validating so
|
|
460
|
+
* mixed-case input canonicalizes cleanly when the first char is a
|
|
461
|
+
* letter; purely invalid shapes (too short, illegal chars, digit-first)
|
|
462
|
+
* still throw.
|
|
463
|
+
*/
|
|
464
|
+
type Username = string & {
|
|
465
|
+
readonly __capxulUsernameBrand: "Username";
|
|
466
|
+
};
|
|
467
|
+
|
|
447
468
|
declare function useAuthFlow(): {
|
|
448
469
|
readonly snapshot: xstate.MachineSnapshot<any, any, any, any, any, any, any, any>;
|
|
449
470
|
readonly send: (event: any) => void;
|
|
450
471
|
};
|
|
472
|
+
declare function useAuthBootstrapFlow(): {
|
|
473
|
+
readonly snapshot: xstate.MachineSnapshot<_capxul_sdk.AuthBootstrapFlowContext, {
|
|
474
|
+
readonly type: "ENTER_EMAIL";
|
|
475
|
+
readonly email: Email;
|
|
476
|
+
} | {
|
|
477
|
+
readonly type: "REQUEST_OTP";
|
|
478
|
+
} | {
|
|
479
|
+
readonly type: "ENTER_OTP";
|
|
480
|
+
readonly code: string;
|
|
481
|
+
} | {
|
|
482
|
+
readonly type: "VERIFY_OTP";
|
|
483
|
+
} | {
|
|
484
|
+
readonly type: "ENTER_USERNAME";
|
|
485
|
+
readonly username: Username;
|
|
486
|
+
} | {
|
|
487
|
+
readonly type: "ENTER_SIGNER_PROVIDER";
|
|
488
|
+
readonly signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
489
|
+
} | {
|
|
490
|
+
readonly type: "COMPLETE_BOOTSTRAP";
|
|
491
|
+
} | {
|
|
492
|
+
readonly type: "BACK";
|
|
493
|
+
} | {
|
|
494
|
+
readonly type: "RESET";
|
|
495
|
+
} | {
|
|
496
|
+
readonly type: "SIGN_OUT";
|
|
497
|
+
}, {
|
|
498
|
+
[x: string]: xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, void, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<_capxul_sdk.CompleteBootstrapResult, {
|
|
499
|
+
bootstrapToken: _capxul_sdk.AuthBootstrapToken;
|
|
500
|
+
username: Username;
|
|
501
|
+
signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
502
|
+
}, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, {
|
|
503
|
+
email: Email;
|
|
504
|
+
}, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<_capxul_sdk.VerifyOtpResult, {
|
|
505
|
+
email: Email;
|
|
506
|
+
code: string;
|
|
507
|
+
}, xstate.EventObject>> | undefined;
|
|
508
|
+
}, "email" | "error" | "bootstrap_required" | "authenticated" | "sending_otp" | "otp_requested" | "signing_out" | "verifying_otp" | "completing_bootstrap", string, xstate.NonReducibleUnknown, xstate.MetaObject, {
|
|
509
|
+
id: "authBootstrap";
|
|
510
|
+
states: {
|
|
511
|
+
readonly email: {};
|
|
512
|
+
readonly sending_otp: {};
|
|
513
|
+
readonly otp_requested: {};
|
|
514
|
+
readonly verifying_otp: {};
|
|
515
|
+
readonly bootstrap_required: {};
|
|
516
|
+
readonly completing_bootstrap: {};
|
|
517
|
+
readonly authenticated: {};
|
|
518
|
+
readonly signing_out: {};
|
|
519
|
+
readonly error: {};
|
|
520
|
+
};
|
|
521
|
+
}>;
|
|
522
|
+
readonly send: (event: {
|
|
523
|
+
readonly type: "ENTER_EMAIL";
|
|
524
|
+
readonly email: Email;
|
|
525
|
+
} | {
|
|
526
|
+
readonly type: "REQUEST_OTP";
|
|
527
|
+
} | {
|
|
528
|
+
readonly type: "ENTER_OTP";
|
|
529
|
+
readonly code: string;
|
|
530
|
+
} | {
|
|
531
|
+
readonly type: "VERIFY_OTP";
|
|
532
|
+
} | {
|
|
533
|
+
readonly type: "ENTER_USERNAME";
|
|
534
|
+
readonly username: Username;
|
|
535
|
+
} | {
|
|
536
|
+
readonly type: "ENTER_SIGNER_PROVIDER";
|
|
537
|
+
readonly signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
538
|
+
} | {
|
|
539
|
+
readonly type: "COMPLETE_BOOTSTRAP";
|
|
540
|
+
} | {
|
|
541
|
+
readonly type: "BACK";
|
|
542
|
+
} | {
|
|
543
|
+
readonly type: "RESET";
|
|
544
|
+
} | {
|
|
545
|
+
readonly type: "SIGN_OUT";
|
|
546
|
+
}) => void;
|
|
547
|
+
};
|
|
451
548
|
declare function useOnboardingFlow(): {
|
|
452
549
|
readonly snapshot: xstate.MachineSnapshot<any, any, any, any, any, any, any, any>;
|
|
453
550
|
readonly send: (event: any) => void;
|
|
@@ -538,4 +635,4 @@ declare function injectedConnector(options?: InjectedConnectorOptions): CapxulCo
|
|
|
538
635
|
*/
|
|
539
636
|
declare function localPrivateKeyConnector(options: LocalPrivateKeyConnectorOptions): CapxulConnector;
|
|
540
637
|
|
|
541
|
-
export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type UseTokenTransferArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, 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, useTokenTransfer, useTokenTransfers, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };
|
|
638
|
+
export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type UseTokenTransferArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import * as _capxul_sdk from '@capxul/sdk';
|
|
2
3
|
import { HttpTransport, TransportState, BrowserCapxulConfig, AuthSessionStore, AccountId, OrganizationId, ApiKeyId, BalanceLedgerEntryId, ExternalAccountId, MemberId, Account, ApiKey, BalanceLedgerEntry, DocumentId, Document, ExternalAccount, KybProfile, KycProfile, CapxulError as CapxulError$1, Member, OperationId, Operation, Organization, PaymentId, Payment, SafeId, Safe, SubAccountId, SubAccount, TokenTransfer, TransferId, Transfer, Treasury, VirtualAccountId, VirtualAccount, VirtualCardId, VirtualCard, WebhookEndpointId, WebhookEndpoint, WebhookEventId, WebhookEvent, WithdrawalId, Withdrawal, List, TokenTransfersListInput, TokenTransfersListPage, LocalPrivateKeySignerProvider } from '@capxul/sdk';
|
|
3
|
-
export { AuthFlowContext, AuthFlowEvent, BrowserCapxulConfig, OnboardingFlowContext, OnboardingFlowEvent, ProvisioningFlowContext, ProvisioningFlowEvent } from '@capxul/sdk';
|
|
4
|
+
export { AuthBootstrapFlowContext, AuthBootstrapFlowEvent, AuthFlowContext, AuthFlowEvent, BrowserCapxulConfig, OnboardingFlowContext, OnboardingFlowEvent, ProvisioningFlowContext, ProvisioningFlowEvent } from '@capxul/sdk';
|
|
4
5
|
import { QueryClient, UseQueryResult } from '@tanstack/react-query';
|
|
5
6
|
import { CapxulClient } from '@capxul/sdk/client';
|
|
6
7
|
import { CapxulError } from '@capxul/sdk/errors';
|
|
@@ -444,10 +445,106 @@ declare function useApiKeys(_organizationId: OrganizationId): QueryResult<List<A
|
|
|
444
445
|
*/
|
|
445
446
|
declare function useWebhookEndpoints(): QueryResult<List<WebhookEndpoint>>;
|
|
446
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Lowercased, shape-validated email address. Brand prevents swapping
|
|
450
|
+
* with `phoneNumber`, `username`, or other string identifiers (per
|
|
451
|
+
* `CANON.md` §4.54 and `sdk-surface.md` §5h).
|
|
452
|
+
*/
|
|
453
|
+
type Email = string & {
|
|
454
|
+
readonly __capxulEmailBrand: "Email";
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* Public Capxul username. 3–30 chars, letter-first, lowercased,
|
|
458
|
+
* remaining chars from `[a-z0-9_-]` (per `CANON.md` §4.54 and
|
|
459
|
+
* `sdk-surface.md` §5h). Constructor lowercases before validating so
|
|
460
|
+
* mixed-case input canonicalizes cleanly when the first char is a
|
|
461
|
+
* letter; purely invalid shapes (too short, illegal chars, digit-first)
|
|
462
|
+
* still throw.
|
|
463
|
+
*/
|
|
464
|
+
type Username = string & {
|
|
465
|
+
readonly __capxulUsernameBrand: "Username";
|
|
466
|
+
};
|
|
467
|
+
|
|
447
468
|
declare function useAuthFlow(): {
|
|
448
469
|
readonly snapshot: xstate.MachineSnapshot<any, any, any, any, any, any, any, any>;
|
|
449
470
|
readonly send: (event: any) => void;
|
|
450
471
|
};
|
|
472
|
+
declare function useAuthBootstrapFlow(): {
|
|
473
|
+
readonly snapshot: xstate.MachineSnapshot<_capxul_sdk.AuthBootstrapFlowContext, {
|
|
474
|
+
readonly type: "ENTER_EMAIL";
|
|
475
|
+
readonly email: Email;
|
|
476
|
+
} | {
|
|
477
|
+
readonly type: "REQUEST_OTP";
|
|
478
|
+
} | {
|
|
479
|
+
readonly type: "ENTER_OTP";
|
|
480
|
+
readonly code: string;
|
|
481
|
+
} | {
|
|
482
|
+
readonly type: "VERIFY_OTP";
|
|
483
|
+
} | {
|
|
484
|
+
readonly type: "ENTER_USERNAME";
|
|
485
|
+
readonly username: Username;
|
|
486
|
+
} | {
|
|
487
|
+
readonly type: "ENTER_SIGNER_PROVIDER";
|
|
488
|
+
readonly signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
489
|
+
} | {
|
|
490
|
+
readonly type: "COMPLETE_BOOTSTRAP";
|
|
491
|
+
} | {
|
|
492
|
+
readonly type: "BACK";
|
|
493
|
+
} | {
|
|
494
|
+
readonly type: "RESET";
|
|
495
|
+
} | {
|
|
496
|
+
readonly type: "SIGN_OUT";
|
|
497
|
+
}, {
|
|
498
|
+
[x: string]: xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, void, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<_capxul_sdk.CompleteBootstrapResult, {
|
|
499
|
+
bootstrapToken: _capxul_sdk.AuthBootstrapToken;
|
|
500
|
+
username: Username;
|
|
501
|
+
signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
502
|
+
}, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, {
|
|
503
|
+
email: Email;
|
|
504
|
+
}, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<_capxul_sdk.VerifyOtpResult, {
|
|
505
|
+
email: Email;
|
|
506
|
+
code: string;
|
|
507
|
+
}, xstate.EventObject>> | undefined;
|
|
508
|
+
}, "email" | "error" | "bootstrap_required" | "authenticated" | "sending_otp" | "otp_requested" | "signing_out" | "verifying_otp" | "completing_bootstrap", string, xstate.NonReducibleUnknown, xstate.MetaObject, {
|
|
509
|
+
id: "authBootstrap";
|
|
510
|
+
states: {
|
|
511
|
+
readonly email: {};
|
|
512
|
+
readonly sending_otp: {};
|
|
513
|
+
readonly otp_requested: {};
|
|
514
|
+
readonly verifying_otp: {};
|
|
515
|
+
readonly bootstrap_required: {};
|
|
516
|
+
readonly completing_bootstrap: {};
|
|
517
|
+
readonly authenticated: {};
|
|
518
|
+
readonly signing_out: {};
|
|
519
|
+
readonly error: {};
|
|
520
|
+
};
|
|
521
|
+
}>;
|
|
522
|
+
readonly send: (event: {
|
|
523
|
+
readonly type: "ENTER_EMAIL";
|
|
524
|
+
readonly email: Email;
|
|
525
|
+
} | {
|
|
526
|
+
readonly type: "REQUEST_OTP";
|
|
527
|
+
} | {
|
|
528
|
+
readonly type: "ENTER_OTP";
|
|
529
|
+
readonly code: string;
|
|
530
|
+
} | {
|
|
531
|
+
readonly type: "VERIFY_OTP";
|
|
532
|
+
} | {
|
|
533
|
+
readonly type: "ENTER_USERNAME";
|
|
534
|
+
readonly username: Username;
|
|
535
|
+
} | {
|
|
536
|
+
readonly type: "ENTER_SIGNER_PROVIDER";
|
|
537
|
+
readonly signerProvider: _capxul_sdk.LocalPrivateKeySignerProvider;
|
|
538
|
+
} | {
|
|
539
|
+
readonly type: "COMPLETE_BOOTSTRAP";
|
|
540
|
+
} | {
|
|
541
|
+
readonly type: "BACK";
|
|
542
|
+
} | {
|
|
543
|
+
readonly type: "RESET";
|
|
544
|
+
} | {
|
|
545
|
+
readonly type: "SIGN_OUT";
|
|
546
|
+
}) => void;
|
|
547
|
+
};
|
|
451
548
|
declare function useOnboardingFlow(): {
|
|
452
549
|
readonly snapshot: xstate.MachineSnapshot<any, any, any, any, any, any, any, any>;
|
|
453
550
|
readonly send: (event: any) => void;
|
|
@@ -538,4 +635,4 @@ declare function injectedConnector(options?: InjectedConnectorOptions): CapxulCo
|
|
|
538
635
|
*/
|
|
539
636
|
declare function localPrivateKeyConnector(options: LocalPrivateKeyConnectorOptions): CapxulConnector;
|
|
540
637
|
|
|
541
|
-
export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type UseTokenTransferArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, 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, useTokenTransfer, useTokenTransfers, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };
|
|
638
|
+
export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type UseTokenTransferArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, 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 };
|
package/dist/index.js
CHANGED
|
@@ -108,7 +108,12 @@ var Errors = {
|
|
|
108
108
|
"Idempotency key was already used for a different request",
|
|
109
109
|
{ details }
|
|
110
110
|
),
|
|
111
|
-
emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}
|
|
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
|
+
}),
|
|
112
117
|
internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
113
118
|
/**
|
|
114
119
|
* Verification gate. Surfaced when a request hits a verification
|
|
@@ -215,6 +220,48 @@ function createReactDataClient(convexUrl, sessionStore) {
|
|
|
215
220
|
}
|
|
216
221
|
};
|
|
217
222
|
}
|
|
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();
|
|
257
|
+
},
|
|
258
|
+
close: () => {
|
|
259
|
+
closed = true;
|
|
260
|
+
client?.close();
|
|
261
|
+
client = null;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
218
265
|
function CapxulProvider({
|
|
219
266
|
config,
|
|
220
267
|
sessionStore,
|
|
@@ -244,12 +291,12 @@ function CapxulProvider({
|
|
|
244
291
|
function buildWiring(config, sessionStore) {
|
|
245
292
|
const validated = createCapxulConfig(config);
|
|
246
293
|
const transport = makeHttpTransport(validated);
|
|
247
|
-
const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) :
|
|
294
|
+
const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) : createLazyReactDataClient(transport, sessionStore);
|
|
248
295
|
const sdkConfig = {
|
|
249
296
|
_transport: transport,
|
|
250
297
|
publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0,
|
|
251
298
|
data: dataClient ?? void 0,
|
|
252
|
-
auth:
|
|
299
|
+
auth: validated.mode === "build-time-urls" || validated.mode === "publishable-key" ? {
|
|
253
300
|
// The auth client builds the BetterAuth root URL from this
|
|
254
301
|
// value. Convex's `.cloud` URL is the wrong host (BetterAuth
|
|
255
302
|
// is mounted on the `.site` URL), but the build-time-urls
|
|
@@ -552,6 +599,12 @@ function useAuthFlow() {
|
|
|
552
599
|
const [snapshot, send] = useActor(machine);
|
|
553
600
|
return { snapshot, send };
|
|
554
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
|
+
}
|
|
555
608
|
function useOnboardingFlow() {
|
|
556
609
|
const client = useCapxul();
|
|
557
610
|
const machine = useMemo(() => client.flows.onboarding(), [client]);
|
|
@@ -660,4 +713,4 @@ function validateAndNormalizeEvmAddress(field, raw) {
|
|
|
660
713
|
}
|
|
661
714
|
}
|
|
662
715
|
|
|
663
|
-
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, useTokenTransfer, useTokenTransfers, 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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capxul/sdk-react",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.9",
|
|
4
4
|
"description": "React provider + hooks for the @capxul/sdk headless client.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@capxul/sdk": "0.1.0-alpha.
|
|
49
|
+
"@capxul/sdk": "0.1.0-alpha.9"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@tanstack/react-query": "^5",
|
|
53
53
|
"@xstate/react": "^5",
|
|
54
54
|
"convex": ">=1.0.0",
|
|
55
|
-
"react": ">=
|
|
55
|
+
"react": ">=19.0.0",
|
|
56
56
|
"viem": ">=2.0.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"typescript": "5.9.2",
|
|
71
71
|
"viem": "2.47.10",
|
|
72
72
|
"vitest": "^4.1.2",
|
|
73
|
-
"@repo/config": "0.0.0",
|
|
74
73
|
"@repo/observability": "0.0.0",
|
|
74
|
+
"@repo/config": "0.0.0",
|
|
75
75
|
"@repo/platform-kernel": "0.0.0",
|
|
76
76
|
"@repo/typescript-config": "0.0.0"
|
|
77
77
|
},
|