@capxul/sdk 0.1.0-alpha.8 → 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/dist/index.d.ts CHANGED
@@ -1,36 +1,15 @@
1
- import { S as Session, C as CapxulClient, A as AccountProvisionPersonalInput } from './client-ByzDfG98.js';
2
- export { a as AccountsClient, b as ApiKeyCreateResult, c as ApiKeysClient, d as AuthClient, e as AuthSessionStore, B as BrowserCapxulConfig, f as CapxulAuthConfig, g as CapxulConfig, h as CapxulDataClient, i as CapxulFlowFactories, j as CapxulSigningConfig, D as DocumentsClient, E as ExternalAccountsClient, H as HttpTransport, L as LocalPrivateKeySignerProvider, M as MeClient, O as OperationsClient, k as OrgDocumentsClient, l as OrgPaymentsClient, m as OrgSafesClient, n as OrgTransfersClient, o as OrgTreasuryClient, p as OrgWithdrawalsClient, q as OrganizationsClient, P as PaymentsClient, r as SubAccountsClient, T as TokenTransfer, s as TokenTransferId, t as TokenTransfersClient, u as TokenTransfersListInput, v as TokenTransfersListPage, w as TokenTransfersRetrieveInput, x as TransfersClient, y as TransportRuntime, z as TransportState, V as VirtualAccountsClient, F as VirtualCardsClient, W as WebhookEndpointCreateResult, G as WebhookEndpointsClient, I as WebhookEventsClient, J as WithdrawalsClient, K as createCapxulClient, N as makeHttpTransport, Q as toTokenTransferId } from './client-ByzDfG98.js';
1
+ import { S as Session, C as CapxulError$1, a as CapxulClient, A as AccountProvisionPersonalInput } from './client-ChZrdf3R.js';
2
+ export { b as AccountsClient, c as ApiKeyCreateResult, d as ApiKeysClient, e as AuthBootstrapFlowContext, f as AuthBootstrapFlowError, g as AuthBootstrapFlowEvent, h as AuthBootstrapReason, i as AuthBootstrapToken, j as AuthClient, k as AuthSessionStore, B as BrowserCapxulConfig, l as CapxulAuthConfig, m as CapxulConfig, n as CapxulDataClient, o as CapxulFlowFactories, p as CapxulSigningConfig, q as CompleteBootstrapInput, r as CompleteBootstrapResult, D as DocumentsClient, E as ExternalAccountsClient, H as HttpTransport, L as LocalPrivateKeySignerProvider, M as MeClient, O as OperationsClient, s as OrgDocumentsClient, t as OrgPaymentsClient, u as OrgSafesClient, v as OrgTransfersClient, w as OrgTreasuryClient, x as OrgWithdrawalsClient, y as OrganizationsClient, P as PaymentsClient, z as SubAccountsClient, T as TokenTransfer, F as TokenTransferId, G as TokenTransfersClient, I as TokenTransfersListInput, J as TokenTransfersListPage, K as TokenTransfersRetrieveInput, N as TransfersClient, Q as TransportRuntime, R as TransportState, V as VerifyOtpResult, U as VirtualAccountsClient, W as VirtualCardsClient, X as WebhookEndpointCreateResult, Y as WebhookEndpointsClient, Z as WebhookEventsClient, _ as WithdrawalsClient, $ as createAuthBootstrapFlowMachine, a0 as createCapxulClient, a1 as makeHttpTransport, a2 as toTokenTransferId } from './client-ChZrdf3R.js';
3
3
  import * as xstate from 'xstate';
4
4
  import { E as Email, U as Username, O as OperationId, N as NextAction } from './next-action-DkrwXYay.js';
5
5
  export { A as AccountId, a as ApiKeyId, B as BalanceLedgerEntryId, C as CorrelationId, D as DocumentId, b as ExternalAccountId, K as KybProfileId, c as KycProfileId, M as MemberId, d as OrganizationId, P as PaymentId, e as PhoneNumber, S as SafeId, f as SubAccountId, T as TransactionIntentId, g as TransferId, h as TreasuryId, V as VirtualAccountId, i as VirtualCardId, W as WebhookEndpointId, j as WebhookEventId, k as WithdrawalId, t as toAccountId, l as toApiKeyId, m as toBalanceLedgerEntryId, n as toDocumentId, o as toEmail, p as toExternalAccountId, q as toKybProfileId, r as toKycProfileId, s as toMemberId, u as toOperationId, v as toOrganizationId, w as toPaymentId, x as toPhoneNumber, y as toSafeId, z as toSubAccountId, F as toTransferId, G as toTreasuryId, H as toUsername, I as toVirtualAccountId, J as toVirtualCardId, L as toWebhookEndpointId, Q as toWebhookEventId, R as toWithdrawalId } from './next-action-DkrwXYay.js';
