@capxul/sdk-react 3.1.0 → 4.0.0

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.
@@ -1,6 +1,6 @@
1
1
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
2
2
  import { QueryClient, QueryClientProvider, useQueryClient } from "@tanstack/react-query";
3
- import { createCapxulClient, isCapxulError, resolveIdentityDestination, toCountryCode } from "@capxul/sdk";
3
+ import { CapxulError, createCapxulClient, isCapxulError, resolveIdentityDestination, toCountryCode } from "@capxul/sdk";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/internal/capxul-bootstrap-context.tsx
6
6
  const CapxulBootstrapContext = createContext(null);
@@ -40,11 +40,11 @@ function useCapxulClientOrNull() {
40
40
  const capxulKeys = {
41
41
  root: ["capxul"],
42
42
  profile: ["capxul", "profile"],
43
- usernameAvailability: (username) => [
43
+ handleAvailability: (handle) => [
44
44
  "capxul",
45
45
  "profile",
46
- "username-availability",
47
- username
46
+ "handle-availability",
47
+ handle
48
48
  ],
49
49
  account: ["capxul", "account"],
50
50
  provisioning: ["capxul", "provisioning"],
@@ -179,6 +179,22 @@ async function guarded(runtime, verb, options, run) {
179
179
  };
180
180
  }
181
181
  }
182
+ function organizationFailure(reason, state) {
183
+ const stateFailure = state.phase === "faulted" ? state.failure : state.phase === "authenticated" && state.account.at === "failed" ? state.account.failure : state.phase === "authenticated" && state.account.at === "claimed" && state.account.org?.at === "failed" ? state.account.org.failure : void 0;
184
+ if (stateFailure?.code === reason) return {
185
+ ok: false,
186
+ reason,
187
+ error: stateFailure.error ?? new CapxulError(stateFailure.code === "WORK_DIED" ? "UNKNOWN" : stateFailure.code, stateFailure.message, {
188
+ ...stateFailure.mode === void 0 ? {} : { details: { failure_mode: stateFailure.mode } },
189
+ layer: "identity"
190
+ })
191
+ };
192
+ return {
193
+ ok: false,
194
+ reason,
195
+ error: new CapxulError(reason === "WORK_DIED" ? "UNKNOWN" : reason, reason === "INVALID_INPUT" ? "Organization details are invalid." : "Organization creation failed.", { layer: "identity" })
196
+ };
197
+ }
182
198
  const ORGANIZATION_HANDLE = /^[a-z0-9-]{3,32}$/;
183
199
  function normalizeOrganization(organization) {
184
200
  const name = typeof organization.name === "string" ? organization.name.trim() : "";
@@ -243,7 +259,7 @@ function createAuth(client, clearAuthenticatedQueries) {
243
259
  };
244
260
  const current = runtime.snapshot();
245
261
  if (current.phase !== "authenticated" || !current.profileComplete) {
246
- const completed = await completeProfile(submission.profileDetails, invocation);
262
+ const completed = await runtime.completeProfile(submission.profileDetails, invocation);
247
263
  if (!completed.ok) return completed;
248
264
  }
249
265
  const refreshed = await read(invocation);
@@ -314,7 +330,10 @@ function createAuth(client, clearAuthenticatedQueries) {
314
330
  }),
315
331
  completePersonal: (profile, options) => guarded(runtime, "completePersonal", options, async (invocation) => {
316
332
  const completed = await completeProfile(profile, invocation);
317
- if (!completed.ok) return completed;
333
+ if (!completed.ok) return {
334
+ ok: false,
335
+ reason: completed.reason
336
+ };
318
337
  const refreshed = await read(invocation);
319
338
  if (!refreshed.ok) return refreshed;
320
339
  return ensureAccount(invocation);
@@ -356,6 +375,14 @@ function createAuth(client, clearAuthenticatedQueries) {
356
375
  ok: false,
357
376
  reason: "UNKNOWN"
358
377
  };
378
+ }).then((result) => {
379
+ if (result.ok) return result;
380
+ if ("error" in result && result.error instanceof CapxulError) return {
381
+ ok: false,
382
+ reason: result.reason,
383
+ error: result.error
384
+ };
385
+ return organizationFailure(result.reason, runtime.snapshot());
359
386
  }),
360
387
  retry: (options) => guarded(runtime, "retry", options, async (invocation) => {
361
388
  const state = runtime.snapshot();
@@ -365,7 +392,10 @@ function createAuth(client, clearAuthenticatedQueries) {
365
392
  }),
366
393
  resumeSubmittedOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
367
394
  const prepared = await prepareOrganization(submission, invocation);
368
- return prepared.ok ? { ok: true } : prepared;
395
+ return prepared.ok ? { ok: true } : {
396
+ ok: false,
397
+ reason: prepared.reason
398
+ };
369
399
  })
370
400
  };
371
401
  }
