@capxul/sdk 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.
Files changed (45) hide show
  1. package/README.md +4 -266
  2. package/dist/InMemoryAuthCacheAdapter-BK-B_ERB.mjs +113 -0
  3. package/dist/InMemoryAuthCacheAdapter-BK-B_ERB.mjs.map +1 -0
  4. package/dist/index.d.mts +1263 -0
  5. package/dist/index.d.mts.map +1 -0
  6. package/dist/index.mjs +4740 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/node/index.d.mts +55 -0
  9. package/dist/node/index.d.mts.map +1 -0
  10. package/dist/node/index.mjs +159 -0
  11. package/dist/node/index.mjs.map +1 -0
  12. package/dist/ports/safe-deployment.d.mts +2 -0
  13. package/dist/ports/safe-deployment.mjs +38 -0
  14. package/dist/ports/safe-deployment.mjs.map +1 -0
  15. package/dist/safe-deployment-Vni46k3t.d.mts +137 -0
  16. package/dist/safe-deployment-Vni46k3t.d.mts.map +1 -0
  17. package/dist/signer-oaYGfjDe.d.mts +142 -0
  18. package/dist/signer-oaYGfjDe.d.mts.map +1 -0
  19. package/package.json +37 -71
  20. package/CHANGELOG.md +0 -256
  21. package/LICENSE +0 -44
  22. package/dist/client-B_Z3ThFO.d.cts +0 -1484
  23. package/dist/client-pMBRFcsz.d.ts +0 -1484
  24. package/dist/client.cjs +0 -4324
  25. package/dist/client.d.cts +0 -6
  26. package/dist/client.d.ts +0 -6
  27. package/dist/client.js +0 -4322
  28. package/dist/errors-CwhCWGxm.d.ts +0 -70
  29. package/dist/errors-rqxuUhQP.d.cts +0 -70
  30. package/dist/errors.cjs +0 -35
  31. package/dist/errors.d.cts +0 -2
  32. package/dist/errors.d.ts +0 -2
  33. package/dist/errors.js +0 -31
  34. package/dist/index.cjs +0 -4626
  35. package/dist/index.d.cts +0 -571
  36. package/dist/index.d.ts +0 -571
  37. package/dist/index.js +0 -4585
  38. package/dist/next-action-CTGl8wpy.d.cts +0 -177
  39. package/dist/next-action-CTGl8wpy.d.ts +0 -177
  40. package/dist/types-Brucpq0Z.d.cts +0 -1191
  41. package/dist/types-V_D7qjxY.d.ts +0 -1191
  42. package/dist/webhooks.cjs +0 -118
  43. package/dist/webhooks.d.cts +0 -33
  44. package/dist/webhooks.d.ts +0 -33
  45. package/dist/webhooks.js +0 -116