6
- import { C as CapxulError$1, a as CapxulErrorCode$1 } from './errors-QHD5Tlok.js';
6
+ import { C as CapxulError, a as CapxulErrorCode } from './errors-QHD5Tlok.js';
7
7
  export { b as CapxulErrorDetails, c as CapxulErrorEnvelope, d as CapxulResult } from './errors-QHD5Tlok.js';
8
8
  import { A as Account } from './types-PM4AQRLP.js';
9
9
  export { a as AccountLookupResult, b as ApiKey, c as ApiKeyEnvironment, d as ApiKeyType, B as BalanceLedgerEntry, e as BankStatementDocument, C as CreatePaymentResult, f as CreateTransferResult, g as CreateWithdrawalResult, D as Document, E as ExternalAccount, h as ExternalAccountKind, I as InvoiceDocument, K as KybProfile, i as KycProfile, j as KycUploadDocument, L as List, M as Member, k as Money, O as Operation, l as OperationStatus, m as OperationSummary, n as Organization, P as PageInfo, o as Payment, p as PaymentParty, q as PaymentStatus, r as PayrollRunDocument, s as PayrollScheduleDocument, R as ReceiptDocument, S as Safe, t as Scope, u as Settlement, v as SubAccount, w as SubAccountOwnerKind, T as TaxFormDocument, x as TimestampIso, y as Transfer, z as TransferCustody, F as TransferEndpoint, G as TransferFx, H as TransferStatus, J as Treasury, U as UserIdentifier, V as VirtualAccount, N as VirtualAccountOwnerKind, Q as VirtualCard, W as VirtualCardLimits, X as VirtualCardOwnerKind, Y as WebhookEndpoint, Z as WebhookEvent, _ as Withdrawal, $ as WithdrawalStatus } from './types-PM4AQRLP.js';
10
10
  import { Account as Account$1 } from 'viem';
11
11
  export { WebhookVerificationOptions, WebhookVerificationResult, verifyWebhook } from './webhooks.js';
12
12
 
13
- /**
14
- * Unified error type used across the entire stack: backend, SDK, and frontend.
15
- * One class, one set of codes, one language.
16
- *
17
- * Backend throws CapxulError → withErrorBoundary serializes to ConvexError →
18
- * SDK deserializes back to CapxulError → frontend routes on err.code.
19
- */
20
- type CapxulErrorCode = "NOT_AUTHENTICATED" | "EMAIL_DELIVERY_FAILED" | "API_KEY_INVALID" | "API_KEY_EXPIRED" | "PROFILE_NOT_FOUND" | "SMART_ACCOUNT_MISSING" | "PLAYER_NOT_FOUND" | "ACCOUNT_NOT_FOUND" | "PROVIDER_ERROR" | "INVALID_INPUT" | "ENV_MISSING" | "NOT_IMPLEMENTED" | "VERIFICATION_REQUIRED" | "INSUFFICIENT_BALANCE" | "INVALID_RECIPIENT" | "TRANSACTION_FAILED" | "RATE_LIMITED" | "NETWORK_ERROR" | "PERMISSION_DENIED" | "IDEMPOTENCY_CONFLICT" | "NOT_FOUND" | "OPERATION_CANCELED" | "OPERATION_TIMEOUT" | "ACTION_REQUIRED" | "KYC_REQUIRED" | "POLICY_DENIED" | "SAFE_NOT_READY" | "PROVIDER_UNAVAILABLE" | "PROVIDER_REJECTED" | "RECONCILIATION_FAILED" | "INTERNAL_ERROR" | "QUOTE_EXPIRED" | "QUOTE_NOT_FOUND" | "UNKNOWN";
21
- declare class CapxulError extends Error {
22
- readonly code: CapxulErrorCode;
23
- readonly details?: Record<string, unknown>;
24
- readonly correlationId?: string;
25
- readonly layer?: string;
26
- constructor(code: CapxulErrorCode, message: string, options?: {
27
- cause?: unknown;
28
- details?: Record<string, unknown>;
29
- correlationId?: string;
30
- layer?: string;
31
- });
32
- }
33
-
34
13
  /**
35
14
  * Auth flow errors may originate from two CapxulError surfaces:
36
15
  * - the SDK-local generic `CapxulError<Codes>` returned by
@@ -42,7 +21,7 @@ declare class CapxulError extends Error {
42
21
  * union keeps either origin assignable to `context.error` without an
43
22
  * `as` cast at the call site.
44
23
  */