@@ -771,10 +801,10 @@ function organizationForm(props, state, auth, submitted) {
771
801
  submit: (organization, options) => {
772
802
  if (submitted !== null) return auth.createOrganization(submitted, options);
773
803
  const normalized = normalizeOrganization(organization);
774
- if (normalized === null) return Promise.resolve({
775
- ok: false,
776
- reason: "INVALID_INPUT"
777
- });
804
+ if (normalized === null) return auth.createOrganization({
805
+ profileDetails,
806
+ organization
807
+ }, options);
778
808
  const next = {
779
809
  profileDetails,
780
810
  organization: normalized
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from "react";
2
- import { CapxulClient, CapxulErrorCode, IdentityDestination, IdentityEvent, IdentityProfileDetails, IdentityState, IdentityTransition, OrgLane, Readiness, StateLabel } from "@capxul/sdk";
2
+ import { CapxulClient, CapxulError, CapxulErrorCode, IdentityDestination, IdentityEvent, IdentityProfileDetails, IdentityState, IdentityTransition, OrgLane, Readiness, StateLabel } from "@capxul/sdk";
3
3
  //#region src/identity.d.ts
4
4
  type Destination = IdentityDestination;
5
5
  interface InvocationOptions {
@@ -34,6 +34,9 @@ type FacadeFailure = {
34
34
  readonly ok: false;
35
35
  readonly reason: CapxulErrorCode;
36
36
  };
37
+ type CreateOrganizationFailure = FacadeFailure & {
38
+ readonly error: CapxulError;
39
+ };
37
40
  type EmptyResult = {
38
41
  readonly ok: true;
39
42
  } | FacadeFailure;
@@ -51,7 +54,7 @@ interface CapxulAuth {
51
54
  readonly createOrganization: (submission: CreateOrganizationSubmission, options?: InvocationOptions) => Promise<{
52
55
  readonly ok: true;
53
56
  readonly orgId: string;
54
- } | FacadeFailure>;
57
+ } | CreateOrganizationFailure>;
55
58
  readonly completePersonal: (profileDetails: ProfileDetails, options?: InvocationOptions) => Promise<EmptyResult>;
56
59
  readonly retry: (options?: InvocationOptions) => Promise<EmptyResult>;
57
60
  }
@@ -201,4 +204,4 @@ interface OnboardingControllerProps {
201
204
  }
202
205
  declare function CapxulOnboardingController(props: OnboardingControllerProps): ReactNode;
203
206
  //#endregion
204
- export { useCapxulAuth as A, CreateOrganizationSubmission as C, ProfileDetails as D, OrganizationDetails as E, useCapxulIdentity as M, useCapxulSend as N, SendResult as O, useCapxulTransitions as P, CapxulSend as S, InvocationOptions as T, ReadyDestination as _, AuthenticationSlots as a, Slot as b, ControllerAction as c, OnboardingControllerProps as d, OrgFailure as f, ProfileSlotProps as g, PendingAuthState as h, AuthenticatedState as i, useCapxulDestination as j, entered as k, FaultedState as l, OtpPendingState as m, AccountProgress as n, CapxulAuthenticationController as o, OrgProgress as p, ActionResult as r, CapxulOnboardingController as s, AccountFailure as t, NavigationAction as u, RetryAction as v, Destination as w, CapxulAuth as x, SignedOutState as y };
207
+ export { entered as A, CreateOrganizationFailure as C, OrganizationDetails as D, InvocationOptions as E, useCapxulTransitions as F, useCapxulDestination as M, useCapxulIdentity as N, ProfileDetails as O, useCapxulSend as P, CapxulSend as S, Destination as T, ReadyDestination as _, AuthenticationSlots as a, Slot as b, ControllerAction as c, OnboardingControllerProps as d, OrgFailure as f, ProfileSlotProps as g, PendingAuthState as h, AuthenticatedState as i, useCapxulAuth as j, SendResult as k, FaultedState as l, OtpPendingState as m, AccountProgress as n, CapxulAuthenticationController as o, OrgProgress as p, ActionResult as r, CapxulOnboardingController as s, AccountFailure as t, NavigationAction as u, RetryAction as v, CreateOrganizationSubmission as w, CapxulAuth as x, SignedOutState as y };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as useCapxulAuth, C as CreateOrganizationSubmission, D as ProfileDetails, E as OrganizationDetails, M as useCapxulIdentity, N as useCapxulSend, O as SendResult, P as useCapxulTransitions, S as CapxulSend, T as InvocationOptions, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulDestination, k as entered, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as Destination, x as CapxulAuth, y as SignedOutState } from "./controllers-CJEsthW2.mjs";
1
+ import { A as entered, C as CreateOrganizationFailure, D as OrganizationDetails, E as InvocationOptions, F as useCapxulTransitions, M as useCapxulDestination, N as useCapxulIdentity, O as ProfileDetails, P as useCapxulSend, S as CapxulSend, T as Destination, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulAuth, k as SendResult, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as CreateOrganizationSubmission, x as CapxulAuth, y as SignedOutState } from "./controllers-DIf8elqQ.mjs";
2
2
  import { ReactNode, RefCallback } from "react";
3
3
  import { QueryClient, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
4
4
  import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, BudgetId, CapxulClient, CapxulError, CapxulResult, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, IdentityDestination, InviteMemberInput, MemberView, Money, MoneyParseErrorReason, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, PartyId, Payment, PaymentDirection, PaymentDocumentRef, PaymentDocumentRender, PaymentStatus, PaymentTiming, PaymentType, PaymentsPayInput, PayrollGroupId, PayrollGroupInput, PayrollRunId, PayrollRunStatus, Permission, PermissionMethods, PermissionReadResult, Profile, RoleView, SubmittedPermissionExecution, isClaimed, isRestoring } from "@capxul/sdk";
@@ -220,7 +220,7 @@ type ProfileDraft = {
220
220
  readonly displayName: string;
221
221
  readonly country: string;
222
222
  readonly withdrawalAddress: string;
223
- readonly username?: string;
223
+ readonly handle?: string;
224
224
  readonly payoutAddresses?: readonly PayoutDraftEntry[];
225
225
  };
226
226
  type OrganizationDraft = {
@@ -295,23 +295,23 @@ declare function acknowledgeOnboardingDestination(destination: {
295
295
  }, ownerId: string): boolean;
296
296
  declare function clearOnboardingJourney(): void;
297
297
  //#endregion
298
- //#region src/headless/onboarding/use-capxul-username-availability.d.ts
299
- type UsernameAvailability = {
298
+ //#region src/headless/onboarding/use-capxul-handle-availability.d.ts
299
+ type HandleAvailability = {
300
300
  readonly available: boolean;
301
301
  readonly normalized: string;
302
302
  };
303
- type UseCapxulUsernameAvailabilityReturn = UseQueryResult<UsernameAvailability, CapxulError>;
303
+ type UseCapxulHandleAvailabilityReturn = UseQueryResult<HandleAvailability, CapxulError>;
304
304
  /**
305
- * #1062: debounced availability probe for the username the user is typing.
305
+ * #1062: debounced availability probe for the handle the user is typing.
306
306
  * Disabled until the candidate reaches the 3-character floor; a malformed or
307
307
  * reserved candidate surfaces as the query's error (INVALID_INPUT with the
308
- * boundary's message), not as `available: false` — only a username someone
308
+ * boundary's message), not as `available: false` — only a handle someone
309
309
  * else owns is "taken".
310
310
  */
311
- declare function useCapxulUsernameAvailability(username: string, options?: {
311
+ declare function useCapxulHandleAvailability(handle: string, options?: {
312
312
  readonly enabled?: boolean;
313
313
  readonly debounceMs?: number;
314
- }): UseCapxulUsernameAvailabilityReturn;
314
+ }): UseCapxulHandleAvailabilityReturn;
315
315
  //#endregion
316
316
  //#region src/headless/media/use-capxul-image-upload.d.ts
317
317
  type ImageUploadTarget = {
@@ -622,16 +622,17 @@ declare const CapxulActivity: typeof Root$5 & {
622
622
  };
623
623
  //#endregion
624
624
  //#region src/headless/send-money/use-recipient-resolution.d.ts
625
- type SendMoneyRecipientMethod = "username" | "email-address";
626
- type SendMoneyRecipientStatus = "empty" | "checking" | "found" | "not-found" | "failed";
625
+ type SendMoneyRecipientStatus = "empty" | "invalid" | "checking" | "known-party" | "new-email" | "external-warning" | "external-ready" | "not-found" | "failed";
627
626
  interface SendMoneyRecipientSlice {
628
- readonly method: SendMoneyRecipientMethod;
629
- readonly setMethod: (method: SendMoneyRecipientMethod) => void;
630
627
  readonly value: string;
631
628
  readonly change: (text: string) => void;
632
- /** ADR-0023 R1: the status IS the failure code; the app owns the sentence. */
633
629
  readonly status: SendMoneyRecipientStatus;
634
630
  readonly label: string | null;
631
+ readonly kind: "person" | "organization" | "external_address" | "unresolved" | null;
632
+ readonly isCapxulAccount: boolean | null;
633
+ readonly publicValue: string | null;
634
+ readonly requiresAcknowledgement: boolean;
635
+ readonly acknowledgeExternalAddress: () => void;
635
636
  }
636
637
  //#endregion
637
638
  //#region src/headless/send-money/use-send-money.d.ts
@@ -997,7 +998,7 @@ declare const CapxulPayrollRun: typeof Root & {
997
998
  declare const capxulKeys: {
998
999
  root: readonly ["capxul"];
999
1000
  profile: readonly ["capxul", "profile"];
1000
- usernameAvailability: (username: string) => readonly ["capxul", "profile", "username-availability", string];
1001
+ handleAvailability: (handle: string) => readonly ["capxul", "profile", "handle-availability", string];
1001
1002
  account: readonly ["capxul", "account"];
1002
1003
  provisioning: readonly ["capxul", "provisioning"];
1003
1004
  binding: readonly ["capxul", "binding"];
@@ -1023,4 +1024,4 @@ declare const capxulKeys: {
1023
1024
  payment: (paymentId: string | undefined) => readonly ["capxul", "payments", string];
1024
1025
  };
1025
1026
  //#endregion
1026
- export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientMethod, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, type UseCapxulUsernameAvailabilityReturn, type UsernameAvailability, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
1027
+ export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationFailure, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type HandleAvailability, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulHandleAvailabilityReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as capxulKeys, f as useCapxulClientOrNull, i as entered, l as useCapxulSend, n as CapxulOnboardingController, o as useCapxulDestination, p as useCapxul, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-BkL0hHuk.mjs";
2
+ import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as capxulKeys, f as useCapxulClientOrNull, i as entered, l as useCapxulSend, n as CapxulOnboardingController, o as useCapxulDestination, p as useCapxul, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-BgkCs0nW.mjs";
3
3
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
- import { CapxulError, Errors, PAYMENT_DIRECTIONS, PAYMENT_STATUSES, fingerprintPaymentIntent, formatMoney, isCapxulError, isClaimed, isClaimed as isClaimed$1, isMoneyParseError, isRestoring, isRestoring as isRestoring$1, parseMoney, paymentPhase, resolveIdentityDestination } from "@capxul/sdk";
5
+ import { CAPXUL_OPERATIONS, CapxulError, EVM_ADDRESS_RE, Errors, HANDLE_RE, PAYMENT_DIRECTIONS, PAYMENT_STATUSES, fingerprintPaymentIntent, formatMoney, isCapxulError, isClaimed, isClaimed as isClaimed$1, isMoneyParseError, isRestoring, isRestoring as isRestoring$1, parseMoney, paymentPhase, resolveIdentityDestination, toEvmAddress, toPartyId } from "@capxul/sdk";
6
6
  import { Fragment, jsx } from "react/jsx-runtime";
7
7
  //#region src/internal/require-bootstrapped-client.ts
8
8
  /**
@@ -38,8 +38,8 @@ function useCapxulProfile() {
38
38
  const client = useCapxulClientOrNull();
39
39
  const identity = useCapxulIdentityOrNull();
40
40
  return useQuery({
41
- queryKey: capxulKeys.profile,
42
- queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "identity.loadCurrent").identity.loadCurrent()),
41
+ queryKey: [...capxulKeys.profile, identity?.phase === "authenticated" ? identity.session.authUserId : null],
42
+ queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.identity.loadCurrent).identity.loadCurrent()),
43
43
  enabled: client !== null && identity?.phase === "authenticated"
44
44
  });
45
45
  }
@@ -50,7 +50,7 @@ function useCapxulAccountBalance(options) {
50
50
  return useQuery({
51
51
  queryKey: capxulKeys.accountBalance,
52
52
  queryFn: async () => {
53
- return unwrapCapxulResult(await requireBootstrappedClient(client, "accounts.read").accounts.read());
53
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.accounts.read).accounts.read());
54
54
  },
55
55
  enabled: client !== null && (options?.enabled ?? true)
56
56
  });
@@ -62,7 +62,7 @@ function useCapxulAccountFund() {
62
62
  const queryClient = useQueryClient();
63
63
  return useMutation({
64
64
  mutationFn: async (amount) => {
65
- return unwrapCapxulResult(await requireBootstrappedClient(client, "_internal.accounts.fund")._internal.accounts.fund(amount));
65
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS._internal.accounts.fund)._internal.accounts.fund(amount));
66
66
  },
67
67
  onSuccess: async () => {
68
68
  await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
@@ -238,8 +238,8 @@ function useCapxulPay() {
238
238
  const queryClient = useQueryClient();
239
239
  return useMutation({
240
240
  mutationFn: async (input) => {
241
- rejectUnresolvedActor(input, "payments.pay");
242
- const bootstrappedClient = requireBootstrappedClient(client, "payments.pay");
241
+ rejectUnresolvedActor(input, CAPXUL_OPERATIONS.payments.pay);
242
+ const bootstrappedClient = requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.pay);
243
243
  return withPaymentRequestKey("personal-pay", {
244
244
  actorId,
245
245
  backendScope,
@@ -262,7 +262,7 @@ function useCapxulCreateCommitment() {
262
262
  const queryClient = useQueryClient();
263
263
  return useMutation({
264
264
  mutationFn: async (input) => {
265
- return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.createCommitment").payments.createCommitment(input));
265
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.createCommitment).payments.createCommitment(input));
266
266
  },
267
267
  onSuccess: (payment) => invalidateMoneyState(queryClient, {
268
268
  actor: { kind: "personal" },
@@ -290,7 +290,7 @@ function useCapxulRedirectPayment() {
290
290
  const queryClient = useQueryClient();
291
291
  return useMutation({
292
292
  mutationFn: async (input) => {
293
- return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.redirect").payments.redirect(input));
293
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.redirect).payments.redirect(input));
294
294
  },
295
295
  onSuccess: (payment) => invalidateMoneyState(queryClient, {
296
296
  actor: { kind: "personal" },
@@ -304,7 +304,7 @@ function useCapxulPayments(options) {
304
304
  return useQuery({
305
305
  queryKey: capxulKeys.payments,
306
306
  queryFn: async () => {
307
- return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.list").payments.list());
307
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.list).payments.list());
308
308
  },
309
309
  enabled: client !== null && identity !== null && isClaimed$1(identity) && (options?.enabled ?? true)
310
310
  });
@@ -315,7 +315,7 @@ function useCapxulPayment(paymentId, options) {
315
315
  queryKey: capxulKeys.payment(paymentId),
316
316
  queryFn: async () => {
317
317
  if (paymentId === void 0) throw Errors.invalidInput("paymentId", "required for payments.get");
318
- return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.get").payments.get(paymentId));
318
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.get).payments.get(paymentId));
319
319
  },
320
320
  enabled: client !== null && paymentId !== void 0 && (options?.enabled ?? true)
321
321
  });
@@ -335,7 +335,7 @@ function useCapxulOrganizationPay(orgId) {
335
335
  return useMutation({
336
336
  mutationFn: async (input) => {
337
337
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrganizationPay");
338
- const bootstrapped = requireBootstrappedClient(client, "organizationPayments.pay");
338
+ const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.organizationPayments.pay);
339
339
  return withPaymentRequestKey("organization-pay", {
340
340
  backendScope,
341
341
  orgId,
@@ -363,7 +363,7 @@ function useCapxulOrganizationPayBatch(orgId) {
363
363
  const queryClient = useQueryClient();
364
364
  return useMutation({
365
365
  mutationFn: async (input) => {
366
- const bootstrapped = requireBootstrappedClient(client, "organizationPayments.payBatch");
366
+ const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.organizationPayments.payBatch);
367
367
  return withPaymentRequestKey("organization-pay-batch", {
368
368
  backendScope,
369
369
  orgId,
@@ -391,7 +391,7 @@ function usePermissionMutation(orgId, operation) {
391
391
  const queryClient = useQueryClient();
392
392
  return useMutation({
393
393
  mutationFn: async (input) => {
394
- const method = requireBootstrappedClient(client, `permissions.${operation}`).org(orgId).permissions[operation];
394
+ const method = requireBootstrappedClient(client, CAPXUL_OPERATIONS.permissions[operation]).org(orgId).permissions[operation];
395
395
  return unwrapCapxulResult(await method(input));
396
396
  },
397
397
  onSuccess: () => queryClient.invalidateQueries({ queryKey: capxulKeys.orgPermissions(orgId) })
@@ -408,7 +408,7 @@ function useCapxulPermissions(orgId, options) {
408
408
  return useQuery({
409
409
  queryKey: capxulKeys.orgPermissions(orgId),
410
410
  queryFn: async () => {
411
- return unwrapCapxulResult(await requireBootstrappedClient(client, "permissions.list").org(orgId).permissions.list());
411
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.permissions.list).org(orgId).permissions.list());
412
412
  },
413
413
  enabled: client !== null && identity !== null && isClaimed$1(identity) && (options?.enabled ?? true)
414
414
  });
@@ -419,7 +419,7 @@ function useCapxulPermission(orgId, permissionId) {
419
419
  queryKey: [...capxulKeys.orgPermissions(orgId), permissionId ?? "pending"],
420
420
  queryFn: async () => {
421
421
  if (permissionId === void 0) throw Errors.invalidInput("permissionId", "required for permissions.get");
422
- return unwrapCapxulResult(await requireBootstrappedClient(client, "permissions.get").org(orgId).permissions.get(permissionId));
422
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.permissions.get).org(orgId).permissions.get(permissionId));
423
423
  },
424
424
  enabled: client !== null && permissionId !== void 0
425
425
  });
@@ -432,7 +432,7 @@ function useCapxulActivity(params) {
432
432
  return useQuery({
433
433
  queryKey: [...capxulKeys.activity, params ?? {}],
434
434
  queryFn: async () => {
435
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.list").activity.list(params));
435
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(params));
436
436
  },
437
437
  enabled: client !== null && identity !== null && isClaimed$1(identity)
438
438
  });
@@ -444,7 +444,7 @@ function useCapxulActivityDetail(reference, actor) {
444
444
  queryKey: capxulKeys.activityDetail(reference, actor),
445
445
  queryFn: async () => {
446
446
  if (reference === void 0) throw Errors.invalidInput("reference", "required for activity.get");
447
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.get").activity.get(reference, actor === void 0 ? void 0 : { actor }));
447
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.get).activity.get(reference, actor === void 0 ? void 0 : { actor }));
448
448
  },
449
449
  enabled: client !== null && reference !== void 0 && identity !== null && isClaimed$1(identity)
450
450
  });
@@ -454,7 +454,7 @@ function useCapxulAnnotateMovement() {
454
454
  const queryClient = useQueryClient();
455
455
  return useMutation({
456
456
  mutationFn: async (input) => {
457
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.annotate").activity.annotate(input));
457
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.annotate).activity.annotate(input));
458
458
  },
459
459
  onSuccess: () => queryClient.invalidateQueries({ queryKey: capxulKeys.activity })
460
460
  });
@@ -468,7 +468,7 @@ function useCapxulHoldings(params) {
468
468
  return useQuery({
469
469
  queryKey: capxulKeys.holdings(actor),
470
470
  queryFn: async () => {
471
- return unwrapCapxulResult(await requireBootstrappedClient(client, "holdings.current").holdings.current(actor === void 0 ? void 0 : { actor }));
471
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.holdings.current).holdings.current(actor === void 0 ? void 0 : { actor }));
472
472
  },
473
473
  enabled: client !== null && identity !== null && isClaimed$1(identity)
474
474
  });
@@ -494,7 +494,7 @@ function useCapxulOrgMembers(orgId, options) {
494
494
  queryKey: capxulKeys.orgMembers(orgId),
495
495
  queryFn: async () => {
496
496
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgMembers");
497
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.members").org(orgId).members());
497
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.members).org(orgId).members());
498
498
  },
499
499
  enabled: client !== null && enabled && orgId !== void 0
500
500
  });
@@ -508,7 +508,7 @@ function useCapxulOrgRoles(orgId, options) {
508
508
  queryKey: capxulKeys.orgRoles(orgId),
509
509
  queryFn: async () => {
510
510
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgRoles");
511
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.roles").org(orgId).roles());
511
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.roles).org(orgId).roles());
512
512
  },
513
513
  enabled: client !== null && enabled && orgId !== void 0
514
514
  });
@@ -522,7 +522,7 @@ function useCapxulOrgTreasury(orgId, options) {
522
522
  queryKey: capxulKeys.orgTreasury(orgId),
523
523
  queryFn: async () => {
524
524
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgTreasury");
525
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.treasury").org(orgId).treasury());
525
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.treasury).org(orgId).treasury());
526
526
  },
527
527
  enabled: client !== null && enabled && orgId !== void 0
528
528
  });
@@ -549,7 +549,7 @@ function useCapxulInviteMember(orgId) {
549
549
  return useMutation({
550
550
  mutationFn: async (input) => {
551
551
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulInviteMember");
552
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.invite").org(orgId).invite(input));
552
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.invite).org(orgId).invite(input));
553
553
  },
554
554
  onSuccess: async () => {
555
555
  if (orgId === void 0) return;
@@ -733,10 +733,10 @@ function isProfileDraft(value) {
733
733
  "displayName",
734
734
  "country",
735
735
  "withdrawalAddress",
736
- "username",
736
+ "handle",
737
737
  "payoutAddresses"
738
738
  ]) || !isDraftText(value.displayName) || !isDraftText(value.country) || !isDraftText(value.withdrawalAddress)) return false;
739
- if (value.username !== void 0 && !isDraftText(value.username)) return false;
739
+ if (value.handle !== void 0 && !isDraftText(value.handle)) return false;
740
740
  if (value.payoutAddresses !== void 0 && !isPayoutDraftList(value.payoutAddresses)) return false;
741
741
  return true;
742
742
  }
@@ -790,21 +790,21 @@ function useDebouncedValue(value, delayMs) {
790
790
  return debounced;
791
791
  }
792
792
  //#endregion
793
- //#region src/headless/onboarding/use-capxul-username-availability.ts
793
+ //#region src/headless/onboarding/use-capxul-handle-availability.ts
794
794
  /**
795
- * #1062: debounced availability probe for the username the user is typing.
795
+ * #1062: debounced availability probe for the handle the user is typing.
796
796
  * Disabled until the candidate reaches the 3-character floor; a malformed or
797
797
  * reserved candidate surfaces as the query's error (INVALID_INPUT with the
798
- * boundary's message), not as `available: false` — only a username someone
798
+ * boundary's message), not as `available: false` — only a handle someone
799
799
  * else owns is "taken".
800
800
  */
801
- function useCapxulUsernameAvailability(username, options) {
801
+ function useCapxulHandleAvailability(handle, options) {
802
802
  const client = useCapxulClientOrNull();
803
- const candidate = useDebouncedValue(username.trim(), options?.debounceMs ?? 300);
803
+ const candidate = useDebouncedValue(handle.trim(), options?.debounceMs ?? 300);
804
804
  return useQuery({
805
- queryKey: capxulKeys.usernameAvailability(candidate),
805
+ queryKey: capxulKeys.handleAvailability(candidate),
806
806
  queryFn: async () => {
807
- return unwrapCapxulResult(await requireBootstrappedClient(client, "identity.usernameAvailable").identity.usernameAvailable(candidate));
807
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.identity.handleAvailable).identity.handleAvailable(candidate));
808
808
  },
809
809
  enabled: client !== null && candidate.length >= 3 && (options?.enabled ?? true)
810
810
  });
@@ -822,7 +822,7 @@ function useCapxulImageUpload() {
822
822
  const queryClient = useQueryClient();
823
823
  return useMutation({
824
824
  mutationFn: async ({ blob, target }) => {
825
- const media = requireBootstrappedClient(client, "media.uploadImage").media;
825
+ const media = requireBootstrappedClient(client, CAPXUL_OPERATIONS.media.uploadImage).media;
826
826
  const uploaded = unwrapCapxulResult(await media.uploadImage(blob));
827
827
  if (target.kind === "profile") return { url: unwrapCapxulResult(await media.setProfileImage({ storageId: uploaded.storageId })).imageUrl };
828
828
  return { url: unwrapCapxulResult(await media.setOrgLogo({
@@ -864,7 +864,7 @@ function useContacts(input) {
864
864
  const [value, setValue] = useState("");
865
865
  const [addError, setAddError] = useState(null);
866
866
  const addContact = useMutation({
867
- mutationFn: async (ref) => unwrapCapxulResult(await requireBook(book, "addressBook.add").add({ ref })),
867
+ mutationFn: async (ref) => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.add).add({ ref })),
868
868
  onSettled: invalidate
869
869
  });
870
870
  const addMutate = addContact.mutate;
@@ -935,7 +935,7 @@ function useContactsList(engine, options) {
935
935
  const { book, refusal } = engine;
936
936
  const query = useQuery({
937
937
  queryKey: capxulKeys.contactsList(engine.scope, includeHidden),
938
- queryFn: async () => unwrapCapxulResult(await requireBook(book, "addressBook.list").list({ includeHidden })),
938
+ queryFn: async () => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.list).list({ includeHidden })),
939
939
  enabled: book !== null
940
940
  });
941
941
  const reason = refusal ?? (query.isError ? "unavailable" : query.data === void 0 ? "loading" : null);
@@ -1128,7 +1128,7 @@ function useActivityDetail(reference, actor) {
1128
1128
  queryKey: capxulKeys.activityDetail(reference, actor),
1129
1129
  queryFn: async () => {
1130
1130
  if (reference === void 0) throw Errors.invalidInput("reference", "required for activity.get");
1131
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.get").activity.get(reference, actor === void 0 ? void 0 : { actor }));
1131
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.get).activity.get(reference, actor === void 0 ? void 0 : { actor }));
1132
1132
  },
1133
1133
  enabled
1134
1134
  });
@@ -1138,7 +1138,7 @@ function useActivityDetail(reference, actor) {
1138
1138
  if (reference === void 0 || receiptDocument === null) throw Errors.invalidInput("receiptDocument", "no renderable document on this row");
1139
1139
  setIsOpeningDocument(true);
1140
1140
  try {
1141
- return unwrapCapxulResult(await requireBootstrappedClient(client, "paymentDocuments.render").paymentDocuments.render(receiptDocument.documentHash));
1141
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.paymentDocuments.render).paymentDocuments.render(receiptDocument.documentHash));
1142
1142
  } finally {
1143
1143
  setIsOpeningDocument(false);
1144
1144
  }
@@ -1280,14 +1280,14 @@ function useActivitySummary(actor, window) {
1280
1280
  const params = {};
1281
1281
  if (actor !== void 0) params.actor = actor;
1282
1282
  if (range !== void 0) params.window = range;
1283
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.summary").activity.summary(params));
1283
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.summary).activity.summary(params));
1284
1284
  },
1285
1285
  enabled
1286
1286
  });
1287
1287
  const primary = useQuery({
1288
1288
  queryKey: [...capxulKeys.holdings(actor), "primary"],
1289
1289
  queryFn: async () => {
1290
- return unwrapCapxulResult(await requireBootstrappedClient(client, "holdings.primary").holdings.primary(actor === void 0 ? void 0 : { actor }));
1290
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.holdings.primary).holdings.primary(actor === void 0 ? void 0 : { actor }));
1291
1291
  },
1292
1292
  enabled
1293
1293
  });
@@ -1329,7 +1329,7 @@ function useActivitySummary(actor, window) {
1329
1329
  //#region src/headless/activity/rows.ts
1330
1330
  /**
1331
1331
  * A Movement's phase is DERIVED, not asserted: `movementItems` returns `null`
1332
- * for any Movement whose `canonicalState` is not `"finalized"`
1332
+ * for any Movement whose `canonicalState` is not `"included"`
1333
1333
  * (`activityList.ts:120`), so a Movement that reaches a page is finished and
1334
1334
  * carries no verdict of its own.
1335
1335
  */
@@ -1526,7 +1526,7 @@ function useActivity(input) {
1526
1526
  filter ?? "none"
1527
1527
  ],
1528
1528
  queryFn: async ({ pageParam }) => {
1529
- return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.list").activity.list(listParams(pageParam, limit)));
1529
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit)));
1530
1530
  },
1531
1531
  initialPageParam: void 0,
1532
1532
  getNextPageParam: (last) => last.cursor ?? void 0,
@@ -1577,7 +1577,7 @@ function useActivity(input) {
1577
1577
  const toCsv = useCallback(async () => {
1578
1578
  setIsExporting(true);
1579
1579
  try {
1580
- const bootstrapped = requireBootstrappedClient(client, "activity.list");
1580
+ const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list);
1581
1581
  const items = [];
1582
1582
  let cursor;
1583
1583
  for (let page = 0; page < EXPORT_PAGE_CEILING; page += 1) {
@@ -1723,7 +1723,7 @@ function useOrgMeReading(orgId) {
1723
1723
  const query = useQuery({
1724
1724
  queryKey: capxulKeys.orgMe(orgId),
1725
1725
  queryFn: async () => {
1726
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.me").org(orgId).me());
1726
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.me).org(orgId).me());
1727
1727
  },
1728
1728
  enabled: ready && orgId !== void 0
1729
1729
  });
@@ -1753,67 +1753,126 @@ function useSignerStatus(client) {
1753
1753
  }
1754
1754
  //#endregion
1755
1755
  //#region src/headless/send-money/use-recipient-resolution.ts
1756
- function toTargetReference(method, text) {
1756
+ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1757
+ const PARTY_ID_RE = /^party_[0-9A-Za-z]+$/;
1758
+ const RESOLVE_DEBOUNCE_MS = 400;
1759
+ function parseRecipient(text) {
1757
1760
  const trimmed = text.trim();
1758
- if (trimmed === "") return null;
1759
- return method === "username" ? {
1760
- kind: "handle",
1761
- handle: trimmed.replace(/^@/, "")
1762
- } : {
1763
- kind: "email",
1764
- email: trimmed
1761
+ if (trimmed === "") return { status: "empty" };
1762
+ if (PARTY_ID_RE.test(trimmed)) return {
1763
+ status: "valid",
1764
+ reference: {
1765
+ kind: "party",
1766
+ partyId: toPartyId(trimmed)
1767
+ }
1765
1768
  };
1769
+ if (EVM_ADDRESS_RE.test(trimmed)) return {
1770
+ status: "valid",
1771
+ reference: {
1772
+ kind: "address",
1773
+ address: toEvmAddress(trimmed)
1774
+ }
1775
+ };
1776
+ if (EMAIL_RE.test(trimmed)) return {
1777
+ status: "valid",
1778
+ reference: {
1779
+ kind: "email",
1780
+ email: trimmed.toLowerCase()
1781
+ }
1782
+ };
1783
+ const handle = trimmed.replace(/^@/, "").toLowerCase();
1784
+ if (HANDLE_RE.test(handle)) return {
1785
+ status: "valid",
1786
+ reference: {
1787
+ kind: "handle",
1788
+ handle
1789
+ }
1790
+ };
1791
+ return { status: "invalid" };
1766
1792
  }
1767
- /** How long the engine waits after the last keystroke before resolving. */
1768
- const RESOLVE_DEBOUNCE_MS = 400;
1769
- function useRecipientResolution(client) {
1770
- const [method, setMethodState] = useState("email-address");
1793
+ function sameReference(left, right) {
1794
+ return JSON.stringify(left) === JSON.stringify(right);
1795
+ }
1796
+ function publicRecipientValue(value) {
1797
+ if (value === null) return null;
1798
+ if (value.status === "known_party") return value.handle ?? value.label;
1799
+ return value.status === "external_address" ? value.safeAddress : null;
1800
+ }
1801
+ function recipientStatus(parsed, settled, acknowledged) {
1802
+ if (parsed.status === "empty" || parsed.status === "invalid") return parsed.status;
1803
+ if (settled === null) return "checking";
1804
+ if (!settled.ok) return settled.error.code === "INVALID_INPUT" ? "not-found" : "failed";
1805
+ if (settled.value.status === "known_party") return "known-party";
1806
+ if (settled.value.status === "new_email") return "new-email";
1807
+ return acknowledged ? "external-ready" : "external-warning";
1808
+ }
1809
+ function useRecipientResolution(client, scope, organizationId) {
1771
1810
  const [text, setText] = useState("");
1772
- const reference = useMemo(() => toTargetReference(method, text), [method, text]);
1811
+ const parsed = useMemo(() => parseRecipient(text), [text]);
1812
+ const reference = parsed.status === "valid" ? parsed.reference : null;
1773
1813
  const debouncedReference = useDebouncedValue(reference, RESOLVE_DEBOUNCE_MS);
1814
+ const debouncedText = useDebouncedValue(text, RESOLVE_DEBOUNCE_MS);
1774
1815
  const [outcome, setOutcome] = useState(null);
1816
+ const [acknowledgedOutcome, setAcknowledgedOutcome] = useState(null);
1817
+ const capturedAcknowledgement = useRef(null);
1818
+ const change = useCallback((next) => {
1819
+ if (next === text) return;
1820
+ setAcknowledgedOutcome(null);
1821
+ setOutcome(null);
1822
+ setText(next);
1823
+ }, [text]);
1775
1824
  useEffect(() => {
1776
1825
  if (debouncedReference === null || client === null) {
1777
1826
  setOutcome(null);
1778
1827
  return;
1779
1828
  }
1780
1829
  const controller = new AbortController();
1781
- setOutcome({
1782
- reference: debouncedReference,
1783
- status: "checking",
1784
- label: null
1785
- });
1830
+ setOutcome(null);
1786
1831
  client.targets.resolve(debouncedReference, { signal: controller.signal }).then((result) => {
1787
- if (controller.signal.aborted) return;
1788
- setOutcome(result.ok ? {
1789
- reference: debouncedReference,
1790
- status: "found",
1791
- label: result.value.label
1792
- } : {
1793
- reference: debouncedReference,
1794
- status: result.error.code === "INVALID_INPUT" ? "not-found" : "failed",
1795
- label: null
1832
+ if (!controller.signal.aborted) setOutcome({
1833
+ client,
1834
+ scope,
1835
+ text: debouncedText,
1836
+ input: debouncedReference,
1837
+ result
1796
1838
  });
1797
1839
  });
1798
1840
  return () => controller.abort();
1799
- }, [client, debouncedReference]);
1800
- const setMethod = useCallback((next) => {
1801
- setMethodState(next);
1802
- setText("");
1803
- }, []);
1804
- const settled = outcome !== null && outcome.reference === debouncedReference ? outcome : null;
1805
- const status = reference === null ? "empty" : reference !== debouncedReference || settled === null ? "checking" : settled.status;
1806
- const resolvedReference = status === "found" ? settled?.reference ?? null : null;
1841
+ }, [
1842
+ client,
1843
+ scope,
1844
+ debouncedReference,
1845
+ debouncedText
1846
+ ]);
1847
+ const settled = reference !== null && debouncedReference !== null && outcome !== null && outcome.client === client && outcome.scope === scope && outcome.text === text && sameReference(reference, debouncedReference) && sameReference(outcome.input, debouncedReference) ? outcome.result : null;
1848
+ const status = recipientStatus(parsed, settled, acknowledgedOutcome === outcome);
1849
+ const ready = settled?.ok === true && (settled.value.status !== "external_address" || status === "external-ready");
1850
+ const value = settled?.ok === true ? settled.value : null;
1851
+ const acknowledgeExternalAddress = useCallback(() => {
1852
+ if (value?.status !== "external_address" || outcome === null) return;
1853
+ setAcknowledgedOutcome(outcome);
1854
+ if (capturedAcknowledgement.current === outcome) return;
1855
+ capturedAcknowledgement.current = outcome;
1856
+ client?._internal.captureExternalAddressAcknowledged(value.safeAddress, organizationId);
1857
+ }, [
1858
+ client,
1859
+ organizationId,
1860
+ value,
1861
+ outcome
1862
+ ]);
1807
1863
  return {
1808
1864
  slice: {
1809
- method,
1810
- setMethod,
1811
1865
  value: text,
1812
- change: setText,
1866
+ change,
1813
1867
  status,
1814
- label: status === "found" ? settled?.label ?? null : null
1868
+ label: value?.label ?? null,
1869
+ kind: value?.kind ?? null,
1870
+ isCapxulAccount: value?.isCapxulAccount ?? null,
1871
+ publicValue: publicRecipientValue(value),
1872
+ requiresAcknowledgement: status === "external-warning",
1873
+ acknowledgeExternalAddress
1815
1874
  },
1816
- resolvedReference,
1875
+ resolvedReference: ready && value !== null ? value.reference : null,
1817
1876
  trimmed: text.trim()
1818
1877
  };
1819
1878
  }
@@ -1858,7 +1917,11 @@ function useSendMoney(input) {
1858
1917
  const parsed = useMemo(() => selectedAssetMoney === null || amountText.trim() === "" ? null : parseMoney(amountText, selectedAssetMoney), [amountText, selectedAssetMoney]);
1859
1918
  const parsedMoney = parsed !== null && !isMoneyParseError(parsed) ? parsed : null;
1860
1919
  const amountError = parsed !== null && isMoneyParseError(parsed) ? parsed.reason : null;
1861
- const recipient = useRecipientResolution(client);
1920
+ const recipient = useRecipientResolution(client, JSON.stringify([
1921
+ actor.kind,
1922
+ orgId,
1923
+ account?.id
1924
+ ]), orgId);
1862
1925
  const resolvedReference = recipient.resolvedReference;
1863
1926
  const personalPay = useCapxulPay();
1864
1927
  const organizationPay = useCapxulOrganizationPay(orgId);
@@ -1870,6 +1933,7 @@ function useSendMoney(input) {
1870
1933
  if (parsedMoney === null || resolvedReference === null) return;
1871
1934
  const amount = parsedMoney;
1872
1935
  const sentRecipient = recipient.trimmed;
1936
+ const externalAddressAcknowledged = recipient.slice.status === "external-ready";
1873
1937
  const callbacks = {
1874
1938
  onSuccess: (payment) => onSent({
1875
1939
  payment,
@@ -1885,7 +1949,8 @@ function useSendMoney(input) {
1885
1949
  submitGate.current = true;
1886
1950
  personalPay.mutate({
1887
1951
  to: resolvedReference,
1888
- amount
1952
+ amount,
1953
+ ...externalAddressAcknowledged ? { externalAddressAcknowledged: true } : {}
1889
1954
  }, callbacks);
1890
1955
  return;
1891
1956
  }
@@ -1894,7 +1959,8 @@ function useSendMoney(input) {
1894
1959
  organizationPay.mutate({
1895
1960
  permissionId: selectedSource.id,
1896
1961
  to: resolvedReference,
1897
- amount
1962
+ amount,
1963
+ ...externalAddressAcknowledged ? { externalAddressAcknowledged: true } : {}
1898
1964
  }, callbacks);
1899
1965
  }, [
1900
1966
  actor.kind,
@@ -1905,6 +1971,7 @@ function useSendMoney(input) {
1905
1971
  parsedMoney,
1906
1972
  personalPay,
1907
1973
  recipient.trimmed,
1974
+ recipient.slice.status,
1908
1975
  resolvedReference,
1909
1976
  selectedSource
1910
1977
  ]);
@@ -2175,7 +2242,7 @@ function useDashboardAccess(scope) {
2175
2242
  const lifecycle = useQuery({
2176
2243
  queryKey: capxulKeys.orgLifecycle(orgId),
2177
2244
  queryFn: async () => {
2178
- return unwrapCapxulResult(await requireBootstrappedClient(client, "org.getLifecycle").org(orgId).getLifecycle());
2245
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.getLifecycle).org(orgId).getLifecycle());
2179
2246
  },
2180
2247
  enabled: wantsLifecycle && client !== null
2181
2248
  });
@@ -2337,7 +2404,7 @@ function useOrgRoster(orgId) {
2337
2404
  const client = useCapxulClientOrNull();
2338
2405
  const query = useQuery({
2339
2406
  queryKey: capxulKeys.contactsList(orgId ?? "pending", false),
2340
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.addressBook.list", orgId).addressBook.list({ includeHidden: false })),
2407
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.addressBook.list, orgId).addressBook.list({ includeHidden: false })),
2341
2408
  enabled: client !== null && orgId !== void 0
2342
2409
  });
2343
2410
  const entries = query.data;
@@ -2359,7 +2426,7 @@ function usePayrollGroups(orgId) {
2359
2426
  const client = useCapxulClientOrNull();
2360
2427
  return useQuery({
2361
2428
  queryKey: capxulKeys.payrollGroups(orgId),
2362
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.payroll.groups.list", orgId).payroll.groups.list()),
2429
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.groups.list, orgId).payroll.groups.list()),
2363
2430
  enabled: client !== null && orgId !== void 0
2364
2431
  });
2365
2432
  }
@@ -2367,7 +2434,7 @@ function usePayrollRuns(orgId) {
2367
2434
  const client = useCapxulClientOrNull();
2368
2435
  return useQuery({
2369
2436
  queryKey: capxulKeys.payrollRuns(orgId),
2370
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.payroll.runs", orgId).payroll.runs()),
2437
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.runs, orgId).payroll.runs()),
2371
2438
  enabled: client !== null && orgId !== void 0
2372
2439
  });
2373
2440
  }
@@ -2383,7 +2450,7 @@ function useOrgTerms(orgId) {
2383
2450
  const client = useCapxulClientOrNull();
2384
2451
  return useQuery({
2385
2452
  queryKey: capxulKeys.payrollTerms(orgId),
2386
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.payroll.terms", orgId).payroll.terms()),
2453
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.terms, orgId).payroll.terms()),
2387
2454
  enabled: client !== null && orgId !== void 0
2388
2455
  });
2389
2456
  }
@@ -2391,7 +2458,7 @@ function useOrgTreasury(orgId) {
2391
2458
  const client = useCapxulClientOrNull();
2392
2459
  return useQuery({
2393
2460
  queryKey: capxulKeys.orgTreasury(orgId),
2394
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.treasury", orgId).treasury()),
2461
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.treasury, orgId).treasury()),
2395
2462
  enabled: client !== null && orgId !== void 0
2396
2463
  });
2397
2464
  }
@@ -2404,7 +2471,7 @@ function useOrgMe(orgId) {
2404
2471
  const client = useCapxulClientOrNull();
2405
2472
  return useQuery({
2406
2473
  queryKey: capxulKeys.orgMe(orgId),
2407
- queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.me", orgId).me()),
2474
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.me, orgId).me()),
2408
2475
  enabled: client !== null && orgId !== void 0
2409
2476
  });
2410
2477
  }