@@ -1,1484 +0,0 @@
1
- import { Account as Account$1 } from 'viem';
2
- import * as xstate from 'xstate';
3
- import { AnyStateMachine } from 'xstate';
4
- import { A as AccountId, S as SafeId, c as KycProfileId, b as ExternalAccountId, f as SubAccountId, d as OrganizationId, a as ApiKeyId, X as TimestampIso, U as Username, E as Email, D as DocumentId, O as OperationId, P as PaymentId, g as TransferId, k as WithdrawalId, W as WebhookEndpointId, j as WebhookEventId, M as MemberId, V as VirtualAccountId, i as VirtualCardId } from './next-action-CTGl8wpy.cjs';
5
- import { d as CapxulResult, C as CapxulError$1 } from './errors-rqxuUhQP.cjs';
6
- import { A as Account, X as UserIdentifier, a as AccountLookupResult, S as Safe, k as KycProfile, E as ExternalAccount, L as List, F as SubAccount, B as BalanceLedgerEntry, b as ApiKey, a5 as CreateApiKeyRequest, a6 as CreateDocumentRequest, D as Document, O as Operation, q as OperationStatus, p as Money, C as CreatePaymentResult, t as Payment, Q as TransferEndpoint, f as CreateTransferResult, J as Transfer, g as CreateWithdrawalResult, a3 as Withdrawal, a7 as CreateWebhookEndpointRequest, a1 as WebhookEndpoint, a2 as WebhookEvent, s as Organization, W as Treasury, o as MembershipStatus, M as Member, n as MemberInviteResponse, a8 as CreateVirtualAccountRequest, Y as VirtualAccount, a9 as CreateVirtualCardRequest, _ as VirtualCard } from './types-Brucpq0Z.cjs';
7
-
8
- /**
9
- * Accounts domain — individual user accounts per sdk-surface.md §1a.
10
- *
11
- * Nested namespaces under `accounts.*` follow Pattern A per CANON.md
12
- * §4.30: `accounts.safes.retrieve(safeId)`, `accounts.subAccounts.list()`,
13
- * etc. — no ambient account context; the argument carries the scope.
14
- */
15
-
16
- type AccountLookupInput = UserIdentifier;
17
- type AccountUpdateInput = Partial<{
18
- readonly name: string;
19
- readonly username: string;
20
- readonly countryCode: string;
21
- }>;
22
- type LocalPrivateKeySignerProvider = {
23
- readonly kind: "local-private-key";
24
- readonly signerAddress: string;
25
- };
26
- type AccountProvisionPersonalInput = {
27
- readonly displayName?: string;
28
- readonly username?: string;
29
- readonly countryCode?: string;
30
- readonly signerProvider: LocalPrivateKeySignerProvider;
31
- };
32
- type AccountCreateKycProfileInput = {
33
- readonly accountId: AccountId;
34
- };
35
- type AccountListInput = {
36
- readonly limit?: number;
37
- readonly cursor?: string;
38
- };
39
- type AccountCreateSubAccountInput = {
40
- readonly accountId: AccountId;
41
- readonly name: string;
42
- readonly purpose?: string;
43
- };
44
- type AccountCreateExternalAccountInput = {
45
- readonly accountId: AccountId;
46
- readonly kind: "bank" | "evm" | "solana" | "starknet" | "card_payout";
47
- readonly label?: string;
48
- readonly address?: string;
49
- readonly iban?: string;
50
- readonly bic?: string;
51
- readonly accountHolder?: string;
52
- readonly network?: "visa" | "mastercard";
53
- readonly panToken?: string;
54
- readonly last4?: string;
55
- };
56
- type RetrieveCodes$e = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
57
- type LookupCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
58
- type UpdateCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "INVALID_INPUT";
59
- type ListCodes$b = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
60
- type SafeRetrieveCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "SAFE_NOT_READY";
61
- type RemoveCodes$5 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
62
- type SubAccountRemoveCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "INVALID_INPUT";
63
- type AccountSafesClient = {
64
- readonly retrieve: (safeId: SafeId) => Promise<CapxulResult<Safe, SafeRetrieveCodes$1>>;
65
- };
66
- type AccountKycProfilesClient = {
67
- readonly create: (input: AccountCreateKycProfileInput) => Promise<CapxulResult<KycProfile, UpdateCodes$1>>;
68
- readonly retrieve: (kycProfileId: KycProfileId) => Promise<CapxulResult<KycProfile, RetrieveCodes$e>>;
69
- };
70
- type AccountExternalAccountsClient = {
71
- readonly create: (input: AccountCreateExternalAccountInput) => Promise<CapxulResult<ExternalAccount, UpdateCodes$1>>;
72
- readonly list: (input: {
73
- readonly accountId: AccountId;
74
- } & AccountListInput) => Promise<CapxulResult<List<ExternalAccount>, ListCodes$b>>;
75
- readonly retrieve: (externalAccountId: ExternalAccountId) => Promise<CapxulResult<ExternalAccount, RetrieveCodes$e>>;
76
- readonly remove: (externalAccountId: ExternalAccountId) => Promise<CapxulResult<void, RemoveCodes$5>>;
77
- };
78
- type AccountSubAccountsClient = {
79
- readonly create: (input: AccountCreateSubAccountInput) => Promise<CapxulResult<SubAccount, UpdateCodes$1 | "PROVIDER_ERROR">>;
80
- readonly list: (input: {
81
- readonly accountId: AccountId;
82
- } & AccountListInput) => Promise<CapxulResult<List<SubAccount>, ListCodes$b | "PROVIDER_ERROR">>;
83
- readonly retrieve: (subAccountId: SubAccountId) => Promise<CapxulResult<SubAccount, RetrieveCodes$e | "PROVIDER_ERROR">>;
84
- readonly remove: (subAccountId: SubAccountId) => Promise<CapxulResult<SubAccount, SubAccountRemoveCodes$1 | "PROVIDER_ERROR">>;
85
- };
86
- type AccountBalanceLedgerClient = {
87
- readonly list: (input: {
88
- readonly accountId: AccountId;
89
- } & AccountListInput) => Promise<CapxulResult<List<BalanceLedgerEntry>, ListCodes$b>>;
90
- readonly retrieve: (entryId: string) => Promise<CapxulResult<BalanceLedgerEntry, RetrieveCodes$e>>;
91
- };
92
- type AccountsClient = {
93
- readonly retrieve: (accountId: AccountId) => Promise<CapxulResult<Account, RetrieveCodes$e>>;
94
- readonly lookup: (input: AccountLookupInput) => Promise<CapxulResult<AccountLookupResult, LookupCodes>>;
95
- readonly update: (input: {
96
- readonly accountId: AccountId;
97
- } & AccountUpdateInput) => Promise<CapxulResult<Account, UpdateCodes$1>>;
98
- readonly provisionPersonal: (input: AccountProvisionPersonalInput) => Promise<CapxulResult<Account, UpdateCodes$1 | "NETWORK_ERROR">>;
99
- readonly safes: AccountSafesClient;
100
- readonly kycProfiles: AccountKycProfilesClient;
101
- readonly externalAccounts: AccountExternalAccountsClient;
102
- readonly subAccounts: AccountSubAccountsClient;
103
- readonly balanceLedger: AccountBalanceLedgerClient;
104
- };
105
-
106
- /**
107
- * API keys domain — org-issued credentials per sdk-surface.md §1b +
108
- * §4.21 + §4.57. Key types: `cap_test_` / `cap_live_` (secret) and
109
- * `cap_pk_test_` / `cap_pk_live_` (publishable).
110
- *
111
- * All methods are org-nested. The one-time `secret` value is returned
112
- * on `create` only; subsequent reads omit it.
113
- */
114
-
115
- type ApiKeysCreateInput = CreateApiKeyRequest & {
116
- readonly organizationId: OrganizationId;
117
- };
118
- type ApiKeysRetrieveInput = {
119
- readonly organizationId: OrganizationId;
120
- readonly apiKeyId: ApiKeyId;
121
- };
122
- type ApiKeysListInput = {
123
- readonly organizationId: OrganizationId;
124
- readonly limit?: number;
125
- readonly cursor?: string;
126
- };
127
- type ApiKeysRevokeInput = ApiKeysRetrieveInput;
128
- type CreateCodes$8 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "RATE_LIMITED" | "NETWORK_ERROR";
129
- type RetrieveCodes$d = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
130
- type ListCodes$a = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
131
- type RevokeCodes = RetrieveCodes$d;
132
- /**
133
- * Shape returned by `organizations.apiKeys.create` — the one-time
134
- * secret `value` is included here and omitted from every subsequent
135
- * read.
136
- */
137
- type ApiKeyCreateResult = ApiKey & {
138
- readonly value: string;
139
- };
140
- type ApiKeysClient = {
141
- readonly create: (input: ApiKeysCreateInput) => Promise<CapxulResult<ApiKeyCreateResult, CreateCodes$8>>;
142
- readonly retrieve: (input: ApiKeysRetrieveInput) => Promise<CapxulResult<ApiKey, RetrieveCodes$d>>;
143
- readonly list: (input: ApiKeysListInput) => Promise<CapxulResult<List<ApiKey>, ListCodes$a>>;
144
- readonly revoke: (input: ApiKeysRevokeInput) => Promise<CapxulResult<ApiKey, RevokeCodes>>;
145
- };
146
-
147
- interface CapxulDataClient {
148
- query(name: any, args: any): Promise<any>;
149
- mutation(name: any, args: any): Promise<any>;
150
- action?(name: any, args: any): Promise<any>;
151
- }
152
-
153
- /**
154
- * Authentication domain.
155
- *
156
- * Maps 1:1 to `/v1/auth/*` HTTP endpoints. Human sign-in via email OTP;
157
- * partner servers mint short-lived service tokens from a long-lived
158
- * API key per sdk-surface.md §3.2.
159
- *
160
- * Stack-1 update: outbound HTTP routes through `makeHttpTransport`
161
- * (`packages/sdk/src/transport.ts`) so that `core/auth.ts` no longer
162
- * owns base-URL validation or `fetch` indirection. The BetterAuth
163
- * `/api/auth` path-mangling stays here — it is auth-protocol-specific
164
- * and the transport layer is auth-protocol-agnostic by design.
165
- *
166
- * Lazy transport construction: when `config.auth.baseUrl` is absent the
167
- * SDK is in scaffold/CLI mode and `sendOtp` / `verifyOtp` return the
168
- * `NOT_IMPLEMENTED` `stub` tuple (preserving the prior behavior). Only
169
- * when `baseUrl` is configured do we construct the transport — at
170
- * which point the build-time-urls variant of `BrowserCapxulConfig`
171
- * runs its own `Errors.invalidInput` validation.
172
- */
173
-
174
- type Session = {
175
- readonly authUserId: string;
176
- readonly accountId?: AccountId;
177
- readonly email: string;
178
- readonly token: string;
179
- readonly convexJwt?: string;
180
- readonly expiresAt: TimestampIso;
181
- };
182
- type AuthSessionStore = {
183
- get(): Session | null;
184
- set(session: Session): void;
185
- clear(): void;
186
- };
187
- type AuthSendOtpInput = {
188
- readonly email: string;
189
- };
190
- type AuthVerifyOtpInput = {
191
- readonly email: string;
192
- readonly otp: string;
193
- };
194
- type AuthBootstrapToken = string & {
195
- readonly __capxulAuthBootstrapTokenBrand: "AuthBootstrapToken";
196
- };
197
- type AuthBootstrapReason = "new_member" | "missing_profile" | "missing_account" | "missing_safe" | "missing_signer_grant";
198
- type VerifyOtpResult = {
199
- readonly kind: "existing_member";
200
- readonly session: Session;
201
- readonly account: Account;
202
- readonly username: Username;
203
- readonly safe: Safe;
204
- } | {
205
- readonly kind: "bootstrap_required";
206
- readonly session: Session;
207
- readonly bootstrapToken: AuthBootstrapToken;
208
- readonly email: Email;
209
- readonly reason: AuthBootstrapReason;
210
- readonly username?: Username;
211
- };
212
- type CompleteBootstrapInput = {
213
- readonly bootstrapToken: AuthBootstrapToken;
214
- readonly username: Username;
215
- readonly displayName?: string;
216
- readonly countryCode?: string;
217
- };
218
- type CompleteBootstrapResult = {
219
- readonly kind: "authenticated";
220
- readonly session: Session;
221
- readonly account: Account;
222
- readonly username: Username;
223
- readonly safe: Safe;
224
- };
225
- type AuthServiceTokenMintInput = {
226
- readonly apiKey: string;
227
- readonly audience?: string;
228
- };
229
- /**
230
- * Options bag for auth methods that perform outbound `fetch` work.
231
- *
232
- * Accepts an `AbortSignal` so XState v5 actors (and any other caller
233
- * that wants cancellation) can cancel the in-flight HTTP request when
234
- * the actor stops. The signal flows through `transport.fetch`'s
235
- * `RequestInit.signal` and into the underlying `fetch` impl, so
236
- * `signal.aborted === true` propagates to the network layer per the
237
- * Web Platform `fetch` contract. See PR #406 S5.
238
- */
239
- type AuthMethodOptions = {
240
- readonly signal?: AbortSignal;
241
- };
242
- type ServiceToken = {
243
- readonly token: string;
244
- readonly expiresAt: TimestampIso;
245
- };
246
- type SendOtpCodes = "EMAIL_DELIVERY_FAILED" | "INVALID_INPUT" | "RATE_LIMITED" | "NETWORK_ERROR" | "PROVIDER_ERROR" | "INTERNAL_ERROR" | "ENV_MISSING" | "UNKNOWN" | "NOT_AUTHENTICATED" | "PERMISSION_DENIED";
247
- type VerifyOtpCodes = "INVALID_INPUT" | "NOT_AUTHENTICATED" | "RATE_LIMITED" | "OPERATION_TIMEOUT" | "NETWORK_ERROR" | "PROVIDER_ERROR" | "INTERNAL_ERROR" | "ENV_MISSING" | "UNKNOWN" | "PERMISSION_DENIED";
248
- type CompleteBootstrapCodes = "INVALID_INPUT" | "IDEMPOTENCY_CONFLICT" | "RATE_LIMITED" | "PROFILE_NOT_FOUND" | "SMART_ACCOUNT_MISSING" | "PROVIDER_UNAVAILABLE" | "PROVIDER_REJECTED" | "OPERATION_TIMEOUT" | "NETWORK_ERROR" | "INTERNAL_ERROR";
249
- type GetSessionCodes = "NETWORK_ERROR";
250
- type SignOutCodes = "NOT_AUTHENTICATED" | "NETWORK_ERROR";
251
- type ServiceTokenMintCodes = "API_KEY_INVALID" | "API_KEY_EXPIRED" | "INVALID_INPUT" | "RATE_LIMITED" | "NETWORK_ERROR";
252
- type AuthClient = {
253
- readonly sendOtp: (input: AuthSendOtpInput, options?: AuthMethodOptions) => Promise<CapxulResult<void, SendOtpCodes>>;
254
- readonly verifyOtp: (input: AuthVerifyOtpInput, options?: AuthMethodOptions) => Promise<CapxulResult<VerifyOtpResult, VerifyOtpCodes>>;
255
- readonly completeBootstrap: (input: CompleteBootstrapInput) => Promise<CapxulResult<CompleteBootstrapResult, CompleteBootstrapCodes>>;
256
- readonly getSession: () => Promise<CapxulResult<Session | null, GetSessionCodes>>;
257
- readonly signOut: () => Promise<CapxulResult<void, SignOutCodes>>;
258
- readonly serviceTokenMint: (input: AuthServiceTokenMintInput) => Promise<CapxulResult<ServiceToken, ServiceTokenMintCodes>>;
259
- /** Internal bridge for flow hooks that need the authenticated Convex data client. */
260
- readonly getDataClient: () => CapxulDataClient | null;
261
- };
262
-
263
- /**
264
- * Documents domain — unified artifact primitive per sdk-surface.md §1a
265
- * + §4.50.
266
- *
267
- * Subsumes the former `invoice` and `org_payroll_entry` top-level
268
- * primitives. The `Document` union discriminates on `type`:
269
- * `invoice | payroll_run | payroll_schedule | receipt | kyc_upload |
270
- * bank_statement | tax_form`.
271
- */
272
-
273
- type DocumentsCreateInput = CreateDocumentRequest;
274
- type DocumentsListInput = {
275
- readonly limit?: number;
276
- readonly cursor?: string;
277
- readonly type?: Document["type"];
278
- };
279
- type OrgDocumentsCreateInput = DocumentsCreateInput & {
280
- readonly organizationId: OrganizationId;
281
- };
282
- type OrgDocumentsRetrieveInput = {
283
- readonly organizationId: OrganizationId;
284
- readonly documentId: DocumentId;
285
- };
286
- type OrgDocumentsListInput = {
287
- readonly organizationId: OrganizationId;
288
- readonly limit?: number;
289
- readonly cursor?: string;
290
- readonly type?: Document["type"];
291
- };
292
- type OrgDocumentsCancelInput = {
293
- readonly organizationId: OrganizationId;
294
- readonly documentId: DocumentId;
295
- };
296
- type CreateCodes$7 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "IDEMPOTENCY_CONFLICT" | "RATE_LIMITED" | "NETWORK_ERROR";
297
- type RetrieveCodes$c = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
298
- type ListCodes$9 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
299
- type CancelCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "OPERATION_CANCELED";
300
- type DocumentsClient = {
301
- readonly create: (input: DocumentsCreateInput) => Promise<CapxulResult<Document, CreateCodes$7>>;
302
- readonly retrieve: (documentId: DocumentId) => Promise<CapxulResult<Document, RetrieveCodes$c>>;
303
- readonly list: (input?: DocumentsListInput) => Promise<CapxulResult<List<Document>, ListCodes$9>>;
304
- readonly cancel: (documentId: DocumentId) => Promise<CapxulResult<Document, CancelCodes$1>>;
305
- };
306
- type OrgDocumentsClient = {
307
- readonly create: (input: OrgDocumentsCreateInput) => Promise<CapxulResult<Document, CreateCodes$7>>;
308
- readonly retrieve: (input: OrgDocumentsRetrieveInput) => Promise<CapxulResult<Document, RetrieveCodes$c>>;
309
- readonly list: (input: OrgDocumentsListInput) => Promise<CapxulResult<List<Document>, ListCodes$9>>;
310
- readonly cancel: (input: OrgDocumentsCancelInput) => Promise<CapxulResult<Document, CancelCodes$1>>;
311
- };
312
-
313
- /**
314
- * External-accounts domain — top-level `capxul.externalAccounts.*`.
315
- *
316
- * Per sdk-surface.md §1a, `external_account` is a reusable withdrawal
317
- * destination. `create` + `list` live under the owner's nested
318
- * namespace (Pattern A — `accounts.externalAccounts.*` or
319
- * `organizations.externalAccounts.*`). The top-level `retrieve` and
320
- * `remove` keep PERSONAL-scope semantics — for org rows route via
321
- * the `organizations.externalAccounts.*` namespace which carries
322
- * `organizationId` end-to-end and pins the row's owner pair to
323
- * prevent cross-org IDOR (revision 1, #464).
324
- *
325
- * Withdrawals v1 W1 (#464) wires these stubs through the
326
- * `externalAccounts/{queries,mutations}` Convex domain. The wire shape
327
- * matches OpenAPI: `{ object: "external_account", id, kind, status,
328
- * ..., operation: { id, status, correlationId } }` — the trust-chain
329
- * ids live under the canonical nested `operation: OperationSummary`
330
- * envelope (revision 3, #464), matching Withdrawal / Payment /
331
- * Transfer / Organization. The SDK rebrands `id` + the nested
332
- * `operation` sub-ids at the read edge.
333
- */
334
-
335
- type RetrieveCodes$b = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
336
- type RemoveCodes$4 = RetrieveCodes$b;
337
- type ExternalAccountsClient = {
338
- readonly retrieve: (externalAccountId: ExternalAccountId) => Promise<CapxulResult<ExternalAccount, RetrieveCodes$b>>;
339
- readonly remove: (externalAccountId: ExternalAccountId) => Promise<CapxulResult<void, RemoveCodes$4>>;
340
- };
341
-
342
- /**
343
- * `me` — first-party-only surface for the authenticated user.
344
- *
345
- * Partner SDK code (service-key lens) uses `capxul.accounts.retrieve(id)`
346
- * instead. This namespace exists because the CLI and `useMe()` hook
347
- * in `@capxul/sdk-react` always know the calling user and shouldn't
348
- * need to pass the account id.
349
- *
350
- * See `/docs/internal/reset/sdk-surface` + `packages/sdk/tests/walkthroughs/me-retrieve.ts`.
351
- */
352
-
353
- type MeUpdateInput = Partial<{
354
- readonly name: string;
355
- readonly username: string;
356
- readonly countryCode: string;
357
- }>;
358
- type MeGetCodes = "NOT_AUTHENTICATED" | "PROFILE_NOT_FOUND";
359
- type MeUpdateCodes = "NOT_AUTHENTICATED" | "PROFILE_NOT_FOUND" | "INVALID_INPUT";
360
- type MeClient = {
361
- readonly get: () => Promise<CapxulResult<Account, MeGetCodes>>;
362
- readonly update: (input: MeUpdateInput) => Promise<CapxulResult<Account, MeUpdateCodes>>;
363
- };
364
-
365
- /**
366
- * Operations domain — durable async-work envelope per sdk-surface.md §1b.
367
- *
368
- * `retrieve` is a snapshot read (no polling). `wait` is the opt-in
369
- * polling helper per CANON.md §4.40 — caller explicitly asks to block
370
- * until a terminal condition or timeout.
371
- */
372
-
373
- type OperationsWaitInput = {
374
- readonly until?: readonly OperationStatus[];
375
- readonly timeoutSeconds?: number;
376
- readonly pollIntervalMs?: number;
377
- };
378
- type RetrieveCodes$a = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
379
- type WaitCodes = RetrieveCodes$a | "OPERATION_TIMEOUT";
380
- type OperationsClient = {
381
- readonly retrieve: (operationId: OperationId) => Promise<CapxulResult<Operation, RetrieveCodes$a>>;
382
- readonly wait: (operationId: OperationId, input?: OperationsWaitInput) => Promise<CapxulResult<Operation, WaitCodes>>;
383
- };
384
-
385
- /**
386
- * Payments domain.
387
- *
388
- * Exposes both the personal-scope `PaymentsClient` (under
389
- * `capxul.payments.*`) and the org-scoped `OrgPaymentsClient` (under
390
- * `capxul.organizations.payments.*`). The org variant takes
391
- * `organizationId` explicitly on every call; there is no ambient org
392
- * context.
393
- *
394
- * See `/docs/internal/reset/sdk-surface` and the walkthroughs in
395
- * `packages/sdk/tests/walkthroughs/`.
396
- */
397
-
398
- type PaymentsCreateInput = {
399
- readonly to: UserIdentifier;
400
- readonly amount: Money;
401
- readonly reference?: string;
402
- readonly idempotencyKey?: string;
403
- readonly include?: readonly string[];
404
- /**
405
- * Funds v1 (#420): tag the payment with the originating sub-account.
406
- * This personal data-path forwards the field to Convex; broader
407
- * organization and React hook wiring lands in #421 alongside
408
- * `include: ["balancesByCustody"]` read paths.
409
- */
410
- readonly source?: {
411
- readonly subAccountId: SubAccountId;
412
- };
413
- };
414
- type PaymentsListInput = {
415
- readonly limit?: number;
416
- readonly cursor?: string;
417
- readonly include?: readonly string[];
418
- };
419
- type OrgPaymentsCreateInput = {
420
- readonly organizationId: OrganizationId;
421
- readonly source?: {
422
- readonly subAccountId: SubAccountId;
423
- };
424
- readonly to: UserIdentifier;
425
- readonly amount: Money;
426
- readonly reference?: string;
427
- readonly idempotencyKey?: string;
428
- readonly include?: readonly string[];
429
- };
430
- type OrgPaymentsRetrieveInput = {
431
- readonly organizationId: OrganizationId;
432
- readonly paymentId: PaymentId;
433
- };
434
- type OrgPaymentsListInput = {
435
- readonly organizationId: OrganizationId;
436
- readonly limit?: number;
437
- readonly cursor?: string;
438
- readonly include?: readonly string[];
439
- };
440
- type CreateCodes$6 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "INVALID_RECIPIENT" | "INSUFFICIENT_BALANCE" | "IDEMPOTENCY_CONFLICT" | "RATE_LIMITED" | "NETWORK_ERROR";
441
- type OrgCreateCodes = CreateCodes$6 | "POLICY_DENIED" | "SAFE_NOT_READY";
442
- type RetrieveCodes$9 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
443
- type ListCodes$8 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
444
- type PaymentsClient = {
445
- readonly create: (input: PaymentsCreateInput) => Promise<CapxulResult<CreatePaymentResult, CreateCodes$6>>;
446
- readonly retrieve: (paymentId: PaymentId) => Promise<CapxulResult<Payment, RetrieveCodes$9>>;
447
- readonly list: (input?: PaymentsListInput) => Promise<CapxulResult<List<Payment>, ListCodes$8>>;
448
- };
449
- type OrgPaymentsClient = {
450
- readonly create: (input: OrgPaymentsCreateInput) => Promise<CapxulResult<CreatePaymentResult, OrgCreateCodes>>;
451
- readonly retrieve: (input: OrgPaymentsRetrieveInput) => Promise<CapxulResult<Payment, RetrieveCodes$9>>;
452
- readonly list: (input: OrgPaymentsListInput) => Promise<CapxulResult<List<Payment>, ListCodes$8>>;
453
- };
454
-
455
- /**
456
- * Transfers domain — cross-custody internal moves per CANON.md §4.53.
457
- *
458
- * A transfer moves balance between custody sources owned by the same
459
- * account or organization (e.g. EUR virtual-account → USD stablecoin
460
- * pool). When currencies differ the wire carries an `fx` block with a
461
- * quote id the caller confirms via `transfers.confirm(...)` per §4.58.
462
- */
463
-
464
- type TransfersCreateInput = {
465
- readonly source: TransferEndpoint;
466
- readonly destination: TransferEndpoint;
467
- readonly amount: Money;
468
- readonly idempotencyKey?: string;
469
- readonly include?: readonly string[];
470
- };
471
- type TransfersListInput = {
472
- readonly limit?: number;
473
- readonly cursor?: string;
474
- };
475
- type TransfersConfirmInput = {
476
- readonly transferId: TransferId;
477
- readonly quoteId: string;
478
- };
479
- type OrgTransfersCreateInput = TransfersCreateInput & {
480
- readonly organizationId: OrganizationId;
481
- };
482
- type OrgTransfersRetrieveInput = {
483
- readonly organizationId: OrganizationId;
484
- readonly transferId: TransferId;
485
- };
486
- type OrgTransfersListInput = {
487
- readonly organizationId: OrganizationId;
488
- readonly limit?: number;
489
- readonly cursor?: string;
490
- };
491
- type OrgTransfersConfirmInput = {
492
- readonly organizationId: OrganizationId;
493
- readonly transferId: TransferId;
494
- readonly quoteId: string;
495
- };
496
- type OrgTransfersCancelInput = {
497
- readonly organizationId: OrganizationId;
498
- readonly transferId: TransferId;
499
- };
500
- type CreateCodes$5 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "INSUFFICIENT_BALANCE" | "IDEMPOTENCY_CONFLICT" | "RATE_LIMITED" | "NETWORK_ERROR";
501
- type RetrieveCodes$8 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
502
- type ListCodes$7 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
503
- type ConfirmCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "QUOTE_EXPIRED" | "QUOTE_NOT_FOUND";
504
- type CancelCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "OPERATION_CANCELED";
505
- type TransfersClient = {
506
- readonly create: (input: TransfersCreateInput) => Promise<CapxulResult<CreateTransferResult, CreateCodes$5>>;
507
- readonly retrieve: (transferId: TransferId) => Promise<CapxulResult<Transfer, RetrieveCodes$8>>;
508
- readonly list: (input?: TransfersListInput) => Promise<CapxulResult<List<Transfer>, ListCodes$7>>;
509
- readonly confirm: (input: TransfersConfirmInput) => Promise<CapxulResult<Transfer, ConfirmCodes>>;
510
- readonly cancel: (transferId: TransferId) => Promise<CapxulResult<Transfer, CancelCodes>>;
511
- };
512
- type OrgTransfersClient = {
513
- readonly create: (input: OrgTransfersCreateInput) => Promise<CapxulResult<CreateTransferResult, CreateCodes$5>>;
514
- readonly retrieve: (input: OrgTransfersRetrieveInput) => Promise<CapxulResult<Transfer, RetrieveCodes$8>>;
515
- readonly list: (input: OrgTransfersListInput) => Promise<CapxulResult<List<Transfer>, ListCodes$7>>;
516
- readonly confirm: (input: OrgTransfersConfirmInput) => Promise<CapxulResult<Transfer, ConfirmCodes>>;
517
- readonly cancel: (input: OrgTransfersCancelInput) => Promise<CapxulResult<Transfer, CancelCodes>>;
518
- };
519
-
520
- /**
521
- * Withdrawals domain — funds exit Capxul via an `external_account` per
522
- * sdk-surface.md §1a + §4.52 + withdrawal-orchestration.mdx.
523
- *
524
- * Withdrawals v1 W2 (#465) refactor:
525
- * - The `kind` shim on `destination` is GONE. The backend now resolves
526
- * the destination row by FK and infers kind + rail. Anything that
527
- * doesn't route to `chain_wallet` returns `VERIFICATION_REQUIRED`.
528
- * - Org-scope `create` is now a real mutation (no longer a stub).
529
- * Personal-scope keeps the on-chain submission tail; org-scope
530
- * returns the `processing` row only — Safe + Zodiac orchestration
531
- * ships in W3+ (D6).
532
- * - All raw `try/catch` blocks have been replaced with `tryCatch` from
533
- * `@repo/observability`, mirroring `core/external-accounts.ts`
534
- * (precedent D2).
535
- */
536
-
537
- type WithdrawalsCreateInput = {
538
- readonly amount: Money;
539
- readonly destination: {
540
- readonly externalAccountId: ExternalAccountId;
541
- };
542
- readonly source?: {
543
- readonly subAccountId: SubAccountId;
544
- };
545
- readonly reference?: string;
546
- readonly idempotencyKey?: string;
547
- readonly include?: readonly string[];
548
- };
549
- type WithdrawalsListInput = {
550
- readonly limit?: number;
551
- readonly cursor?: string;
552
- };
553
- /**
554
- * Withdrawals v1 W4 (#467) — input for the reconciliation pipe.
555
- * Caller passes the same `txHash` that `recordSubmitted` wrote; the
556
- * backend cross-checks the value against the persisted operation row.
557
- *
558
- * `withdrawalId` accepts either the branded `WithdrawalId` or a raw
559
- * string. `txHash` is a raw string at the SDK boundary — the backend
560
- * re-validates the shape via `toTxHash` at the mutation handler (the
561
- * SDK package is no longer coupled to `@repo/types`'s brand surface
562
- * post the alpha-epic decoupling; see
563
- * `packages/sdk/docs/internal/decoupling-prep.md`).
564
- */
565
- type WithdrawalsRecordCompletedInput = {
566
- readonly withdrawalId: WithdrawalId | string;
567
- readonly txHash: string;
568
- };
569
- type OrgWithdrawalsCreateInput = WithdrawalsCreateInput & {
570
- readonly organizationId: OrganizationId;
571
- };
572
- type OrgWithdrawalsRetrieveInput = {
573
- readonly organizationId: OrganizationId;
574
- readonly withdrawalId: WithdrawalId;
575
- };
576
- type OrgWithdrawalsListInput = {
577
- readonly organizationId: OrganizationId;
578
- readonly limit?: number;
579
- readonly cursor?: string;
580
- };
581
- type CreateCodes$4 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "INSUFFICIENT_BALANCE" | "IDEMPOTENCY_CONFLICT" | "KYC_REQUIRED" | "POLICY_DENIED" | "RATE_LIMITED" | "NETWORK_ERROR" | "NOT_FOUND" | "VERIFICATION_REQUIRED";
582
- type RetrieveCodes$7 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
583
- type ListCodes$6 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
584
- /**
585
- * Narrow code set for `recordCompleted`. Mirror of `recordSubmitted`'s
586
- * code surface — the SDK does NOT export `recordSubmitted` publicly
587
- * (the create signing tail invokes it), but the call shape is the
588
- * reference. Per ADR 9, `recordCompleted` is exposed on personal-scope
589
- * `WithdrawalsClient` ONLY.
590
- */
591
- type RecordCompletedCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "NOT_FOUND" | "NETWORK_ERROR" | "INTERNAL_ERROR";
592
- type WithdrawalsClient = {
593
- readonly create: (input: WithdrawalsCreateInput) => Promise<CapxulResult<CreateWithdrawalResult, CreateCodes$4>>;
594
- readonly retrieve: (withdrawalId: WithdrawalId) => Promise<CapxulResult<Withdrawal, RetrieveCodes$7>>;
595
- readonly list: (input?: WithdrawalsListInput) => Promise<CapxulResult<List<Withdrawal>, ListCodes$6>>;
596
- /**
597
- * Withdrawals v1 W4 (#467) — reconciliation pipe.
598
- *
599
- * Caller invokes this AFTER `withdrawals.create` resolves AND after
600
- * the on-chain receipt confirms (e.g., via the harness's
601
- * `chain.waitReceipt`). The mutation patches the withdrawal +
602
- * execution + attempt + operation rows to terminal happy state and
603
- * emits a single `operation.succeeded` outbox event joined to the
604
- * original correlationId. Idempotent on already-`completed` rows.
605
- *
606
- * Personal-scope only — the org-scope client does NOT expose this
607
- * method (mirror of `recordSubmitted`; see ADR 9 in #467).
608
- */
609
- readonly recordCompleted: (input: WithdrawalsRecordCompletedInput) => Promise<CapxulResult<null, RecordCompletedCodes>>;
610
- };
611
- type OrgWithdrawalsClient = {
612
- readonly create: (input: OrgWithdrawalsCreateInput) => Promise<CapxulResult<CreateWithdrawalResult, CreateCodes$4>>;
613
- readonly retrieve: (input: OrgWithdrawalsRetrieveInput) => Promise<CapxulResult<Withdrawal, RetrieveCodes$7>>;
614
- readonly list: (input: OrgWithdrawalsListInput) => Promise<CapxulResult<List<Withdrawal>, ListCodes$6>>;
615
- };
616
-
617
- /**
618
- * Webhook endpoints domain — developer-registered receivers per
619
- * sdk-surface.md §1b. All methods are org-nested (accessed via
620
- * `capxul.organizations.webhookEndpoints.*` per CANON.md §4.30).
621
- * The top-level `webhookEndpoints` surface on `CapxulClient` is kept
622
- * as an alias for discoverability; its methods proxy to the org
623
- * variant at call time and require `organizationId` explicitly.
624
- */
625
-
626
- type WebhookEndpointsCreateInput = CreateWebhookEndpointRequest & {
627
- readonly organizationId: OrganizationId;
628
- };
629
- type WebhookEndpointsRetrieveInput = {
630
- readonly organizationId: OrganizationId;
631
- readonly webhookEndpointId: WebhookEndpointId;
632
- };
633
- type WebhookEndpointsListInput = {
634
- readonly organizationId: OrganizationId;
635
- readonly limit?: number;
636
- readonly cursor?: string;
637
- };
638
- type WebhookEndpointsRemoveInput = WebhookEndpointsRetrieveInput;
639
- type CreateCodes$3 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "RATE_LIMITED" | "NETWORK_ERROR";
640
- type RetrieveCodes$6 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
641
- type ListCodes$5 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
642
- type RemoveCodes$3 = RetrieveCodes$6;
643
- /**
644
- * Shape returned by `organizations.webhookEndpoints.create` — the
645
- * one-time `signingSecret` is included here and omitted from every
646
- * subsequent read (per sdk-surface.md §1b).
647
- */
648
- type WebhookEndpointCreateResult = WebhookEndpoint & {
649
- readonly signingSecret: string;
650
- };
651
- type WebhookEndpointsClient = {
652
- readonly create: (input: WebhookEndpointsCreateInput) => Promise<CapxulResult<WebhookEndpointCreateResult, CreateCodes$3>>;
653
- readonly retrieve: (input: WebhookEndpointsRetrieveInput) => Promise<CapxulResult<WebhookEndpoint, RetrieveCodes$6>>;
654
- readonly list: (input: WebhookEndpointsListInput) => Promise<CapxulResult<List<WebhookEndpoint>, ListCodes$5>>;
655
- readonly remove: (input: WebhookEndpointsRemoveInput) => Promise<CapxulResult<void, RemoveCodes$3>>;
656
- };
657
-
658
- /**
659
- * Webhook events domain — individual delivery attempt + payload per
660
- * sdk-surface.md §1b. v1 is read-only (partner replay lands in v1.5
661
- * per §4.20). All methods are org-nested.
662
- */
663
-
664
- type WebhookEventsRetrieveInput = {
665
- readonly organizationId: OrganizationId;
666
- readonly webhookEventId: WebhookEventId;
667
- };
668
- type WebhookEventsListInput = {
669
- readonly organizationId: OrganizationId;
670
- readonly limit?: number;
671
- readonly cursor?: string;
672
- readonly endpointId?: string;
673
- readonly type?: string;
674
- };
675
- type RetrieveCodes$5 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
676
- type ListCodes$4 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
677
- type WebhookEventsClient = {
678
- readonly retrieve: (input: WebhookEventsRetrieveInput) => Promise<CapxulResult<WebhookEvent, RetrieveCodes$5>>;
679
- readonly list: (input: WebhookEventsListInput) => Promise<CapxulResult<List<WebhookEvent>, ListCodes$4>>;
680
- };
681
-
682
- /**
683
- * Organizations domain per sdk-surface.md §1a.
684
- *
685
- * The org surface is broad because org-scoped flows for every money-
686
- * movement + identity primitive live under `organizations.*` per
687
- * CANON.md §4.30 (Shape A). Sub-client factories delegate to the
688
- * dedicated domain factories in `core/*.ts` so the tuple-return +
689
- * error-narrowing plumbing is shared.
690
- */
691
-
692
- type OrganizationsCreateInput = {
693
- readonly name: string;
694
- readonly country?: string;
695
- };
696
- type OrganizationsListInput = {
697
- readonly limit?: number;
698
- readonly cursor?: string;
699
- };
700
- type OrganizationsUpdateInput = {
701
- readonly organizationId: OrganizationId;
702
- readonly name?: string;
703
- };
704
- type OrgSafeRetrieveInput = {
705
- readonly organizationId: OrganizationId;
706
- readonly safeId: SafeId;
707
- };
708
- type OrgMemberInviteInput = {
709
- readonly organizationId: OrganizationId;
710
- readonly email: string;
711
- readonly role: Member["role"];
712
- };
713
- type OrgMemberAcceptInput = {
714
- readonly token: string;
715
- };
716
- type OrgMemberUpdateRoleInput = {
717
- readonly organizationId: OrganizationId;
718
- readonly memberId: MemberId;
719
- readonly role: Member["role"];
720
- };
721
- type OrgMemberRemoveInput = {
722
- readonly organizationId: OrganizationId;
723
- readonly memberId: MemberId;
724
- };
725
- type OrgMemberRetrieveInput = OrgMemberRemoveInput;
726
- type OrgMemberRevokeInput = OrgMemberRemoveInput;
727
- type OrgMemberResendInput = OrgMemberRemoveInput;
728
- type OrgListInput = {
729
- readonly organizationId: OrganizationId;
730
- readonly limit?: number;
731
- readonly cursor?: string;
732
- };
733
- type OrgMemberListInput = {
734
- readonly organizationId: OrganizationId;
735
- readonly status?: MembershipStatus | "all";
736
- readonly limit?: number;
737
- readonly cursor?: string;
738
- };
739
- type OrgCreateSubAccountInput = {
740
- readonly organizationId: OrganizationId;
741
- readonly name: string;
742
- readonly purpose?: string;
743
- };
744
- type OrgCreateExternalAccountInput = {
745
- readonly organizationId: OrganizationId;
746
- readonly kind: "bank" | "evm" | "solana" | "starknet" | "card_payout";
747
- readonly label?: string;
748
- readonly address?: string;
749
- readonly iban?: string;
750
- readonly bic?: string;
751
- readonly accountHolder?: string;
752
- readonly network?: "visa" | "mastercard";
753
- readonly panToken?: string;
754
- readonly last4?: string;
755
- };
756
- type CreateCodes$2 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "RATE_LIMITED" | "NETWORK_ERROR";
757
- type RetrieveCodes$4 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
758
- type ListCodes$3 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
759
- type UpdateCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "INVALID_INPUT";
760
- /**
761
- * Org safe retrieve does NOT surface `SAFE_NOT_READY` — a co-member
762
- * who tries to read an in-flight Safe hits `PERMISSION_DENIED` (Safes
763
- * are admin-lens-only), and an admin gets `processing` via the
764
- * operation field. The mid-deploy balance view surfaces via
765
- * `treasury.retrieve` which DOES carry `SAFE_NOT_READY`.
766
- *
767
- * Contrast with `accounts.safes.retrieve` which DOES surface
768
- * `SAFE_NOT_READY` because personal Safes are visible to the owner
769
- * while deploying.
770
- */
771
- type SafeRetrieveCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
772
- type TreasuryRetrieveCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "SAFE_NOT_READY";
773
- type RemoveCodes$2 = RetrieveCodes$4;
774
- type SubAccountRemoveCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "INVALID_INPUT";
775
- type OrgSafesClient = {
776
- readonly retrieve: (input: OrgSafeRetrieveInput) => Promise<CapxulResult<Safe, SafeRetrieveCodes>>;
777
- };
778
- type OrgTreasuryClient = {
779
- readonly retrieve: (organizationId: OrganizationId) => Promise<CapxulResult<Treasury, TreasuryRetrieveCodes>>;
780
- };
781
- type OrgMembersClient = {
782
- readonly list: (input: OrgMemberListInput) => Promise<CapxulResult<List<Member>, ListCodes$3>>;
783
- readonly retrieve: (input: OrgMemberRetrieveInput) => Promise<CapxulResult<Member, RetrieveCodes$4>>;
784
- readonly invite: (input: OrgMemberInviteInput) => Promise<CapxulResult<MemberInviteResponse, UpdateCodes>>;
785
- readonly accept: (input: OrgMemberAcceptInput) => Promise<CapxulResult<Member, UpdateCodes>>;
786
- readonly updateRole: (input: OrgMemberUpdateRoleInput) => Promise<CapxulResult<Member, UpdateCodes>>;
787
- readonly revoke: (input: OrgMemberRevokeInput) => Promise<CapxulResult<Member, UpdateCodes>>;
788
- readonly remove: (input: OrgMemberRemoveInput) => Promise<CapxulResult<void, RemoveCodes$2>>;
789
- readonly resend: (input: OrgMemberResendInput) => Promise<CapxulResult<MemberInviteResponse, UpdateCodes>>;
790
- };
791
- type OrgSubAccountsClient = {
792
- readonly create: (input: OrgCreateSubAccountInput) => Promise<CapxulResult<SubAccount, UpdateCodes | "PROVIDER_ERROR">>;
793
- readonly list: (input: OrgListInput) => Promise<CapxulResult<List<SubAccount>, ListCodes$3 | "PROVIDER_ERROR">>;
794
- readonly retrieve: (input: {
795
- readonly organizationId: OrganizationId;
796
- readonly subAccountId: SubAccountId;
797
- }) => Promise<CapxulResult<SubAccount, RetrieveCodes$4 | "PROVIDER_ERROR">>;
798
- readonly remove: (input: {
799
- readonly organizationId: OrganizationId;
800
- readonly subAccountId: SubAccountId;
801
- }) => Promise<CapxulResult<SubAccount, SubAccountRemoveCodes | "PROVIDER_ERROR">>;
802
- };
803
- type OrgExternalAccountsClient = {
804
- readonly create: (input: OrgCreateExternalAccountInput) => Promise<CapxulResult<ExternalAccount, UpdateCodes>>;
805
- readonly list: (input: OrgListInput) => Promise<CapxulResult<List<ExternalAccount>, ListCodes$3>>;
806
- readonly retrieve: (input: {
807
- readonly organizationId: OrganizationId;
808
- readonly externalAccountId: ExternalAccountId;
809
- }) => Promise<CapxulResult<ExternalAccount, RetrieveCodes$4>>;
810
- readonly remove: (input: {
811
- readonly organizationId: OrganizationId;
812
- readonly externalAccountId: ExternalAccountId;
813
- }) => Promise<CapxulResult<void, RemoveCodes$2>>;
814
- };
815
- type OrgBalanceLedgerClient = {
816
- readonly list: (input: OrgListInput) => Promise<CapxulResult<List<BalanceLedgerEntry>, ListCodes$3>>;
817
- readonly retrieve: (input: {
818
- readonly organizationId: OrganizationId;
819
- readonly entryId: string;
820
- }) => Promise<CapxulResult<BalanceLedgerEntry, RetrieveCodes$4>>;
821
- };
822
- type OrgApiKeysClient = ApiKeysClient;
823
- type OrganizationsClient = {
824
- readonly create: (input: OrganizationsCreateInput) => Promise<CapxulResult<Organization, CreateCodes$2>>;
825
- readonly retrieve: (organizationId: OrganizationId) => Promise<CapxulResult<Organization, RetrieveCodes$4>>;
826
- readonly list: (input?: OrganizationsListInput) => Promise<CapxulResult<List<Organization>, ListCodes$3>>;
827
- readonly update: (input: OrganizationsUpdateInput) => Promise<CapxulResult<Organization, UpdateCodes>>;
828
- readonly safes: OrgSafesClient;
829
- readonly treasury: OrgTreasuryClient;
830
- readonly members: OrgMembersClient;
831
- readonly apiKeys: OrgApiKeysClient;
832
- readonly subAccounts: OrgSubAccountsClient;
833
- readonly externalAccounts: OrgExternalAccountsClient;
834
- readonly balanceLedger: OrgBalanceLedgerClient;
835
- readonly payments: OrgPaymentsClient;
836
- readonly transfers: OrgTransfersClient;
837
- readonly withdrawals: OrgWithdrawalsClient;
838
- readonly documents: OrgDocumentsClient;
839
- readonly webhookEndpoints: WebhookEndpointsClient;
840
- readonly webhookEvents: WebhookEventsClient;
841
- };
842
-
843
- /**
844
- * HTTP transport — the SDK's outbound network seam AND the canonical
845
- * lifecycle observable for the publishable-key DX path (ADR #14c).
846
- *
847
- * The transport plays two roles:
848
- *
849
- * 1. **Network seam.** `fetch(path, init?)` resolves a path against
850
- * `authBaseUrl` (absolute URLs are forwarded unchanged). The
851
- * `build-time-urls` arm exposes the URLs immediately; the
852
- * `publishable-key` arm resolves them lazily on first use through
853
- * `/v1/client/bootstrap`, with singleflight + reset-on-failure.
854
- *
855
- * 2. **Lifecycle observable.** A 5-state machine
856
- * (`idle → bootstrapping → ready → authenticated → error`) drives
857
- * the React `useCapxulStatus()` hook. The transport is a stable
858
- * singleton across renders — React subscribes to its lifecycle via
859
- * `useSyncExternalStore` and re-renders only when the state
860
- * transitions, never because the provider rebuilt.
861
- *
862
- * The transport is auth-protocol-agnostic. Path mangling like
863
- * BetterAuth's `/api/auth` prefix lives in `core/auth.ts` and stays
864
- * out of this file.
865
- */
866
-
867
- /**
868
- * Browser-side SDK config — discriminated union per ADR 5.
869
- *
870
- * Stack 2 ships the full union:
871
- * - `mode: "build-time-urls"` for explicit local/dev wiring
872
- * - `mode: "publishable-key"` for browser-safe lazy bootstrap through
873
- * `/v1/client/bootstrap`
874
- */
875
- type BrowserCapxulConfig = {
876
- readonly mode: "build-time-urls";
877
- readonly authBaseUrl: string;
878
- readonly convexUrl: string;
879
- /**
880
- * Inject a `fetch` implementation. Defaults to `globalThis.fetch`.
881
- * Named `fetchImpl` to avoid shadowing the global.
882
- */
883
- readonly fetchImpl?: typeof fetch;
884
- } | {
885
- readonly mode: "publishable-key";
886
- readonly publishableKey: string;
887
- /**
888
- * Override the absolute URL used for `/v1/client/bootstrap`.
889
- *
890
- * Defaults to `${CAPXUL_API_BASE_URL}/v1/client/bootstrap` from
891
- * `@repo/config`. Tests and alternative staging deployments set
892
- * this to point at a local mock server or a non-alpha Convex
893
- * site. A trailing slash is stripped before joining.
894
- */
895
- readonly bootstrapUrl?: string;
896
- readonly fetchImpl?: typeof fetch;
897
- };
898
- /**
899
- * Transport lifecycle state — the canonical state machine for the
900
- * publishable-key DX path per ADR #14c.
901
- *
902
- * Transitions:
903
- * - `idle → bootstrapping` on first network call
904
- * - `bootstrapping → ready` on successful `/v1/client/bootstrap`
905
- * - `bootstrapping → error` on bootstrap failure
906
- * - `error → bootstrapping` when a subsequent caller retries (reset-on-failure)
907
- * - `ready → authenticated` via `markAuthenticated()` after verifyOtp
908
- * - `authenticated → ready` via `signOut()` / `clearAuth()`
909
- *
910
- * The `build-time-urls` arm starts in `ready` immediately because no
911
- * bootstrap is required.
912
- */
913
- type TransportState = {
914
- readonly status: "idle";
915
- } | {
916
- readonly status: "bootstrapping";
917
- } | {
918
- readonly status: "ready";
919
- readonly runtime: TransportRuntime;
920
- } | {
921
- readonly status: "authenticated";
922
- readonly runtime: TransportRuntime;
923
- } | {
924
- readonly status: "error";
925
- readonly error: CapxulError$1;
926
- };
927
- type TransportRuntime = {
928
- readonly authBaseUrl: string;
929
- readonly convexUrl: string;
930
- };
931
- /**
932
- * HTTP transport surface consumed by every domain client (auth, me,
933
- * payments, …) once Stack 1 task 1.5 routes them through here.
934
- *
935
- * - `fetch(path, init?)` resolves a relative path against
936
- * `authBaseUrl` (absolute URLs are forwarded unchanged).
937
- * - `authBaseUrl` and `convexUrl` are exposed as resolved values so
938
- * downstream consumers (e.g. Convex client construction) can read
939
- * them directly. The publishable-key arm populates these lazily
940
- * after the first bootstrap resolution; before that they are empty
941
- * strings.
942
- * - `getState()` / `subscribe()` are the React-friendly observable
943
- * surface for `useCapxulStatus()`. Use `useSyncExternalStore` on the
944
- * React side.
945
- * - `markAuthenticated()` / `clearAuth()` are the post-verifyOtp /
946
- * post-signOut transition methods (ADR #14c contract item 3 — the
947
- * provider does NOT setState; it lets the transport's state machine
948
- * drive React subscriptions).
949
- */
950
- type HttpTransport = {
951
- readonly fetch: (path: string, init?: RequestInit) => Promise<Response>;
952
- readonly ensureRuntime: () => Promise<TransportRuntime>;
953
- readonly authBaseUrl: string;
954
- readonly convexUrl: string;
955
- readonly getState: () => TransportState;
956
- readonly subscribe: (listener: () => void) => () => void;
957
- readonly getDataClient: () => CapxulDataClient | null;
958
- readonly markAuthenticated: (opts: {
959
- readonly dataClient?: CapxulDataClient;
960
- }) => void;
961
- readonly clearAuth: () => void;
962
- };
963
- /**
964
- * Build an `HttpTransport` from a `BrowserCapxulConfig`.
965
- *
966
- * Throws `CapxulError<"INVALID_INPUT">` with
967
- * `details.source === "sdk-config"` when local transport config is
968
- * malformed. Backend bootstrap failures also throw `CapxulError`, but
969
- * carry `details.source === "backend-bootstrap"` so consumers can
970
- * distinguish setup mistakes from server-side bootstrap refusals.
971
- */
972
- declare function makeHttpTransport(config: BrowserCapxulConfig): HttpTransport;
973
-
974
- /**
975
- * Sub-accounts domain — the top-level `capxul.subAccounts.*` surface.
976
- *
977
- * Per sdk-surface.md §1a, `sub_account` is a named partition under an
978
- * account or organization that aggregates balance across custody
979
- * sources (stablecoin pool + virtual accounts + cards). `create` and
980
- * `list` live on the owner's nested namespace (Pattern A —
981
- * `accounts.subAccounts.create(...)` or
982
- * `organizations.subAccounts.create(...)`), so only `retrieve` and
983
- * `remove` live at the top level.
984
- *
985
- * Wired in PR-2a of the funds-v1 balance-closure stack: the backend
986
- * always returns truthful `balance: Money` per canon §sub_account
987
- * (PR-1 made `toCanonShape` populate it from `computeSubAccountBalance`).
988
- * The SDK brands the wire shape and passes the balance through as-is.
989
- * NO zero-balance fallback exists at the SDK layer — if the backend
990
- * ever omits `balance`, that is a bug to surface, not paper over.
991
- */
992
-
993
- type RetrieveCodes$3 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "PROVIDER_ERROR";
994
- type RemoveCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "INVALID_INPUT" | "PROVIDER_ERROR";
995
- type SubAccountsClient = {
996
- readonly retrieve: (subAccountId: SubAccountId) => Promise<CapxulResult<SubAccount, RetrieveCodes$3>>;
997
- readonly remove: (subAccountId: SubAccountId) => Promise<CapxulResult<SubAccount, RemoveCodes$1>>;
998
- };
999
-
1000
- /**
1001
- * **NON-CANONICAL surface.**
1002
- *
1003
- * `capxul.tokenTransfers.*` exposes the indexer's raw on-chain ERC-20
1004
- * transfer rows directly to consumers, backed by
1005
- * `packages/backend/convex/tokenTransfers/queries.ts`. Authorized at
1006
- * `slice/02-story2-balance` per the conductor's Option-A verdict —
1007
- * the canonical SDK `transfers.*` namespace assumes a cross-custody
1008
- * internal-move shape (`Transfer = { source, destination, fx,
1009
- * operation, ... }`) that has no canon-aligned backing query yet.
1010
- * Surfacing the on-chain feed under a separate, clearly-marked
1011
- * non-canonical namespace lets the Ink CLI's activity dashboard
1012
- * progress without forcing canon synthesis.
1013
- *
1014
- * **NOT in `packages/api-contract`.** Do NOT use this surface as the
1015
- * basis for new canon. When `transfers.*` shape alignment lands
1016
- * (post-alpha.4 follow-up issue), the canonical `transfers.*` will
1017
- * subsume this and `tokenTransfers.*` becomes a deprecation alias.
1018
- *
1019
- * Stub families that REMAIN deferred at this slice
1020
- * (per `[DEFERRED-CANON]` markers in
1021
- * `.claude/worktrees/post-alpha-wire2/.progress.txt`):
1022
- * - `transfers.{create,retrieve,list,confirm,cancel}` — canon shape mismatch
1023
- * - `accounts.balanceLedger.{list,retrieve}` — no canon backing query
1024
- * - `organizations.balanceLedger.*` — no canon backing query
1025
- * - `organizations.transfers.*` — canon shape mismatch
1026
- * - `organizations.treasury.retrieve` — backing query has different shape
1027
- */
1028
-
1029
- /**
1030
- * Branded id for an on-chain `tokenTransfer` row. Backed by the
1031
- * Convex document id; the brand prevents accidental swaps with other
1032
- * SDK ids without leaking the document-id constraint into call sites.
1033
- *
1034
- * Returned in `TokenTransfer.id` for clients that want a stable
1035
- * back-reference; the canonical lookup key is the
1036
- * `(txHash, logIndex)` composite used by `retrieve`.
1037
- */
1038
- type TokenTransferId = string & {
1039
- readonly __capxulTokenTransferIdBrand: "TokenTransferId";
1040
- };
1041
- declare const toTokenTransferId: (raw: string) => TokenTransferId;
1042
- /**
1043
- * Raw on-chain ERC-20 transfer row. Shape mirrors
1044
- * `tokenTransfers/queries.ts` `list` / `getByTxLogIndex` output. The
1045
- * primitive fields (`txHash`, `tokenAddress`, etc.) match
1046
- * `@repo/api-contract` conventions — `string` for hashes/addresses,
1047
- * `number` for block + chain ids — so consumers don't need to import
1048
- * a brand surface that isn't in the SDK's published deps.
1049
- */
1050
- type TokenTransfer = {
1051
- readonly id: TokenTransferId;
1052
- readonly object: "token_transfer";
1053
- readonly direction: "in" | "out";
1054
- /** Token-units string ("123456" not "1.23456"). Decimals carried in `tokenDecimals`. */
1055
- readonly amount: string;
1056
- readonly tokenSymbol: string;
1057
- readonly tokenDecimals: number;
1058
- readonly tokenAddress: string;
1059
- readonly counterpartyName: string | null;
1060
- readonly counterpartyAddress: string;
1061
- readonly description: string;
1062
- /** Block timestamp in epoch milliseconds. */
1063
- readonly createdAt: number;
1064
- readonly txHash: string;
1065
- readonly blockNumber: number;
1066
- readonly chainId: number;
1067
- };
1068
- type TokenTransfersListPage = {
1069
- readonly object: "list";
1070
- readonly data: readonly TokenTransfer[];
1071
- readonly page: {
1072
- readonly hasMore: boolean;
1073
- /** Block-timestamp cursor (epoch ms) for the next page; null when exhausted. */
1074
- readonly nextCursor: number | null;
1075
- };
1076
- /** Caller's display currency. The backend echoes it so renderers don't need a second round-trip. */
1077
- readonly displayCurrency: string;
1078
- };
1079
- type TokenTransfersListInput = {
1080
- readonly limit?: number;
1081
- /** Block-timestamp cursor (epoch ms) returned in the previous page's `page.nextCursor`. */
1082
- readonly cursor?: number;
1083
- readonly direction?: "in" | "out";
1084
- };
1085
- type TokenTransfersRetrieveInput = {
1086
- readonly txHash: string;
1087
- readonly logIndex: number;
1088
- /** Optional chain filter. When omitted, the first index hit wins (single-chain default). */
1089
- readonly chainId?: number;
1090
- };
1091
- type ListCodes$2 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
1092
- type RetrieveCodes$2 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
1093
- type TokenTransfersClient = {
1094
- readonly list: (input?: TokenTransfersListInput) => Promise<CapxulResult<TokenTransfersListPage, ListCodes$2>>;
1095
- readonly retrieve: (input: TokenTransfersRetrieveInput) => Promise<CapxulResult<TokenTransfer, RetrieveCodes$2>>;
1096
- };
1097
-
1098
- /**
1099
- * Virtual accounts domain — International Bank Account Number (IBAN)-
1100
- * bearing receive rails per sdk-surface.md §1a + §4.51.
1101
- *
1102
- * Uses Pattern C (ownerKind in body): the caller specifies
1103
- * `owner = { kind: "account" | "sub_account" | "organization", id: ... }`
1104
- * in the create payload rather than nesting the route under the owner.
1105
- */
1106
-
1107
- type VirtualAccountsCreateInput = CreateVirtualAccountRequest;
1108
- type VirtualAccountsListInput = {
1109
- readonly limit?: number;
1110
- readonly cursor?: string;
1111
- readonly ownerKind?: "account" | "sub_account" | "organization";
1112
- readonly ownerId?: string;
1113
- };
1114
- type CreateCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "KYC_REQUIRED" | "PROVIDER_UNAVAILABLE" | "RATE_LIMITED" | "NETWORK_ERROR";
1115
- type RetrieveCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
1116
- type ListCodes$1 = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
1117
- type RemoveCodes = RetrieveCodes$1;
1118
- type VirtualAccountsClient = {
1119
- readonly create: (input: VirtualAccountsCreateInput) => Promise<CapxulResult<VirtualAccount, CreateCodes$1>>;
1120
- readonly retrieve: (virtualAccountId: VirtualAccountId) => Promise<CapxulResult<VirtualAccount, RetrieveCodes$1>>;
1121
- readonly list: (input?: VirtualAccountsListInput) => Promise<CapxulResult<List<VirtualAccount>, ListCodes$1>>;
1122
- readonly remove: (virtualAccountId: VirtualAccountId) => Promise<CapxulResult<void, RemoveCodes>>;
1123
- };
1124
-
1125
- /**
1126
- * Virtual cards domain — issued Visa / Mastercard spending sub-account
1127
- * balance per sdk-surface.md §1a + §4.51.
1128
- *
1129
- * Uses Pattern C (ownerKind in body).
1130
- */
1131
-
1132
- type VirtualCardsCreateInput = CreateVirtualCardRequest;
1133
- type VirtualCardsListInput = {
1134
- readonly limit?: number;
1135
- readonly cursor?: string;
1136
- readonly ownerKind?: "account" | "sub_account" | "organization";
1137
- readonly ownerId?: string;
1138
- };
1139
- type CreateCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT" | "KYC_REQUIRED" | "PROVIDER_UNAVAILABLE" | "RATE_LIMITED" | "NETWORK_ERROR";
1140
- type RetrieveCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND";
1141
- type ListCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "INVALID_INPUT";
1142
- type MutateCodes = "NOT_AUTHENTICATED" | "PERMISSION_DENIED" | "NOT_FOUND" | "PROVIDER_UNAVAILABLE";
1143
- type VirtualCardsClient = {
1144
- readonly create: (input: VirtualCardsCreateInput) => Promise<CapxulResult<VirtualCard, CreateCodes>>;
1145
- readonly retrieve: (virtualCardId: VirtualCardId) => Promise<CapxulResult<VirtualCard, RetrieveCodes>>;
1146
- readonly list: (input?: VirtualCardsListInput) => Promise<CapxulResult<List<VirtualCard>, ListCodes>>;
1147
- readonly freeze: (virtualCardId: VirtualCardId) => Promise<CapxulResult<VirtualCard, MutateCodes>>;
1148
- readonly unfreeze: (virtualCardId: VirtualCardId) => Promise<CapxulResult<VirtualCard, MutateCodes>>;
1149
- readonly cancel: (virtualCardId: VirtualCardId) => Promise<CapxulResult<VirtualCard, MutateCodes>>;
1150
- };
1151
-
1152
- /**
1153
- * Unified error type used across the entire stack: backend, SDK, and frontend.
1154
- * One class, one set of codes, one language.
1155
- *
1156
- * Backend throws CapxulError → withErrorBoundary serializes to ConvexError →
1157
- * SDK deserializes back to CapxulError → frontend routes on err.code.
1158
- */
1159
- 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" | "INDEXER_DELIVERY_TIMEOUT" | "UNKNOWN";
1160
- declare class CapxulError extends Error {
1161
- readonly code: CapxulErrorCode;
1162
- readonly details?: Record<string, unknown>;
1163
- readonly correlationId?: string;
1164
- readonly layer?: string;
1165
- constructor(code: CapxulErrorCode, message: string, options?: {
1166
- cause?: unknown;
1167
- details?: Record<string, unknown>;
1168
- correlationId?: string;
1169
- layer?: string;
1170
- });
1171
- }
1172
-
1173
- type AuthBootstrapFlowError = CapxulError$1 | CapxulError;
1174
- type AuthBootstrapFlowContext = {
1175
- readonly email: Email | null;
1176
- readonly code: string | null;
1177
- readonly username: Username | null;
1178
- readonly bootstrapToken: AuthBootstrapToken | null;
1179
- readonly bootstrapReason: AuthBootstrapReason | null;
1180
- readonly session: Session | null;
1181
- readonly account: Account | null;
1182
- readonly safe: Safe | null;
1183
- readonly error: AuthBootstrapFlowError | null;
1184
- };
1185
- type AuthBootstrapFlowEvent = {
1186
- readonly type: "ENTER_EMAIL";
1187
- readonly email: Email;
1188
- } | {
1189
- readonly type: "REQUEST_OTP";
1190
- } | {
1191
- readonly type: "ENTER_OTP";
1192
- readonly code: string;
1193
- } | {
1194
- readonly type: "VERIFY_OTP";
1195
- } | {
1196
- readonly type: "ENTER_USERNAME";
1197
- readonly username: Username;
1198
- } | {
1199
- readonly type: "COMPLETE_BOOTSTRAP";
1200
- } | {
1201
- readonly type: "BACK";
1202
- } | {
1203
- readonly type: "RESET";
1204
- } | {
1205
- readonly type: "SIGN_OUT";
1206
- };
1207
- declare function createAuthBootstrapFlowMachine(client: CapxulClient): xstate.StateMachine<AuthBootstrapFlowContext, {
1208
- readonly type: "ENTER_EMAIL";
1209
- readonly email: Email;
1210
- } | {
1211
- readonly type: "REQUEST_OTP";
1212
- } | {
1213
- readonly type: "ENTER_OTP";
1214
- readonly code: string;
1215
- } | {
1216
- readonly type: "VERIFY_OTP";
1217
- } | {
1218
- readonly type: "ENTER_USERNAME";
1219
- readonly username: Username;
1220
- } | {
1221
- readonly type: "COMPLETE_BOOTSTRAP";
1222
- } | {
1223
- readonly type: "BACK";
1224
- } | {
1225
- readonly type: "RESET";
1226
- } | {
1227
- readonly type: "SIGN_OUT";
1228
- }, {
1229
- [x: string]: xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, void, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<void, {
1230
- email: Email;
1231
- }, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<VerifyOtpResult, {
1232
- email: Email;
1233
- code: string;
1234
- }, xstate.EventObject>> | xstate.ActorRefFromLogic<xstate.PromiseActorLogic<CompleteBootstrapResult, {
1235
- bootstrapToken: AuthBootstrapToken;
1236
- username: Username;
1237
- }, xstate.EventObject>> | undefined;
1238
- }, {
1239
- src: "sendOtp";
1240
- logic: xstate.PromiseActorLogic<void, {
1241
- email: Email;
1242
- }, xstate.EventObject>;
1243
- id: string | undefined;
1244
- } | {
1245
- src: "verifyOtp";
1246
- logic: xstate.PromiseActorLogic<VerifyOtpResult, {
1247
- email: Email;
1248
- code: string;
1249
- }, xstate.EventObject>;
1250
- id: string | undefined;
1251
- } | {
1252
- src: "signOut";
1253
- logic: xstate.PromiseActorLogic<void, void, xstate.EventObject>;
1254
- id: string | undefined;
1255
- } | {
1256
- src: "completeBootstrap";
1257
- logic: xstate.PromiseActorLogic<CompleteBootstrapResult, {
1258
- bootstrapToken: AuthBootstrapToken;
1259
- username: Username;
1260
- }, xstate.EventObject>;
1261
- id: string | undefined;
1262
- }, {
1263
- type: "trackOtpRequested";
1264
- params: unknown;
1265
- } | {
1266
- type: "trackTimeoutFailed";
1267
- params: unknown;
1268
- } | {
1269
- type: "trackVerified";
1270
- params: unknown;
1271
- } | {
1272
- type: "identifyAndTrack";
1273
- params: unknown;
1274
- } | {
1275
- type: "trackSignedOut";
1276
- params: unknown;
1277
- } | {
1278
- type: "trackFailed";
1279
- params: unknown;
1280
- } | {
1281
- type: "trackBootstrapRequired";
1282
- params: unknown;
1283
- }, never, never, "email" | "authenticated" | "error" | "bootstrap_required" | "sending_otp" | "otp_requested" | "signing_out" | "verifying_otp" | "completing_bootstrap", string, xstate.NonReducibleUnknown, xstate.NonReducibleUnknown, xstate.EventObject, xstate.MetaObject, {
1284
- id: "authBootstrap";
1285
- states: {
1286
- readonly email: {};
1287
- readonly sending_otp: {};
1288
- readonly otp_requested: {};
1289
- readonly verifying_otp: {};
1290
- readonly bootstrap_required: {};
1291
- readonly completing_bootstrap: {};
1292
- readonly authenticated: {};
1293
- readonly signing_out: {};
1294
- readonly error: {};
1295
- };
1296
- }>;
1297
-
1298
- /**
1299
- * Root `@capxul/sdk` client factory.
1300
- *
1301
- * Canonical construction per sdk-surface.md §3a:
1302
- *
1303
- * ```ts
1304
- * import { createCapxulClient, createLocalSigner } from "@capxul/sdk";
1305
- *
1306
- * const capxul = createCapxulClient({
1307
- * apiKey: process.env.CAPXUL_API_KEY!,
1308
- * signer: createLocalSigner(process.env.CAPXUL_PRIVATE_KEY as `0x${string}`),
1309
- * });
1310
- * ```
1311
- *
1312
- * Three auth modes are mutually exclusive:
1313
- * - `apiKey` — server-to-server partner flows (`cap_live_` / `cap_test_`)
1314
- * - `publishableKey` — installed-app flows with OTP-established human
1315
- * sessions (`cap_pk_live_` / `cap_pk_test_`); sessions persist
1316
- * via the SDK's auth adapter (file / cookie depending on runtime)
1317
- * - neither — unauthenticated only; useful for `auth.sendOtp` +
1318
- * `auth.verifyOtp` bootstrap before a session exists
1319
- *
1320
- * The `signer` (viem `Account`) is required for methods that submit
1321
- * on-chain UserOperations (payments, withdrawals, transfers) per
1322
- * CANON.md §4.28.
1323
- */
1324
-
1325
- type CapxulSigningConfig = {
1326
- /** EVM chain ID (currently Base Sepolia). */
1327
- readonly chainId: number;
1328
- /** JSON-RPC URL for UserOperation submission. */
1329
- readonly rpcUrl: string;
1330
- /** Alchemy gas policy ID for UserOperation sponsorship. */
1331
- readonly gasPolicyId: string;
1332
- };
1333
- type CapxulAuthConfig = {
1334
- /**
1335
- * Convex `.site` URL that hosts the BetterAuth endpoints.
1336
- *
1337
- * Optional when the client is configured with a publishable key and
1338
- * lazy bootstrap resolves the runtime URLs instead.
1339
- */
1340
- readonly baseUrl?: string;
1341
- /** Optional explicit Convex token endpoint. Defaults to `${baseUrl}/api/auth/convex/token`. */
1342
- readonly convexTokenUrl?: string;
1343
- /** Scenario/browser-local session store shared by auth + onboarding hooks. */
1344
- readonly sessionStore?: AuthSessionStore;
1345
- };
1346
- type CapxulConfig = {
1347
- /** Server-to-server partner key. Mutually exclusive with `publishableKey`. */
1348
- readonly apiKey?: string;
1349
- /**
1350
- * Installed-app publishable key. Pairs with an OTP-established human
1351
- * session persisted by the SDK's auth adapter.
1352
- */
1353
- readonly publishableKey?: string;
1354
- /**
1355
- * viem `Account` used to sign UserOperations for on-chain methods
1356
- * (payments, withdrawals, transfers) per CANON.md §4.28.
1357
- */
1358
- readonly signer?: Account$1;
1359
- /**
1360
- * @internal
1361
- *
1362
- * Test-only override seam for injecting an authenticated Convex data client.
1363
- * The SDK now owns runtime construction of the data client; this field is
1364
- * reserved for tests and the React provider's singleton lifecycle.
1365
- */
1366
- readonly _data?: CapxulDataClient;
1367
- /**
1368
- * Chain + bundler configuration for on-chain submission.
1369
- *
1370
- * Required alongside `signer` for runtime `payments.create`.
1371
- */
1372
- readonly signing?: CapxulSigningConfig;
1373
- /** Human OTP auth runtime configuration. */
1374
- readonly auth?: CapxulAuthConfig;
1375
- /**
1376
- * Override the API base URL. Defaults to `https://api.capxul.com`
1377
- * in production builds; point at `http://localhost:<port>/v1` for
1378
- * local development against Convex's httpAction router.
1379
- */
1380
- readonly baseUrl?: string;
1381
- /**
1382
- * Inject a `fetch` implementation. Defaults to global `fetch`. Used
1383
- * for testing or to plug in `undici` / `node-fetch` in older Node
1384
- * environments.
1385
- */
1386
- readonly fetch?: typeof fetch;
1387
- /**
1388
- * @internal
1389
- *
1390
- * Inject a pre-built `HttpTransport`. The `@capxul/sdk-react`
1391
- * `CapxulProvider` uses this in the lazy-DX path (ADR #14c) so the
1392
- * provider's externally-built transport is the SAME singleton used by
1393
- * the auth client's bootstrap calls. Without injection, the SDK would
1394
- * build a second transport internally — the `useCapxulStatus()` hook
1395
- * would observe a different state machine than the one auth methods
1396
- * actually drive.
1397
- *
1398
- * Underscored to mark it as an internal SDK seam, not a partner-facing
1399
- * config field. Do not document publicly.
1400
- */
1401
- readonly _transport?: HttpTransport;
1402
- };
1403
- /**
1404
- * Per-call factories for the three Stack-1 XState v5 flow machines.
1405
- *
1406
- * Each factory returns a fresh machine instance bound to this
1407
- * `CapxulClient`. The consumer is responsible for creating a single
1408
- * actor (e.g. via `createActor` / React's `useMemo` + `useActor`) and
1409
- * keeping it alive for the duration of the flow. Calling a factory
1410
- * twice yields two independent machines — useful for parallel
1411
- * onboarding sessions in tests, never the desired pattern in app code.
1412
- *
1413
- * The return types are intentionally erased to `AnyStateMachine` to
1414
- * keep this surface stable across XState v5 type-parameter changes;
1415
- * downstream consumers (`@capxul/sdk-react` hooks, the e2e harness's
1416
- * `xstateFlowSequence` primitive) re-import the precise types from
1417
- * `./flows/*` when they need them.
1418
- */
1419
- type CapxulFlowFactories = {
1420
- readonly auth: () => AnyStateMachine;
1421
- readonly authBootstrap: () => ReturnType<typeof createAuthBootstrapFlowMachine>;
1422
- readonly onboarding: () => AnyStateMachine;
1423
- readonly provisioning: () => AnyStateMachine;
1424
- };
1425
- type CapxulClient = {
1426
- /**
1427
- * @internal
1428
- *
1429
- * Per-client UUID minted at construction. Used as a TanStack Query
1430
- * cache-key prefix to isolate per-client cache when multiple
1431
- * `CapxulClient` instances are mounted in the same React tree.
1432
- *
1433
- * MUST NOT be passed to `identify()`, `track()`, or any analytics
1434
- * surface — PostHog has no way to distinguish "namespace UUID" from
1435
- * "person UUID" and conflating the two creates fake users in
1436
- * analytics. Treat as opaque cache implementation detail.
1437
- *
1438
- * Stable for the lifetime of the client; new on every
1439
- * `createCapxulClient()` call. See Codex P1 finding on PR #406.
1440
- */
1441
- readonly id: string;
1442
- readonly auth: AuthClient;
1443
- readonly me: MeClient;
1444
- readonly accounts: AccountsClient;
1445
- readonly organizations: OrganizationsClient;
1446
- readonly payments: PaymentsClient;
1447
- readonly transfers: TransfersClient;
1448
- /**
1449
- * **NON-CANONICAL.** On-chain ERC-20 transfer feed (raw indexer
1450
- * rows). NOT part of `packages/api-contract`. Slated for
1451
- * deprecation when canonical `transfers.*` shape alignment lands.
1452
- * See `core/token-transfers.ts` for the doc-comment contract.
1453
- */
1454
- readonly tokenTransfers: TokenTransfersClient;
1455
- readonly withdrawals: WithdrawalsClient;
1456
- readonly documents: DocumentsClient;
1457
- readonly subAccounts: SubAccountsClient;
1458
- readonly virtualAccounts: VirtualAccountsClient;
1459
- readonly virtualCards: VirtualCardsClient;
1460
- readonly externalAccounts: ExternalAccountsClient;
1461
- readonly operations: OperationsClient;
1462
- readonly webhookEndpoints: WebhookEndpointsClient;
1463
- readonly webhookEvents: WebhookEventsClient;
1464
- readonly apiKeys: ApiKeysClient;
1465
- readonly flows: CapxulFlowFactories;
1466
- };
1467
- /**
1468
- * Construct a Capxul client. Every method stub in Slice C throws
1469
- * `NOT_IMPLEMENTED` per CANON.md §2 (types-first scaffold). Slice F.2
1470
- * wires the restart `payments` + `operations` runtime path through an
1471
- * injected authenticated Convex client; the broader `/v1/*` surface is
1472
- * still pending.
1473
- *
1474
- * Two-pass construction: the per-domain clients (`auth`, `me`, …) are
1475
- * built first, then `flows` is assigned with factories that close over
1476
- * the fully-built `client` so the spawned XState machines can call
1477
- * back into `client.auth.sendOtp`, `client.accounts.provisionPersonal`,
1478
- * etc. The intermediate `clientWithoutFlows` value is typed without
1479
- * `flows`; `Object.assign` mutates a single `flows` field on it before
1480
- * the returned `CapxulClient` cast — minimal and contained.
1481
- */
1482
- declare function createCapxulClient(config?: CapxulConfig): CapxulClient;
1483
-
1484
- export { type WithdrawalsClient as $, type AccountProvisionPersonalInput as A, type BrowserCapxulConfig as B, CapxulError as C, type DocumentsClient as D, type ExternalAccountsClient as E, type SubAccountsClient as F, type TokenTransferId as G, type HttpTransport as H, type TokenTransfersClient as I, type TokenTransfersListInput as J, type TokenTransfersListPage as K, type LocalPrivateKeySignerProvider as L, type MeClient as M, type TokenTransfersRetrieveInput as N, type OperationsClient as O, type PaymentsClient as P, type TransfersClient as Q, type TransportRuntime as R, type Session as S, type TokenTransfer as T, type TransportState as U, type VerifyOtpResult as V, type VirtualAccountsClient as W, type VirtualCardsClient as X, type WebhookEndpointCreateResult as Y, type WebhookEndpointsClient as Z, type WebhookEventsClient as _, type CapxulClient as a, createAuthBootstrapFlowMachine as a0, createCapxulClient as a1, makeHttpTransport as a2, toTokenTransferId as a3, type CapxulConfig as b, type CompleteBootstrapInput as c, type CompleteBootstrapResult as d, type AccountsClient as e, type ApiKeyCreateResult as f, type ApiKeysClient as g, type AuthBootstrapFlowContext as h, type AuthBootstrapFlowError as i, type AuthBootstrapFlowEvent as j, type AuthBootstrapReason as k, type AuthBootstrapToken as l, type AuthClient as m, type AuthSessionStore as n, type CapxulAuthConfig as o, type CapxulDataClient as p, type CapxulFlowFactories as q, type CapxulSigningConfig as r, type OrgDocumentsClient as s, type OrgMembersClient as t, type OrgPaymentsClient as u, type OrgSafesClient as v, type OrgTransfersClient as w, type OrgTreasuryClient as x, type OrgWithdrawalsClient as y, type OrganizationsClient as z };