45
- type AuthFlowError = CapxulError$1 | CapxulError;
24
+ type AuthFlowError = CapxulError | CapxulError$1;
46
25
  type AuthFlowContext = {
47
26
  readonly email: Email | null;
48
27
  readonly session: Session | null;
@@ -118,7 +97,7 @@ declare function createAuthFlowMachine(client: CapxulClient): xstate.StateMachin
118
97
  } | {
119
98
  type: "trackSignedOut";
120
99
  params: unknown;
121
- }, never, never, "error" | "idle" | "sending_otp" | "otp_requested" | "verifying" | "authenticated" | "signing_out", string, xstate.NonReducibleUnknown, xstate.NonReducibleUnknown, xstate.EventObject, xstate.MetaObject, {
100
+ }, never, never, "idle" | "authenticated" | "error" | "sending_otp" | "otp_requested" | "verifying" | "signing_out", string, xstate.NonReducibleUnknown, xstate.NonReducibleUnknown, xstate.EventObject, xstate.MetaObject, {
122
101
  id: "auth";
123
102
  states: {
124
103
  readonly idle: {};
@@ -141,7 +120,7 @@ declare function createAuthFlowMachine(client: CapxulClient): xstate.StateMachin
141
120
  *
142
121
  * Both share `.code`, `.message`, `.details`, and extend `Error`.
143
122
  */
144
- type ProvisioningFlowError = CapxulError$1 | CapxulError;
123
+ type ProvisioningFlowError = CapxulError | CapxulError$1;
145
124
  type ProvisioningFlowContext = {
146
125
  readonly input: AccountProvisionPersonalInput | null;
147
126
  readonly account: Account | null;
@@ -218,7 +197,7 @@ declare function createProvisioningMachine(client: CapxulClient): xstate.StateMa
218
197
  }, {
219
198
  type: "hasInput";
220
199
  params: unknown;
221
- }, never, "done" | "error" | "idle" | "starting" | "running", string, {
200
+ }, never, "idle" | "error" | "done" | "starting" | "running", string, {
222
201
  readonly input: AccountProvisionPersonalInput;
223
202
  }, {
224
203
  readonly account: Account;
@@ -248,7 +227,7 @@ declare function createProvisioningMachine(client: CapxulClient): xstate.StateMa
248
227
  *
249
228
  * Both share `.code`, `.message`, `.details`, and extend `Error`.
250
229
  */
251
- type OnboardingFlowError = CapxulError$1 | CapxulError;
230
+ type OnboardingFlowError = CapxulError | CapxulError$1;
252
231
  /** Subjects supported by the onboarding flow. */
253
232
  type OnboardingSubjectKind = "account" | "organization";
254
233
  /**
@@ -326,7 +305,7 @@ declare function createOnboardingFlowMachine(client: CapxulClient): xstate.State
326
305
  }, {
327
306
  type: "hasInput";
328
307
  params: unknown;
329
- }, never, "done" | "error" | "idle" | "starting" | "running", string, {
308
+ }, never, "idle" | "error" | "done" | "starting" | "running", string, {
330
309
  readonly input: AccountProvisionPersonalInput;
331
310
  }, {
332
311
  readonly account: Account;
@@ -368,7 +347,7 @@ declare function createOnboardingFlowMachine(client: CapxulClient): xstate.State
368
347
  }, {
369
348
  type: "hasInput";
370
349
  params: unknown;
371
- }, never, "done" | "error" | "idle" | "starting" | "running", string, {
350
+ }, never, "idle" | "error" | "done" | "starting" | "running", string, {
372
351
  readonly input: AccountProvisionPersonalInput;
373
352
  }, {
374
353
  readonly account: Account;
@@ -438,7 +417,7 @@ declare function createOnboardingFlowMachine(client: CapxulClient): xstate.State
438
417
  } | {
439
418
  type: "childReportedError";
440
419
  params: unknown;
441
- }, never, "error" | "provisioning" | "profile" | "complete" | "action_required", string, xstate.NonReducibleUnknown, xstate.NonReducibleUnknown, xstate.EventObject, xstate.MetaObject, {
420
+ }, never, "action_required" | "provisioning" | "error" | "profile" | "complete", string, xstate.NonReducibleUnknown, xstate.NonReducibleUnknown, xstate.EventObject, xstate.MetaObject, {
442
421
  id: "onboarding";
443
422
  states: {
444
423
  readonly profile: {};
@@ -461,8 +440,8 @@ declare function createOnboardingFlowMachine(client: CapxulClient): xstate.State
461
440
  * No `default:` arm needed — the compile-time exhaustiveness check is
462
441
  * the contract.
463
442
  */
464
- declare function matchError<Codes extends CapxulErrorCode$1, R>(err: CapxulError$1<Codes>, handlers: {
465
- [K in Codes]: (err: CapxulError$1<K>) => R;
443
+ declare function matchError<Codes extends CapxulErrorCode, R>(err: CapxulError<Codes>, handlers: {
444
+ [K in Codes]: (err: CapxulError<K>) => R;
466
445
  }): R;
467
446
  /**
468
447
  * Exhaustive resource-status dispatch per CANON.md §4.44.
@@ -518,4 +497,4 @@ declare function tryCatch<T>(promise: Promise<T>): Promise<[Error, null] | [null
518
497
  */
519
498
  declare function createLocalSigner(privateKey: `0x${string}`): Account$1;
520
499
 
521
- export { Account, AccountProvisionPersonalInput, type AuthFlowContext, type AuthFlowError, type AuthFlowEvent, CapxulClient, CapxulError$1 as CapxulError, CapxulErrorCode$1 as CapxulErrorCode, Email, NextAction, type OnboardingFlowContext, type OnboardingFlowError, type OnboardingFlowEvent, type OnboardingProfileInput, type OnboardingSubjectKind, OperationId, type ProvisioningFlowContext, type ProvisioningFlowError, type ProvisioningFlowEvent, type ProvisioningFlowInput, type ProvisioningFlowOutput, Session, Username, createAuthFlowMachine, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, matchAction, matchError, matchStatus, tryCatch };
500
+ export { Account, AccountProvisionPersonalInput, type AuthFlowContext, type AuthFlowError, type AuthFlowEvent, CapxulClient, CapxulError, CapxulErrorCode, Email, NextAction, type OnboardingFlowContext, type OnboardingFlowError, type OnboardingFlowEvent, type OnboardingProfileInput, type OnboardingSubjectKind, OperationId, type ProvisioningFlowContext, type ProvisioningFlowError, type ProvisioningFlowEvent, type ProvisioningFlowInput, type ProvisioningFlowOutput, Session, Username, createAuthFlowMachine, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, matchAction, matchError, matchStatus, tryCatch };
package/dist/index.js CHANGED
@@ -1125,7 +1125,68 @@ function createAuthClient(config = {}) {
1125
1125
  ];
1126
1126
  }
1127
1127
  }
1128
- return [null, session];
1128
+ if (!dataClient) {
1129
+ return [
1130
+ new CapxulError({
1131
+ code: "NOT_AUTHENTICATED",
1132
+ message: "Auth bootstrap requires an authenticated Convex data client."
1133
+ }),
1134
+ null
1135
+ ];
1136
+ }
1137
+ try {
1138
+ const resolution = await dataClient.mutation(
1139
+ api.authBootstrap.resolveAfterOtp,
1140
+ {
1141
+ email: session.email,
1142
+ sessionToken: session.token
1143
+ }
1144
+ );
1145
+ if (resolution.kind === "existing_member") {
1146
+ return [null, { ...resolution, session }];
1147
+ }
1148
+ return [null, { ...resolution, session }];
1149
+ } catch (cause) {
1150
+ return [fromConvexError(cause), null];
1151
+ }
1152
+ },
1153
+ completeBootstrap: async (input) => {
1154
+ const session = sessionStore.get();
1155
+ const data = dataClient ?? config.data;
1156
+ if (!session || !data) {
1157
+ return [
1158
+ new CapxulError({
1159
+ code: "INVALID_INPUT",
1160
+ message: "completeBootstrap requires the OTP-verified session that issued the bootstrap token."
1161
+ }),
1162
+ null
1163
+ ];
1164
+ }
1165
+ if (input.signerProvider.kind !== "local-private-key") {
1166
+ return [
1167
+ new CapxulError({
1168
+ code: "INVALID_INPUT",
1169
+ message: "completeBootstrap currently supports local-private-key signer providers only."
1170
+ }),
1171
+ null
1172
+ ];
1173
+ }
1174
+ try {
1175
+ const result = await data.mutation(api.authBootstrap.completeBootstrap, {
1176
+ bootstrapToken: input.bootstrapToken,
1177
+ sessionToken: session.token,
1178
+ username: input.username,
1179
+ displayName: input.displayName,
1180
+ countryCode: input.countryCode,
1181
+ signerProvider: input.signerProvider
1182
+ });
1183
+ return [null, { kind: "authenticated", session, ...result }];
1184
+ } catch (cause) {
1185
+ return [
1186
+ fromConvexError(cause),
1187
+ null
1188
+ ];
1189
+ }
1129
1190
  },
1130
1191
  getSession: async () => [null, sessionStore.get()],
1131
1192
  signOut: async () => {
@@ -2484,7 +2545,7 @@ function createAuthFlowMachine(client) {
2484
2545
  }),
2485
2546
  verifyOtp: fromPromise(
2486
2547
  async ({ input, signal }) => {
2487
- const [error, session] = await client.auth.verifyOtp(
2548
+ const [error, result] = await client.auth.verifyOtp(
2488
2549
  {
2489
2550
  email: input.email,
2490
2551
  otp: input.code
@@ -2492,7 +2553,14 @@ function createAuthFlowMachine(client) {
2492
2553
  { signal }
2493
2554
  );
2494
2555
  if (error) throw error;
2495
- return session;
2556
+ if (result.kind === "bootstrap_required") {
2557
+ throw new CapxulError({
2558
+ code: "ACTION_REQUIRED",
2559
+ message: "OTP verified but auth bootstrap is required. Use createAuthBootstrapFlowMachine for product sign-up.",
2560
+ details: { reason: result.reason }
2561
+ });
2562
+ }
2563
+ return result.session;
2496
2564
  }
2497
2565
  ),
2498
2566
  signOut: fromPromise(async () => {
@@ -2740,6 +2808,345 @@ function emailDomain(email) {
2740
2808
  const domain = email.split("@")[1]?.trim().toLowerCase();
2741
2809
  return domain || "unknown";
2742
2810
  }
2811
+ var initialContext = {
2812
+ email: null,
2813
+ code: null,
2814
+ username: null,
2815
+ signerProvider: null,
2816
+ bootstrapToken: null,
2817
+ bootstrapReason: null,
2818
+ session: null,
2819
+ account: null,
2820
+ safe: null,
2821
+ error: null
2822
+ };
2823
+ function createAuthBootstrapFlowMachine(client) {
2824
+ return setup({
2825
+ types: {},
2826
+ actors: {
2827
+ sendOtp: fromPromise(async ({ input, signal }) => {
2828
+ const [error] = await client.auth.sendOtp(
2829
+ { email: input.email },
2830
+ { signal }
2831
+ );
2832
+ if (error) throw error;
2833
+ }),
2834
+ verifyOtp: fromPromise(
2835
+ async ({ input, signal }) => {
2836
+ const [error, result] = await client.auth.verifyOtp(
2837
+ { email: input.email, otp: input.code },
2838
+ { signal }
2839
+ );
2840
+ if (error) throw error;
2841
+ return result;
2842
+ }
2843
+ ),
2844
+ completeBootstrap: fromPromise(async ({ input }) => {
2845
+ const [error, result] = await client.auth.completeBootstrap(input);
2846
+ if (error) throw error;
2847
+ return result;
2848
+ }),
2849
+ signOut: fromPromise(async () => {
2850
+ const [error] = await client.auth.signOut();
2851
+ if (error) throw error;
2852
+ })
2853
+ },
2854
+ actions: {
2855
+ trackOtpRequested: ({ context }) => {
2856
+ if (!context.email) return;
2857
+ track("auth_otp_requested", {
2858
+ email_domain: emailDomain2(context.email)
2859
+ });
2860
+ },
2861
+ trackFailed: ({ event }) => {
2862
+ track("auth_failed", {
2863
+ auth_type: "email_otp",
2864
+ reason: errorFromEvent2(event).code
2865
+ });
2866
+ },
2867
+ trackTimeoutFailed: () => {
2868
+ track("auth_failed", {
2869
+ auth_type: "email_otp",
2870
+ reason: "timeout"
2871
+ });
2872
+ },
2873
+ trackVerified: () => {
2874
+ track("auth_verified", { auth_type: "email_otp" });
2875
+ },
2876
+ trackBootstrapRequired: ({ context }) => {
2877
+ track("auth_verified", {
2878
+ auth_type: "email_otp",
2879
+ auth_mode: context.bootstrapReason ?? "bootstrap_required"
2880
+ });
2881
+ },
2882
+ identifyAndTrack: ({ context }) => {
2883
+ if (!context.session) return;
2884
+ identify(context.session.authUserId, {
2885
+ email_domain: emailDomain2(context.session.email)
2886
+ });
2887
+ track("auth_identified", {
2888
+ email_domain: emailDomain2(context.session.email)
2889
+ });
2890
+ },
2891
+ trackSignedOut: () => {
2892
+ track("auth_signed_out");
2893
+ }
2894
+ }
2895
+ }).createMachine({
2896
+ id: "authBootstrap",
2897
+ initial: "email",
2898
+ context: initialContext,
2899
+ states: {
2900
+ email: {
2901
+ on: {
2902
+ ENTER_EMAIL: {
2903
+ actions: assign({
2904
+ email: ({ event }) => event.email,
2905
+ error: () => null
2906
+ })
2907
+ },
2908
+ REQUEST_OTP: { target: "sending_otp" }
2909
+ }
2910
+ },
2911
+ sending_otp: {
2912
+ invoke: {
2913
+ src: "sendOtp",
2914
+ input: ({ context }) => ({ email: requireEmail2(context) }),
2915
+ onDone: { target: "otp_requested", actions: "trackOtpRequested" },
2916
+ onError: {
2917
+ target: "otp_requested",
2918
+ actions: [
2919
+ assign({ error: ({ event }) => errorFromEvent2(event) }),
2920
+ "trackFailed"
2921
+ ]
2922
+ }
2923
+ },
2924
+ after: {
2925
+ [FLOW_INVOKE_TIMEOUT_MS]: {
2926
+ target: "otp_requested",
2927
+ actions: [
2928
+ assign({ error: () => timeoutError2("sending_otp") }),
2929
+ "trackTimeoutFailed"
2930
+ ]
2931
+ }
2932
+ }
2933
+ },
2934
+ otp_requested: {
2935
+ on: {
2936
+ ENTER_OTP: {
2937
+ actions: assign({
2938
+ code: ({ event }) => event.code,
2939
+ error: () => null
2940
+ })
2941
+ },
2942
+ VERIFY_OTP: { target: "verifying_otp" },
2943
+ BACK: { target: "email" },
2944
+ RESET: { target: "email", actions: assign(() => initialContext) }
2945
+ }
2946
+ },
2947
+ verifying_otp: {
2948
+ invoke: {
2949
+ src: "verifyOtp",
2950
+ input: ({ context }) => ({
2951
+ email: requireEmail2(context),
2952
+ code: requireCode(context)
2953
+ }),
2954
+ onDone: [
2955
+ {
2956
+ guard: ({ event }) => event.output.kind === "existing_member",
2957
+ target: "authenticated",
2958
+ actions: [
2959
+ assign({
2960
+ session: ({ event }) => event.output.session,
2961
+ account: ({ event }) => event.output.kind === "existing_member" ? event.output.account : null,
2962
+ username: ({ event }) => event.output.kind === "existing_member" ? event.output.username : null,
2963
+ safe: ({ event }) => event.output.kind === "existing_member" ? event.output.safe : null,
2964
+ email: () => null,
2965
+ error: () => null
2966
+ }),
2967
+ "trackVerified",
2968
+ "identifyAndTrack"
2969
+ ]
2970
+ },
2971
+ {
2972
+ target: "bootstrap_required",
2973
+ actions: [
2974
+ assign({
2975
+ session: ({ event }) => event.output.session,
2976
+ bootstrapToken: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.bootstrapToken : null,
2977
+ bootstrapReason: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.reason : null,
2978
+ username: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.username ?? null : null,
2979
+ email: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.email : null,
2980
+ error: () => null
2981
+ }),
2982
+ "trackVerified",
2983
+ "trackBootstrapRequired"
2984
+ ]
2985
+ }
2986
+ ],
2987
+ onError: {
2988
+ target: "otp_requested",
2989
+ actions: [
2990
+ assign({ error: ({ event }) => errorFromEvent2(event) }),
2991
+ "trackFailed"
2992
+ ]
2993
+ }
2994
+ },
2995
+ after: {
2996
+ [FLOW_INVOKE_TIMEOUT_MS]: {
2997
+ target: "otp_requested",
2998
+ actions: [
2999
+ assign({ error: () => timeoutError2("verifying_otp") }),
3000
+ "trackTimeoutFailed"
3001
+ ]
3002
+ }
3003
+ }
3004
+ },
3005
+ bootstrap_required: {
3006
+ on: {
3007
+ ENTER_USERNAME: {
3008
+ actions: assign({
3009
+ username: ({ event }) => event.username,
3010
+ error: () => null
3011
+ })
3012
+ },
3013
+ ENTER_SIGNER_PROVIDER: {
3014
+ actions: assign({
3015
+ signerProvider: ({ event }) => event.signerProvider,
3016
+ error: () => null
3017
+ })
3018
+ },
3019
+ COMPLETE_BOOTSTRAP: { target: "completing_bootstrap" },
3020
+ BACK: { target: "otp_requested" },
3021
+ RESET: { target: "email", actions: assign(() => initialContext) }
3022
+ }
3023
+ },
3024
+ completing_bootstrap: {
3025
+ invoke: {
3026
+ src: "completeBootstrap",
3027
+ input: ({ context }) => ({
3028
+ bootstrapToken: requireBootstrapToken(context),
3029
+ username: requireUsername(context),
3030
+ signerProvider: requireSignerProvider(context)
3031
+ }),
3032
+ onDone: {
3033
+ target: "authenticated",
3034
+ actions: [
3035
+ assign({
3036
+ session: ({ event }) => event.output.session,
3037
+ account: ({ event }) => event.output.account,
3038
+ username: ({ event }) => event.output.username,
3039
+ safe: ({ event }) => event.output.safe,
3040
+ bootstrapToken: () => null,
3041
+ bootstrapReason: () => null,
3042
+ signerProvider: () => null,
3043
+ email: () => null,
3044
+ error: () => null
3045
+ }),
3046
+ "identifyAndTrack"
3047
+ ]
3048
+ },
3049
+ onError: {
3050
+ target: "bootstrap_required",
3051
+ actions: [
3052
+ assign({ error: ({ event }) => errorFromEvent2(event) }),
3053
+ "trackFailed"
3054
+ ]
3055
+ }
3056
+ },
3057
+ after: {
3058
+ [FLOW_INVOKE_TIMEOUT_MS]: {
3059
+ target: "bootstrap_required",
3060
+ actions: [
3061
+ assign({ error: () => timeoutError2("completing_bootstrap") }),
3062
+ "trackTimeoutFailed"
3063
+ ]
3064
+ }
3065
+ }
3066
+ },
3067
+ authenticated: {
3068
+ on: {
3069
+ SIGN_OUT: { target: "signing_out" }
3070
+ }
3071
+ },
3072
+ signing_out: {
3073
+ invoke: {
3074
+ src: "signOut",
3075
+ onDone: {
3076
+ target: "email",
3077
+ actions: [
3078
+ assign(() => initialContext),
3079
+ "trackSignedOut"
3080
+ ]
3081
+ },
3082
+ onError: {
3083
+ target: "error",
3084
+ actions: assign({ error: ({ event }) => errorFromEvent2(event) })
3085
+ }
3086
+ }
3087
+ },
3088
+ error: {
3089
+ on: {
3090
+ RESET: { target: "email", actions: assign(() => initialContext) }
3091
+ }
3092
+ }
3093
+ }
3094
+ });
3095
+ }
3096
+ function requireEmail2(context) {
3097
+ if (!context.email) {
3098
+ throw Errors.invalidInput("email", "Auth bootstrap requires an email.");
3099
+ }
3100
+ return context.email;
3101
+ }
3102
+ function requireCode(context) {
3103
+ if (!context.code) {
3104
+ throw Errors.invalidInput("code", "Auth bootstrap requires an OTP code.");
3105
+ }
3106
+ return context.code;
3107
+ }
3108
+ function requireBootstrapToken(context) {
3109
+ if (!context.bootstrapToken) {
3110
+ throw Errors.invalidInput(
3111
+ "bootstrapToken",
3112
+ "Auth bootstrap requires a continuation token."
3113
+ );
3114
+ }
3115
+ return context.bootstrapToken;
3116
+ }
3117
+ function requireUsername(context) {
3118
+ if (!context.username) {
3119
+ throw Errors.invalidInput("username", "Auth bootstrap requires a username.");
3120
+ }
3121
+ return context.username;
3122
+ }
3123
+ function requireSignerProvider(context) {
3124
+ if (!context.signerProvider) {
3125
+ throw Errors.invalidInput(
3126
+ "signerProvider",
3127
+ "Auth bootstrap requires a signer provider."
3128
+ );
3129
+ }
3130
+ return context.signerProvider;
3131
+ }
3132
+ function errorFromEvent2(event) {
3133
+ const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
3134
+ if (cause instanceof CapxulError || cause instanceof CapxulError2) {
3135
+ return cause;
3136
+ }
3137
+ return Errors.providerError("auth", "bootstrap", cause);
3138
+ }
3139
+ function timeoutError2(state) {
3140
+ return Errors.providerError(
3141
+ "auth",
3142
+ "bootstrap",
3143
+ new Error(`timeout: ${state} exceeded ${FLOW_INVOKE_TIMEOUT_MS}ms`)
3144
+ );
3145
+ }
3146
+ function emailDomain2(email) {
3147
+ const domain = email.split("@")[1]?.trim().toLowerCase();
3148
+ return domain || "unknown";
3149
+ }
2743
3150
  function createProvisioningMachine(client) {
2744
3151
  return setup({
2745
3152
  types: {},
@@ -2812,13 +3219,13 @@ function createProvisioningMachine(client) {
2812
3219
  },
2813
3220
  onError: {
2814
3221
  target: "error",
2815
- actions: assign({ error: ({ event }) => errorFromEvent2(event) })
3222
+ actions: assign({ error: ({ event }) => errorFromEvent3(event) })
2816
3223
  }
2817
3224
  },
2818
3225
  after: {
2819
3226
  [FLOW_INVOKE_TIMEOUT_MS]: {
2820
3227
  target: "error",
2821
- actions: assign({ error: () => timeoutError2() })
3228
+ actions: assign({ error: () => timeoutError3() })
2822
3229
  }
2823
3230
  }
2824
3231
  },
@@ -2836,7 +3243,7 @@ function createProvisioningMachine(client) {
2836
3243
  * this payload on its `onDone` transition and branches via guards
2837
3244
  * on `event.output.error`.
2838
3245
  */
2839
- output: ({ context }) => context.error ? { error: context.error } : context.account ? { account: context.account } : { error: timeoutError2() }
3246
+ output: ({ context }) => context.error ? { error: context.error } : context.account ? { account: context.account } : { error: timeoutError3() }
2840
3247
  });
2841
3248
  }
2842
3249
  function requireProvisionInput(context) {
@@ -2848,13 +3255,13 @@ function requireProvisionInput(context) {
2848
3255
  }
2849
3256
  return context.input;
2850
3257
  }
2851
- function errorFromEvent2(event) {
3258
+ function errorFromEvent3(event) {
2852
3259
  const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
2853
3260
  if (cause instanceof CapxulError) return cause;
2854
3261
  if (cause instanceof CapxulError2) return cause;
2855
3262
  return Errors.providerError("provisioning", "flow", cause);
2856
3263
  }
2857
- function timeoutError2() {
3264
+ function timeoutError3() {
2858
3265
  return Errors.providerError(
2859
3266
  "provisioning",
2860
3267
  "flow",
@@ -2947,7 +3354,7 @@ function createOnboardingFlowMachine(client) {
2947
3354
  error: ({ event }) => extractChildErrorOrFallback(event)
2948
3355
  }),
2949
3356
  assignChildThrown: assign({
2950
- error: ({ event }) => errorFromEvent3(event)
3357
+ error: ({ event }) => errorFromEvent4(event)
2951
3358
  }),
2952
3359
  assignAccountFromChild: assign({
2953
3360
  account: ({ event }) => extractChildAccountOrNull(event)
@@ -3109,7 +3516,7 @@ function extractChildAccountOrNull(event) {
3109
3516
  if (output && "account" in output && output.account) return output.account;
3110
3517
  return null;
3111
3518
  }
3112
- function errorFromEvent3(event) {
3519
+ function errorFromEvent4(event) {
3113
3520
  const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
3114
3521
  if (cause instanceof CapxulError) return cause;
3115
3522
  if (cause instanceof CapxulError2) return cause;
@@ -3141,6 +3548,7 @@ function createCapxulClient(config = {}) {
3141
3548
  const client = clientWithoutFlows;
3142
3549
  client.flows = {
3143
3550
  auth: () => createAuthFlowMachine(client),
3551
+ authBootstrap: () => createAuthBootstrapFlowMachine(client),
3144
3552
  onboarding: () => createOnboardingFlowMachine(client),
3145
3553
  provisioning: () => createProvisioningMachine(client)
3146
3554
  };
@@ -3245,4 +3653,4 @@ function isWebhookEvent(value) {
3245
3653
  return typeof candidate.id === "string" && typeof candidate.type === "string" && typeof candidate.createdAt === "string" && (candidate.operationId === void 0 || typeof candidate.operationId === "string") && (candidate.correlationId === void 0 || typeof candidate.correlationId === "string") && !!candidate.data && typeof candidate.data === "object" && !Array.isArray(candidate.data);
3246
3654
  }
3247
3655
 
3248
- export { CapxulError, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };
3656
+ export { CapxulError, createAuthBootstrapFlowMachine, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capxul/sdk",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "Headless TypeScript client for Capxul's /v1/* HTTP contract.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -73,8 +73,8 @@
73
73
  "viem": "2.47.10",
74
74
  "vitest": "^4.1.2",
75
75
  "zod": "^4.3.6",
76
- "@repo/api-contract": "0.0.0",
77
76
  "@repo/backend": "0.0.0",
77
+ "@repo/api-contract": "0.0.0",
78
78
  "@repo/config": "0.0.0",
79
79
  "@repo/observability": "0.0.0",
80
80
  "@repo/platform-kernel": "0.0.0",