@@ -2460,7 +2527,7 @@ function usePayroll(orgId) {
2460
2527
  const invalidate = useCallback(() => queryClient.invalidateQueries({ queryKey: capxulKeys.payrollGroups(orgId) }), [orgId, queryClient]);
2461
2528
  const write = useMutation({
2462
2529
  mutationFn: async (command) => {
2463
- const payroll = scopedClient(client, `org.payroll.groups.${command.kind}`, orgId).payroll;
2530
+ const payroll = scopedClient(client, CAPXUL_OPERATIONS.org.payroll.groups[command.kind], orgId).payroll;
2464
2531
  if (command.kind === "remove") {
2465
2532
  unwrapCapxulResult(await payroll.groups.remove(command.id));
2466
2533
  return null;
@@ -2811,7 +2878,7 @@ function usePayrollRun(input) {
2811
2878
  const authorize = useMutation({
2812
2879
  mutationFn: async (command) => {
2813
2880
  const runAt = Date.now();
2814
- return unwrapCapxulResult(await scopedClient(client, "org.payroll.authorizeRun", orgId).payroll.authorizeRun({
2881
+ return unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.authorizeRun, orgId).payroll.authorizeRun({
2815
2882
  permissionId: command.permissionId,
2816
2883
  period: {
2817
2884
  start: runAt,
@@ -2968,4 +3035,4 @@ const CapxulPayrollRun = Object.assign(Root, {
2968
3035
  Actions
2969
3036
  });
2970
3037
  //#endregion
2971
- export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
3038
+ export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
@@ -1,4 +1,4 @@
1
- import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-CJEsthW2.mjs";
1
+ import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-DIf8elqQ.mjs";
2
2
  import * as React from "react";
3
3
  import { ReactNode } from "react";
4
4
  import { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, SeedTestIdentityInput, createCapxulTestClient } from "@capxul/sdk/testing";
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-BkL0hHuk.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-BgkCs0nW.mjs";
2
2
  import "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createCapxulTestClient } from "@capxul/sdk/testing";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capxul/sdk-react",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
@@ -26,7 +26,7 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@capxul/sdk": "3.1.0"
29
+ "@capxul/sdk": "4.0.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -43,8 +43,8 @@
43
43
  "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
44
44
  "vite-plus": "0.3.0",
45
45
  "vitest": "4.1.11",
46
- "@capxul/errors": "0.2.0",
47
- "@capxul/types": "0.2.3",
46
+ "@capxul/errors": "0.3.0",
47
+ "@capxul/types": "0.3.0",
48
48
  "@capxul/typescript-config": "0.0.0"
49
49
  },
50
50
  "peerDependencies": {