@capxul/sdk-react 2.1.0 → 2.2.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.
package/README.md CHANGED
@@ -35,6 +35,19 @@ export function Providers({ children }: { children: React.ReactNode }) {
35
35
  - Rich-data hooks such as `useCapxulProfile`, `useCapxulOrgs`, members, roles,
36
36
  treasury, and money hooks remain TanStack Query projections. Personal
37
37
  holdings and activity reads start only after the Account is claimed.
38
+ - `CapxulSendMoney` is the compound send component. One root owns the send
39
+ behaviour and draws nothing. The `.Asset`, `.Amount`, `.Recipient`, and
40
+ `.Actions` region parts each hand the screen one finished slice. The engine
41
+ hook stays module-scoped. This release ships the personal actor path;
42
+ `.Source` and the organization path follow the Access & session budgets
43
+ read.
44
+ - `CapxulContacts` is the compound address-book component. One root owns the
45
+ book behaviour and draws nothing. The `.Summary`, `.List`, and `.Add` region
46
+ parts each hand the screen one finished slice, and a `.List` row carries its
47
+ own `rename`, `hide`, and `unhide` verbs. A screen places any subset. Both
48
+ actor paths ship: a personal actor reads the account book, and an
49
+ organization actor reads the organization book. The `managePeople` capability
50
+ gate stays in the app, on `CapxulOrgMember.Can`.
38
51
 
39
52
  The packed npm package exposes `@capxul/sdk-react` and
40
53
  `@capxul/sdk-react/testing`. The workspace-only `@capxul/sdk-react/headless`
@@ -80,6 +80,17 @@ const capxulKeys = {
80
80
  orgId ?? "pending",
81
81
  "permissions"
82
82
  ],
83
+ contacts: (scope) => [
84
+ "capxul",
85
+ "contacts",
86
+ scope
87
+ ],
88
+ contactsList: (scope, includeHidden) => [
89
+ "capxul",
90
+ "contacts",
91
+ scope,
92
+ includeHidden ? "all" : "visible"
93
+ ],
83
94
  activity: ["capxul", "activity"],
84
95
  activityDetail: (reference) => [
85
96
  "capxul",
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
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-D3_Q5d2t.mjs";
2
2
  import { ReactNode } from "react";
3
3
  import { QueryClient, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
4
- import { Account, AccountRequirement, ActivityAnnotationInput, ActivityDetail, ActivityListParams, ActivityPage, ActivityReference, CapxulClient, CapxulError, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, InviteMemberInput, MemberView, Money, MovementAnnotation, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, Payment, PaymentTiming, PaymentsPayInput, Permission, PermissionReadResult, Profile, RoleView } from "@capxul/sdk";
4
+ import { Account, AccountRequirement, ActivityAnnotationInput, ActivityDetail, ActivityListParams, ActivityPage, ActivityReference, AddressBookEntry, CapxulClient, CapxulError, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, InviteMemberInput, MemberView, Money, MoneyParseErrorReason, MovementAnnotation, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, PartyId, Payment, PaymentTiming, PaymentsPayInput, Permission, PermissionReadResult, Profile, RoleView } from "@capxul/sdk";
5
5
 
6
6
  //#region src/provider.d.ts
7
7
  type CapxulProviderSharedProps = {
@@ -112,6 +112,7 @@ type Address = Brand<string, "Address">;
112
112
  type PermissionId = Brand<string, "PermissionId">;
113
113
  type PermissionAssignmentId = Brand<string, "PermissionAssignmentId">;
114
114
  type PaymentCommandId = Brand<string, "PaymentCommandId">;
115
+ type OrgId$1 = Brand<string, "OrgId">;
115
116
  type WeiAmount = Brand<string, "WeiAmount">;
116
117
  type RoleKey = Brand<string, "RoleKey">;
117
118
  type AllowanceKey = Brand<string, "AllowanceKey">;
@@ -517,4 +518,215 @@ type UseCapxulImageUploadReturn = UseMutationResult<{
517
518
  */
518
519
  declare function useCapxulImageUpload(): UseCapxulImageUploadReturn;
519
520
  //#endregion
520
- export { type AccountFailure, type AccountProgress, type ActionResult, type AuthenticatedState, type AuthenticationSlots, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulOnboardingController, CapxulProvider, type CapxulProviderProps, type CapxulSend, type ControllerAction, type CreateOrganizationSubmission, 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 OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendResult, type SignedOutState, type Slot, 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, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, 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 };
521
+ //#region src/headless/contacts/use-contacts.d.ts
522
+ type ContactsActor = {
523
+ readonly kind: "personal";
524
+ } | {
525
+ readonly kind: "organization";
526
+ readonly orgId: OrgId$1 | undefined;
527
+ };
528
+ /**
529
+ * How a contact entered the book. Taken from the shipped surface rather than
530
+ * re-declared, so the component can never advertise a provenance the wire
531
+ * cannot carry (ADR-0022 R2; #1532 owns the definition site).
532
+ */
533
+ type ContactRelationship = AddressBookEntry["relationship"][number];
534
+ interface Contact {
535
+ /**
536
+ * The counterparty's `PartyId` — created once and claimed at signup, never
537
+ * re-keyed (ADR-0022 R1/R3). No email, no prefix, nothing to parse.
538
+ */
539
+ readonly id: PartyId;
540
+ /** The saved label when there is one, else the party's display name. */
541
+ readonly name: string;
542
+ readonly relationship: readonly ContactRelationship[];
543
+ readonly hidden: boolean;
544
+ /** Epoch milliseconds. The seam never formats a date; the app writes the words. */
545
+ readonly lastActivityAt: number;
546
+ }
547
+ interface ContactRow extends Contact {
548
+ /** Ours: one initials rule, not one copy per screen. */
549
+ readonly initials: string;
550
+ readonly rename: (name: string) => void;
551
+ readonly hide: () => void;
552
+ readonly unhide: () => void;
553
+ }
554
+ /** ADR-0023 R1: refusal CODES, never sentences — the app owns the words. */
555
+ type ContactsRefusal = "loading" | "org-unavailable" | "unavailable";
556
+ /**
557
+ * The blocked facts, in the fixed order `.Add.blockedReason` names them.
558
+ * `"no-permission"` is absent by ruling, not by omission: the org screen places
559
+ * `CapxulOrgMember.Can do="managePeople"` around its own Add control.
560
+ */
561
+ type ContactsAddBlockedReason = "org-unavailable" | "empty";
562
+ /**
563
+ * Why an add did not land, as a code. ADR-0023 R1 supersedes the contract's
564
+ * field-message carve-out: `"unresolved"` is the backend refusing to resolve
565
+ * what was typed (`INVALID_INPUT`), and every other code — offline, signed
566
+ * out, refused — is `"failed"`. A person can fix only one of them.
567
+ */
568
+ type ContactsAddError = "unresolved" | "failed";
569
+ interface ContactsSummarySlice {
570
+ readonly total: number | null;
571
+ readonly activeCount: number | null;
572
+ readonly isLoading: boolean;
573
+ readonly reason: ContactsRefusal | null;
574
+ }
575
+ interface ContactsListSlice {
576
+ readonly rows: readonly ContactRow[];
577
+ readonly isLoading: boolean;
578
+ readonly reason: ContactsRefusal | null;
579
+ }
580
+ interface ContactsListOptions {
581
+ readonly limit?: number | undefined;
582
+ /** `"all"` forwards `includeHidden` to the backend, which already accepts it. */
583
+ readonly show?: "visible" | "all" | undefined;
584
+ }
585
+ interface ContactsAddSlice {
586
+ readonly value: string;
587
+ readonly change: (text: string) => void;
588
+ readonly submit: () => void;
589
+ readonly isSubmitting: boolean;
590
+ readonly blocked: boolean;
591
+ readonly blockedReason: ContactsAddBlockedReason | null;
592
+ readonly error: ContactsAddError | null;
593
+ }
594
+ //#endregion
595
+ //#region src/headless/contacts/contacts.d.ts
596
+ interface CapxulContactsProps {
597
+ readonly actor: ContactsActor;
598
+ readonly onAdded: (contact: Contact) => void;
599
+ /** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
600
+ readonly onFailed: (error: CapxulError) => void;
601
+ readonly children: ReactNode;
602
+ }
603
+ declare function Root$1({
604
+ actor,
605
+ onAdded,
606
+ onFailed,
607
+ children
608
+ }: CapxulContactsProps): import("react/jsx-runtime").JSX.Element;
609
+ declare function Summary({
610
+ children
611
+ }: {
612
+ readonly children: (slice: ContactsSummarySlice) => ReactNode;
613
+ }): import("react/jsx-runtime").JSX.Element;
614
+ declare function List({
615
+ limit,
616
+ show,
617
+ children
618
+ }: ContactsListOptions & {
619
+ readonly children: (slice: ContactsListSlice) => ReactNode;
620
+ }): import("react/jsx-runtime").JSX.Element;
621
+ declare function Add({
622
+ children
623
+ }: {
624
+ readonly children: (slice: ContactsAddSlice) => ReactNode;
625
+ }): import("react/jsx-runtime").JSX.Element;
626
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
627
+ declare const CapxulContacts: typeof Root$1 & {
628
+ Summary: typeof Summary;
629
+ List: typeof List;
630
+ Add: typeof Add;
631
+ };
632
+ //#endregion
633
+ //#region src/headless/send-money/use-recipient-resolution.d.ts
634
+ type SendMoneyRecipientMethod = "username" | "email-address";
635
+ type SendMoneyRecipientStatus = "empty" | "checking" | "found" | "not-found" | "failed";
636
+ interface SendMoneyRecipientSlice {
637
+ readonly method: SendMoneyRecipientMethod;
638
+ readonly setMethod: (method: SendMoneyRecipientMethod) => void;
639
+ readonly value: string;
640
+ readonly change: (text: string) => void;
641
+ /** ADR-0023 R1: the status IS the failure code; the app owns the sentence. */
642
+ readonly status: SendMoneyRecipientStatus;
643
+ readonly label: string | null;
644
+ }
645
+ //#endregion
646
+ //#region src/headless/send-money/use-send-money.d.ts
647
+ type SendActor = {
648
+ readonly kind: "personal";
649
+ } | {
650
+ readonly kind: "organization";
651
+ readonly orgId: OrgId$1 | undefined;
652
+ };
653
+ type SentPayment = {
654
+ /** The backend payment row. */readonly payment: Payment; /** What we parsed and sent — `.value` is the comma-stripped major-unit string. */
655
+ readonly amount: Money; /** The trimmed text the person typed — the app's success toast interpolates it. */
656
+ readonly recipient: string;
657
+ };
658
+ /**
659
+ * Refusal CODES, never sentences (#1447 ruling 8). The app maps each code to
660
+ * the words it already prints; no English refusal string ships from here.
661
+ */
662
+ type CapxulSendMoneyBlockedReason = "signer-not-ready" | "amount-invalid" | "recipient-unresolved" | "no-source" | "no-asset";
663
+ interface SendMoneyAssetOption {
664
+ readonly id: string;
665
+ readonly symbol: string;
666
+ readonly availableDisplay: string;
667
+ }
668
+ /** ADR-0023 R1: a code, never a sentence — the app owns the words. */
669
+ type SendMoneyAssetError = "read-failed";
670
+ interface SendMoneyAssetSlice {
671
+ readonly options: ReadonlyArray<SendMoneyAssetOption>;
672
+ readonly selected: SendMoneyAssetOption | null;
673
+ readonly select: (id: string) => void;
674
+ readonly error: SendMoneyAssetError | null;
675
+ }
676
+ interface SendMoneyAmountSlice {
677
+ readonly value: string;
678
+ readonly change: (text: string) => void;
679
+ /** ADR-0023 R1: the parse verdict as a closed code; the app maps it to copy. */
680
+ readonly error: MoneyParseErrorReason | null;
681
+ readonly availableDisplay: string | null;
682
+ }
683
+ interface SendMoneyActionsSlice {
684
+ readonly submit: () => void;
685
+ readonly isSubmitting: boolean;
686
+ readonly blocked: boolean;
687
+ readonly blockedReason: CapxulSendMoneyBlockedReason | null;
688
+ }
689
+ //#endregion
690
+ //#region src/headless/send-money/send-money.d.ts
691
+ interface CapxulSendMoneyProps {
692
+ readonly actor: SendActor;
693
+ readonly onSent: (sent: SentPayment) => void;
694
+ /** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
695
+ readonly onFailed: (error: CapxulError) => void;
696
+ readonly children: ReactNode;
697
+ }
698
+ declare function Root({
699
+ actor,
700
+ onSent,
701
+ onFailed,
702
+ children
703
+ }: CapxulSendMoneyProps): import("react/jsx-runtime").JSX.Element;
704
+ declare function Asset({
705
+ children
706
+ }: {
707
+ readonly children: (slice: SendMoneyAssetSlice) => ReactNode;
708
+ }): import("react/jsx-runtime").JSX.Element;
709
+ declare function Amount({
710
+ children
711
+ }: {
712
+ readonly children: (slice: SendMoneyAmountSlice) => ReactNode;
713
+ }): import("react/jsx-runtime").JSX.Element;
714
+ declare function Recipient({
715
+ children
716
+ }: {
717
+ readonly children: (slice: SendMoneyRecipientSlice) => ReactNode;
718
+ }): import("react/jsx-runtime").JSX.Element;
719
+ declare function Actions({
720
+ children
721
+ }: {
722
+ readonly children: (slice: SendMoneyActionsSlice) => ReactNode;
723
+ }): import("react/jsx-runtime").JSX.Element;
724
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
725
+ declare const CapxulSendMoney: typeof Root & {
726
+ Asset: typeof Asset;
727
+ Amount: typeof Amount;
728
+ Recipient: typeof Recipient;
729
+ Actions: typeof Actions;
730
+ };
731
+ //#endregion
732
+ export { type AccountFailure, type AccountProgress, type ActionResult, type AuthenticatedState, type AuthenticationSlots, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulOnboardingController, 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 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 OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, 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 SendResult, type SentPayment, type SignedOutState, type Slot, 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, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, 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 };
package/dist/index.mjs CHANGED
@@ -1,166 +1,9 @@
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-Chqyy3HR.mjs";
3
- import { useEffect, useState } from "react";
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-ClhmseFL.mjs";
3
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
- import { fingerprintPaymentIntent } from "@capxul/sdk";
6
- //#region ../errors/src/errors.ts
7
- const CAPXUL_ERROR_CODES = [
8
- "NOT_AUTHENTICATED",
9
- "EMAIL_DELIVERY_FAILED",
10
- "PROFILE_NOT_FOUND",
11
- "SMART_ACCOUNT_MISSING",
12
- "PLAYER_NOT_FOUND",
13
- "ACCOUNT_NOT_FOUND",
14
- "PROVIDER_ERROR",
15
- "CAPABILITY_UNAVAILABLE",
16
- "INVALID_INPUT",
17
- "ENV_MISSING",
18
- "NOT_IMPLEMENTED",
19
- "VERIFICATION_REQUIRED",
20
- "INSUFFICIENT_BALANCE",
21
- "INVALID_RECIPIENT",
22
- "ROLE_PERMISSION_DENIED",
23
- "TRANSACTION_FAILED",
24
- "RATE_LIMITED",
25
- "NETWORK_ERROR",
26
- "UNKNOWN",
27
- "OTP_EXPIRED",
28
- "SIGNER_REJECTED",
29
- "CANCELLED",
30
- "WRONG_STATE",
31
- "STALE_EPOCH",
32
- "SUPERSEDED",
33
- "WORK_DIED",
34
- "ACTOR_STOPPED"
35
- ];
36
- var CapxulError$1 = class extends Error {
37
- code;
38
- details;
39
- correlationId;
40
- layer;
41
- constructor(code, message, options = {}) {
42
- super(message, "cause" in options ? { cause: options.cause } : void 0);
43
- this.name = "CapxulError";
44
- this.code = code;
45
- if (options.details !== void 0) this.details = options.details;
46
- if (options.correlationId !== void 0) this.correlationId = options.correlationId;
47
- if (options.layer !== void 0) this.layer = options.layer;
48
- }
49
- };
50
- const Errors = {
51
- notAuthenticated: (message, opts) => new CapxulError$1("NOT_AUTHENTICATED", message ?? "Not authenticated", opts?.failure_mode ? { details: { failure_mode: opts.failure_mode } } : void 0),
52
- emailDeliveryFailed: (detail) => new CapxulError$1("EMAIL_DELIVERY_FAILED", "Failed to send email", { details: { detail } }),
53
- profileNotFound: (authUserId) => new CapxulError$1("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`, { details: { authUserId } }),
54
- smartAccountMissing: (authUserId) => new CapxulError$1("SMART_ACCOUNT_MISSING", "Smart account not provisioned", { details: { authUserId } }),
55
- playerNotFound: (playerId) => new CapxulError$1("PLAYER_NOT_FOUND", playerId ? `Openfort player ${playerId} not found` : "Openfort player not found", playerId === void 0 ? void 0 : { details: { playerId } }),
56
- accountNotFound: (accountId) => new CapxulError$1("ACCOUNT_NOT_FOUND", accountId ? `Openfort account ${accountId} not found` : "Openfort account not found", accountId === void 0 ? void 0 : { details: { accountId } }),
57
- providerError: (provider, operation, cause, opts) => {
58
- const details = {
59
- provider,
60
- operation
61
- };
62
- if (opts?.failure_mode) details.failure_mode = opts.failure_mode;
63
- return new CapxulError$1("PROVIDER_ERROR", `Provider error: ${provider} ${operation}`, {
64
- cause,
65
- details
66
- });
67
- },
68
- capabilityUnavailable: (provider, operation) => new CapxulError$1("CAPABILITY_UNAVAILABLE", "Provider capability is unavailable", { details: {
69
- provider,
70
- operation
71
- } }),
72
- invalidInput: (field, reason) => new CapxulError$1("INVALID_INPUT", `Invalid ${field}: ${reason}`, { details: {
73
- field,
74
- reason
75
- } }),
76
- envMissing: (name) => new CapxulError$1("ENV_MISSING", `Environment variable ${name} not configured`, { details: { name } }),
77
- notImplemented: (domain, method) => new CapxulError$1("NOT_IMPLEMENTED", `${domain}.${method} is not yet implemented. This feature is planned for a future release.`, { details: {
78
- domain,
79
- method
80
- } }),
81
- /**
82
- * Sibling factory to {@link Errors.providerError} for the per-state timeout
83
- * path in flows. Same `PROVIDER_ERROR` code as
84
- * `providerError`, plus a `details.reason: "timeout"` discriminator so
85
- * downstream observers can distinguish failure modes without parsing the
86
- * message string. The redacted message names the timeout budget; the
87
- * native `cause` carries the same information for `reportError` fidelity.
88
- */
89
- providerTimeout: (provider, operation, timeoutMs) => new CapxulError$1("PROVIDER_ERROR", `Provider error: ${provider} ${operation} (timeout exceeded ${timeoutMs}ms)`, {
90
- details: {
91
- provider,
92
- operation,
93
- reason: "timeout"
94
- },
95
- cause: /* @__PURE__ */ new Error(`timeout: ${operation} exceeded ${timeoutMs}ms`)
96
- }),
97
- verificationRequired: (details) => {
98
- return new CapxulError$1("VERIFICATION_REQUIRED", "rail" in details ? `Verification is required before ${details.rail} can use ${details.currentKind}.` : `Verification tier ${details.requiredTier} is required.`, { details });
99
- },
100
- insufficientBalance: (asset, available, required) => new CapxulError$1("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, { details: {
101
- asset,
102
- available,
103
- required
104
- } }),
105
- invalidRecipient: (reason) => new CapxulError$1("INVALID_RECIPIENT", `Invalid recipient: ${reason}`, { details: { reason } }),
106
- /**
107
- * The org Zodiac Roles modifier REFUSED the spend on-chain (G4 · #547): the
108
- * member's role condition (per-tx cap, per-day allowance, allowed recipient,
109
- * or membership) was violated, so `execTransactionWithRole` reverted. This is
110
- * a PERMISSION denial — explicitly NOT an `INSUFFICIENT_BALANCE` (the treasury
111
- * held the funds; the role's authority is what bound). `reason` discriminates
112
- * the violated condition (`over_cap` / `daily_cap` / `not_member` /
113
- * `disallowed_recipient` / `condition_violation`); leak-safe — no on-chain
114
- * identifiers ever enter the details.
115
- */
116
- rolePermissionDenied: (details) => new CapxulError$1("ROLE_PERMISSION_DENIED", `Org role denied this spend on-chain (${details.reason}).`, { details: details.operation === void 0 ? { reason: details.reason } : {
117
- reason: details.reason,
118
- operation: details.operation
119
- } }),
120
- /**
121
- * A transaction (or sponsored UserOp) failed. `details.reason` discriminates
122
- * the failure mode for callers that must distinguish a CONFIRMED on-chain
123
- * revert (`"onchain_revert"` — the op executed and reverted, e.g. a Zodiac
124
- * Roles condition violation) from an inconclusive infra failure. A confirmed
125
- * revert is the ONLY mode the org spend port may map to a roles denial.
126
- */
127
- transactionFailed: (operation, cause, extra) => new CapxulError$1("TRANSACTION_FAILED", `Transaction failed: ${operation}`, {
128
- cause,
129
- details: extra?.reason === void 0 ? { operation } : {
130
- operation,
131
- reason: extra.reason
132
- }
133
- }),
134
- rateLimited: (details) => new CapxulError$1("RATE_LIMITED", "Rate limit exceeded", details === void 0 ? void 0 : { details: { ...details } }),
135
- networkError: (operation, cause) => new CapxulError$1("NETWORK_ERROR", `Network error during ${operation}`, {
136
- cause,
137
- details: { operation }
138
- }),
139
- unknown: (cause) => new CapxulError$1("UNKNOWN", "Unknown error", { cause }),
140
- otpExpired: (details) => new CapxulError$1("OTP_EXPIRED", "Verification code has expired. Request a new one.", details === void 0 ? void 0 : { details: { ...details } }),
141
- signerRejected: (details) => new CapxulError$1("SIGNER_REJECTED", "Signer rejected the request.", {
142
- cause: details.cause,
143
- details: details.reason === void 0 ? { source: details.source } : {
144
- source: details.source,
145
- reason: details.reason
146
- }
147
- }),
148
- cancelled: (details) => new CapxulError$1("CANCELLED", "Operation was cancelled.", details === void 0 ? void 0 : { details: { ...details } }),
149
- /**
150
- * Method called from a flow state where its precondition fails (TA16). The
151
- * SDK's method API short-circuits with this error before driving the
152
- * internal state machine. `currentState` is the Effect-machine snapshot
153
- * tag (stringified from the SDK's actor-shell snapshot; see
154
- * `packages/errors/CONTEXT.md`); `validStates`
155
- * enumerates the states the method accepts.
156
- */
157
- wrongState: (details) => new CapxulError$1("WRONG_STATE", `${details.method} called from state '${details.currentState}'; valid states: ${details.validStates.join(", ")}`, { details: {
158
- ...details,
159
- validStates: [...details.validStates]
160
- } })
161
- };
162
- new Set(CAPXUL_ERROR_CODES);
163
- //#endregion
5
+ import { Errors, fingerprintPaymentIntent, formatMoney, isMoneyParseError, parseMoney } from "@capxul/sdk";
6
+ import { Fragment, jsx } from "react/jsx-runtime";
164
7
  //#region src/internal/require-bootstrapped-client.ts
165
8
  /**
166
9
  * Narrow the bootstrap-nullable client to a ready client inside a query /
@@ -182,12 +25,10 @@ function requireBootstrappedClient(client, method) {
182
25
  * Unwrap a `CapxulResult` for TanStack query/mutation functions and throw into
183
26
  * React Query's error path.
184
27
  *
185
- * Failure observation belongs to the core SDK method boundary. The legacy
186
- * telemetry/operation arguments remain temporarily source-compatible with the
187
- * existing hook call sites, but are deliberately ignored so React cannot
28
+ * Failure observation belongs to the core SDK method boundary. React does not
188
29
  * report the same logical failure a second time.
189
30
  */
190
- function unwrapCapxulResult(result, _legacyTelemetry, _legacyOperation = "query") {
31
+ function unwrapCapxulResult(result) {
191
32
  if (result.ok) return result.value;
192
33
  throw result.error;
193
34
  }
@@ -198,7 +39,7 @@ function useCapxulProfile() {
198
39
  const identity = useCapxulIdentityOrNull();
199
40
  return useQuery({
200
41
  queryKey: capxulKeys.profile,
201
- queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "identity.loadCurrent").identity.loadCurrent(), client._internal.telemetry),
42
+ queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "identity.loadCurrent").identity.loadCurrent()),
202
43
  enabled: client !== null && identity?.phase === "authenticated"
203
44
  });
204
45
  }
@@ -209,8 +50,7 @@ function useCapxulAccountBalance(options) {
209
50
  return useQuery({
210
51
  queryKey: capxulKeys.accountBalance,
211
52
  queryFn: async () => {
212
- const bootstrappedClient = requireBootstrappedClient(client, "accounts.read");
213
- return unwrapCapxulResult(await bootstrappedClient.accounts.read(), bootstrappedClient._internal.telemetry);
53
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "accounts.read").accounts.read());
214
54
  },
215
55
  enabled: client !== null && (options?.enabled ?? true)
216
56
  });
@@ -222,8 +62,7 @@ function useCapxulAccountFund() {
222
62
  const queryClient = useQueryClient();
223
63
  return useMutation({
224
64
  mutationFn: async (amount) => {
225
- const bootstrappedClient = requireBootstrappedClient(client, "_internal.accounts.fund");
226
- return unwrapCapxulResult(await bootstrappedClient._internal.accounts.fund(amount), bootstrappedClient._internal.telemetry, "mutation");
65
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "_internal.accounts.fund")._internal.accounts.fund(amount));
227
66
  },
228
67
  onSuccess: async () => {
229
68
  await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
@@ -255,7 +94,7 @@ async function storageKey(operation, intent) {
255
94
  }
256
95
  function paymentLockManager() {
257
96
  const manager = navigator.locks;
258
- if (manager === void 0 || typeof manager.query !== "function") throw new Error("Web Locks are required for payment request keys");
97
+ if (manager === void 0 || typeof manager.query !== "function") throw Errors.providerError("sdk-react", "paymentRequestKey", /* @__PURE__ */ new Error("Web Locks are required for payment request keys"));
259
98
  return manager;
260
99
  }
261
100
  function attemptLockName(storageSlot, attemptId) {
@@ -299,14 +138,14 @@ function readState(key) {
299
138
  const stored = localStorage.getItem(key);
300
139
  if (stored === null) return null;
301
140
  const state = JSON.parse(stored);
302
- if (typeof state.key !== "string" || !Array.isArray(state.active) || state.active.some((attempt) => typeof attempt !== "string") || typeof state.resolved !== "boolean") throw new TypeError("Invalid payment request key state");
141
+ if (typeof state.key !== "string" || !Array.isArray(state.active) || state.active.some((attempt) => typeof attempt !== "string") || typeof state.resolved !== "boolean") throw Errors.providerError("sdk-react", "paymentRequestKey", /* @__PURE__ */ new TypeError("Invalid payment request key state"));
303
142
  return state;
304
143
  }
305
144
  async function beginPaymentRequestKey(operation, intent) {
306
- const storageSlot = await storageKey(operation, intent);
307
145
  let releaseAttemptLock;
308
146
  let forgetPagehideRelease;
309
147
  try {
148
+ const storageSlot = await storageKey(operation, intent);
310
149
  const attemptId = `attempt_${crypto.randomUUID()}`;
311
150
  releaseAttemptLock = await holdAttemptLock(attemptLockName(storageSlot, attemptId));
312
151
  forgetPagehideRelease = releaseAttemptOnPagehide(releaseAttemptLock);
@@ -408,7 +247,7 @@ function useCapxulPay() {
408
247
  }, async (requestKey) => unwrapCapxulResult(await bootstrappedClient.payments.pay({
409
248
  ...input,
410
249
  requestKey
411
- }), bootstrappedClient._internal.telemetry, "mutation"));
250
+ })));
412
251
  },
413
252
  onSuccess: async (payment) => {
414
253
  await invalidateMoneyState(queryClient, {
@@ -423,8 +262,7 @@ function useCapxulCreateCommitment() {
423
262
  const queryClient = useQueryClient();
424
263
  return useMutation({
425
264
  mutationFn: async (input) => {
426
- const bootstrapped = requireBootstrappedClient(client, "payments.createCommitment");
427
- return unwrapCapxulResult(await bootstrapped.payments.createCommitment(input), bootstrapped._internal.telemetry, "mutation");
265
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.createCommitment").payments.createCommitment(input));
428
266
  },
429
267
  onSuccess: (payment) => invalidateMoneyState(queryClient, {
430
268
  actor: { kind: "personal" },
@@ -437,8 +275,7 @@ function usePaymentIdMutation(method) {
437
275
  const queryClient = useQueryClient();
438
276
  return useMutation({
439
277
  mutationFn: async (paymentId) => {
440
- const bootstrapped = requireBootstrappedClient(client, `payments.${method}`);
441
- return unwrapCapxulResult(await bootstrapped.payments[method](paymentId), bootstrapped._internal.telemetry, "mutation");
278
+ return unwrapCapxulResult(await requireBootstrappedClient(client, `payments.${method}`).payments[method](paymentId));
442
279
  },
443
280
  onSuccess: (payment) => invalidateMoneyState(queryClient, {
444
281
  actor: { kind: "personal" },
@@ -453,8 +290,7 @@ function useCapxulRedirectPayment() {
453
290
  const queryClient = useQueryClient();
454
291
  return useMutation({
455
292
  mutationFn: async (input) => {
456
- const bootstrapped = requireBootstrappedClient(client, "payments.redirect");
457
- return unwrapCapxulResult(await bootstrapped.payments.redirect(input), bootstrapped._internal.telemetry, "mutation");
293
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.redirect").payments.redirect(input));
458
294
  },
459
295
  onSuccess: (payment) => invalidateMoneyState(queryClient, {
460
296
  actor: { kind: "personal" },
@@ -468,8 +304,7 @@ function useCapxulPayments(options) {
468
304
  return useQuery({
469
305
  queryKey: capxulKeys.payments,
470
306
  queryFn: async () => {
471
- const bootstrappedClient = requireBootstrappedClient(client, "payments.list");
472
- return unwrapCapxulResult(await bootstrappedClient.payments.list(), bootstrappedClient._internal.telemetry);
307
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.list").payments.list());
473
308
  },
474
309
  enabled: client !== null && identity?.phase === "authenticated" && identity.account.at === "claimed" && (options?.enabled ?? true)
475
310
  });
@@ -480,8 +315,7 @@ function useCapxulPayment(paymentId, options) {
480
315
  queryKey: capxulKeys.payment(paymentId),
481
316
  queryFn: async () => {
482
317
  if (paymentId === void 0) throw Errors.invalidInput("paymentId", "required for payments.get");
483
- const bootstrappedClient = requireBootstrappedClient(client, "payments.get");
484
- return unwrapCapxulResult(await bootstrappedClient.payments.get(paymentId), bootstrappedClient._internal.telemetry);
318
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "payments.get").payments.get(paymentId));
485
319
  },
486
320
  enabled: client !== null && paymentId !== void 0 && (options?.enabled ?? true)
487
321
  });
@@ -502,7 +336,7 @@ function useCapxulOrganizationPay(orgId) {
502
336
  }, async (requestKey) => unwrapCapxulResult(await bootstrapped.org(orgId).payments.pay({
503
337
  ...input,
504
338
  requestKey
505
- }), bootstrapped._internal.telemetry, "mutation"));
339
+ })));
506
340
  },
507
341
  onSuccess: async (payment) => {
508
342
  return invalidateMoneyState(queryClient, {
@@ -529,7 +363,7 @@ function useCapxulOrganizationPayBatch(orgId) {
529
363
  }, async (requestKey) => unwrapCapxulResult(await bootstrapped.org(orgId).payments.payBatch({
530
364
  ...input,
531
365
  requestKey
532
- }), bootstrapped._internal.telemetry, "mutation"));
366
+ })));
533
367
  },
534
368
  onSuccess: async (payments) => {
535
369
  return Promise.all(payments.map((payment) => invalidateMoneyState(queryClient, {
@@ -549,9 +383,8 @@ function usePermissionMutation(orgId, operation) {
549
383
  const queryClient = useQueryClient();
550
384
  return useMutation({
551
385
  mutationFn: async (input) => {
552
- const bootstrapped = requireBootstrappedClient(client, `permissions.${operation}`);
553
- const method = bootstrapped.org(orgId).permissions[operation];
554
- return unwrapCapxulResult(await method(input), bootstrapped._internal.telemetry, "mutation");
386
+ const method = requireBootstrappedClient(client, `permissions.${operation}`).org(orgId).permissions[operation];
387
+ return unwrapCapxulResult(await method(input));
555
388
  },
556
389
  onSuccess: () => queryClient.invalidateQueries({ queryKey: capxulKeys.orgPermissions(orgId) })
557
390
  });
@@ -566,8 +399,7 @@ function useCapxulPermissions(orgId, options) {
566
399
  return useQuery({
567
400
  queryKey: capxulKeys.orgPermissions(orgId),
568
401
  queryFn: async () => {
569
- const bootstrapped = requireBootstrappedClient(client, "permissions.list");
570
- return unwrapCapxulResult(await bootstrapped.org(orgId).permissions.list(), bootstrapped._internal.telemetry);
402
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "permissions.list").org(orgId).permissions.list());
571
403
  },
572
404
  enabled: client !== null && (options?.enabled ?? true)
573
405
  });
@@ -577,9 +409,8 @@ function useCapxulPermission(orgId, permissionId) {
577
409
  return useQuery({
578
410
  queryKey: [...capxulKeys.orgPermissions(orgId), permissionId ?? "pending"],
579
411
  queryFn: async () => {
580
- if (permissionId === void 0) throw new Error("permissionId is required");
581
- const bootstrapped = requireBootstrappedClient(client, "permissions.get");
582
- return unwrapCapxulResult(await bootstrapped.org(orgId).permissions.get(permissionId), bootstrapped._internal.telemetry);
412
+ if (permissionId === void 0) throw Errors.invalidInput("permissionId", "required for permissions.get");
413
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "permissions.get").org(orgId).permissions.get(permissionId));
583
414
  },
584
415
  enabled: client !== null && permissionId !== void 0
585
416
  });
@@ -592,8 +423,7 @@ function useCapxulActivity(params) {
592
423
  return useQuery({
593
424
  queryKey: [...capxulKeys.activity, params ?? {}],
594
425
  queryFn: async () => {
595
- const bootstrapped = requireBootstrappedClient(client, "activity.list");
596
- return unwrapCapxulResult(await bootstrapped.activity.list(params), bootstrapped._internal.telemetry);
426
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.list").activity.list(params));
597
427
  },
598
428
  enabled: client !== null && identity?.phase === "authenticated" && identity.account.at === "claimed"
599
429
  });
@@ -604,9 +434,8 @@ function useCapxulActivityDetail(reference) {
604
434
  return useQuery({
605
435
  queryKey: capxulKeys.activityDetail(reference),
606
436
  queryFn: async () => {
607
- if (reference === void 0) throw new Error("activity reference is required");
608
- const bootstrapped = requireBootstrappedClient(client, "activity.get");
609
- return unwrapCapxulResult(await bootstrapped.activity.get(reference), bootstrapped._internal.telemetry);
437
+ if (reference === void 0) throw Errors.invalidInput("reference", "required for activity.get");
438
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.get").activity.get(reference));
610
439
  },
611
440
  enabled: client !== null && reference !== void 0 && identity?.phase === "authenticated" && identity.account.at === "claimed"
612
441
  });
@@ -616,8 +445,7 @@ function useCapxulAnnotateMovement() {
616
445
  const queryClient = useQueryClient();
617
446
  return useMutation({
618
447
  mutationFn: async (input) => {
619
- const bootstrapped = requireBootstrappedClient(client, "activity.annotate");
620
- return unwrapCapxulResult(await bootstrapped.activity.annotate(input), bootstrapped._internal.telemetry, "mutation");
448
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "activity.annotate").activity.annotate(input));
621
449
  },
622
450
  onSuccess: () => queryClient.invalidateQueries({ queryKey: capxulKeys.activity })
623
451
  });
@@ -630,8 +458,7 @@ function useCapxulHoldings() {
630
458
  return useQuery({
631
459
  queryKey: capxulKeys.holdings,
632
460
  queryFn: async () => {
633
- const bootstrapped = requireBootstrappedClient(client, "holdings.current");
634
- return unwrapCapxulResult(await bootstrapped.holdings.current(), bootstrapped._internal.telemetry);
461
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "holdings.current").holdings.current());
635
462
  },
636
463
  enabled: client !== null && identity?.phase === "authenticated" && identity.account.at === "claimed"
637
464
  });
@@ -643,8 +470,7 @@ function useCapxulOrgs(options) {
643
470
  return useQuery({
644
471
  queryKey: capxulKeys.orgs,
645
472
  queryFn: async () => {
646
- const bootstrappedClient = requireBootstrappedClient(client, "orgs");
647
- return unwrapCapxulResult(await bootstrappedClient.orgs(), bootstrappedClient._internal.telemetry);
473
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "orgs").orgs());
648
474
  },
649
475
  enabled: client !== null && (options?.enabled ?? true)
650
476
  });
@@ -658,8 +484,7 @@ function useCapxulOrgMembers(orgId, options) {
658
484
  queryKey: capxulKeys.orgMembers(orgId),
659
485
  queryFn: async () => {
660
486
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgMembers");
661
- const bootstrappedClient = requireBootstrappedClient(client, "org.members");
662
- return unwrapCapxulResult(await bootstrappedClient.org(orgId).members(), bootstrappedClient._internal.telemetry);
487
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "org.members").org(orgId).members());
663
488
  },
664
489
  enabled: client !== null && enabled && orgId !== void 0
665
490
  });
@@ -673,8 +498,7 @@ function useCapxulOrgRoles(orgId, options) {
673
498
  queryKey: capxulKeys.orgRoles(orgId),
674
499
  queryFn: async () => {
675
500
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgRoles");
676
- const bootstrappedClient = requireBootstrappedClient(client, "org.roles");
677
- return unwrapCapxulResult(await bootstrappedClient.org(orgId).roles(), bootstrappedClient._internal.telemetry);
501
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "org.roles").org(orgId).roles());
678
502
  },
679
503
  enabled: client !== null && enabled && orgId !== void 0
680
504
  });
@@ -688,8 +512,7 @@ function useCapxulOrgTreasury(orgId, options) {
688
512
  queryKey: capxulKeys.orgTreasury(orgId),
689
513
  queryFn: async () => {
690
514
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgTreasury");
691
- const bootstrappedClient = requireBootstrappedClient(client, "org.treasury");
692
- return unwrapCapxulResult(await bootstrappedClient.org(orgId).treasury(), bootstrappedClient._internal.telemetry);
515
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "org.treasury").org(orgId).treasury());
693
516
  },
694
517
  enabled: client !== null && enabled && orgId !== void 0
695
518
  });
@@ -701,8 +524,7 @@ function useCapxulCreateOrg() {
701
524
  const queryClient = useQueryClient();
702
525
  return useMutation({
703
526
  mutationFn: async (input) => {
704
- const bootstrappedClient = requireBootstrappedClient(client, "createOrg");
705
- return unwrapCapxulResult(await bootstrappedClient.createOrg(input), bootstrappedClient._internal.telemetry, "mutation");
527
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "createOrg").createOrg(input));
706
528
  },
707
529
  onSuccess: async () => {
708
530
  await queryClient.invalidateQueries({ queryKey: capxulKeys.orgs });
@@ -717,8 +539,7 @@ function useCapxulInviteMember(orgId) {
717
539
  return useMutation({
718
540
  mutationFn: async (input) => {
719
541
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulInviteMember");
720
- const bootstrappedClient = requireBootstrappedClient(client, "org.invite");
721
- return unwrapCapxulResult(await bootstrappedClient.org(orgId).invite(input), bootstrappedClient._internal.telemetry, "mutation");
542
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "org.invite").org(orgId).invite(input));
722
543
  },
723
544
  onSuccess: async () => {
724
545
  if (orgId === void 0) return;
@@ -973,8 +794,7 @@ function useCapxulUsernameAvailability(username, options) {
973
794
  return useQuery({
974
795
  queryKey: capxulKeys.usernameAvailability(candidate),
975
796
  queryFn: async () => {
976
- const bootstrappedClient = requireBootstrappedClient(client, "identity.usernameAvailable");
977
- return unwrapCapxulResult(await bootstrappedClient.identity.usernameAvailable(candidate), bootstrappedClient._internal.telemetry);
797
+ return unwrapCapxulResult(await requireBootstrappedClient(client, "identity.usernameAvailable").identity.usernameAvailable(candidate));
978
798
  },
979
799
  enabled: client !== null && candidate.length >= 3 && (options?.enabled ?? true)
980
800
  });
@@ -992,15 +812,13 @@ function useCapxulImageUpload() {
992
812
  const queryClient = useQueryClient();
993
813
  return useMutation({
994
814
  mutationFn: async ({ blob, target }) => {
995
- const bootstrappedClient = requireBootstrappedClient(client, "media.uploadImage");
996
- const media = bootstrappedClient.media;
997
- const telemetry = bootstrappedClient._internal.telemetry;
998
- const uploaded = unwrapCapxulResult(await media.uploadImage(blob), telemetry);
999
- if (target.kind === "profile") return { url: unwrapCapxulResult(await media.setProfileImage({ storageId: uploaded.storageId }), telemetry).imageUrl };
815
+ const media = requireBootstrappedClient(client, "media.uploadImage").media;
816
+ const uploaded = unwrapCapxulResult(await media.uploadImage(blob));
817
+ if (target.kind === "profile") return { url: unwrapCapxulResult(await media.setProfileImage({ storageId: uploaded.storageId })).imageUrl };
1000
818
  return { url: unwrapCapxulResult(await media.setOrgLogo({
1001
819
  orgId: target.orgId,
1002
820
  storageId: uploaded.storageId
1003
- }), telemetry).logoUrl };
821
+ })).logoUrl };
1004
822
  },
1005
823
  onSuccess: async (_value, input) => {
1006
824
  await queryClient.invalidateQueries({ queryKey: input.target.kind === "profile" ? capxulKeys.profile : capxulKeys.orgs });
@@ -1008,4 +826,413 @@ function useCapxulImageUpload() {
1008
826
  });
1009
827
  }
1010
828
  //#endregion
1011
- export { CapxulAuthenticationController, CapxulOnboardingController, CapxulProvider, acknowledgeOnboardingDestination, activeOnboardingRecovery, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, 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 };
829
+ //#region src/headless/contacts/use-contacts.ts
830
+ function useContacts(input) {
831
+ const { actor, onAdded, onFailed } = input;
832
+ const client = useCapxulClientOrNull();
833
+ const queryClient = useQueryClient();
834
+ const orgId = actor.kind === "organization" ? actor.orgId : void 0;
835
+ const scope = actor.kind === "personal" ? "personal" : orgId ?? "pending";
836
+ const refusal = actor.kind === "organization" && orgId === void 0 ? "org-unavailable" : null;
837
+ const book = useMemo(() => addressBookOf(client, actor.kind, orgId), [
838
+ client,
839
+ actor.kind,
840
+ orgId
841
+ ]);
842
+ const invalidate = useCallback(() => queryClient.invalidateQueries({ queryKey: capxulKeys.contacts(scope) }), [queryClient, scope]);
843
+ const writeMutate = useMutation({
844
+ mutationFn: async (command) => {
845
+ const target = requireBook(book, `addressBook.${command.kind}`);
846
+ return unwrapCapxulResult(command.kind === "rename" ? await target.label({
847
+ entryId: command.id,
848
+ label: command.name
849
+ }) : command.kind === "hide" ? await target.hide(command.id) : await target.unhide(command.id));
850
+ },
851
+ onSettled: invalidate,
852
+ onError: onFailed
853
+ }).mutate;
854
+ const [value, setValue] = useState("");
855
+ const [addError, setAddError] = useState(null);
856
+ const addContact = useMutation({
857
+ mutationFn: async (ref) => unwrapCapxulResult(await requireBook(book, "addressBook.add").add({ ref })),
858
+ onSettled: invalidate
859
+ });
860
+ const addMutate = addContact.mutate;
861
+ const blockedReason = refusal !== null ? "org-unavailable" : value.trim() === "" ? "empty" : null;
862
+ const submitGate = useRef(false);
863
+ const submit = useCallback(() => {
864
+ if (blockedReason !== null || submitGate.current) return;
865
+ submitGate.current = true;
866
+ setAddError(null);
867
+ addMutate(refFromTypedText(value), {
868
+ onSuccess: (entry) => {
869
+ setValue("");
870
+ onAdded(toContact(entry));
871
+ },
872
+ onError: (error) => {
873
+ setAddError(error.code === "INVALID_INPUT" ? "unresolved" : "failed");
874
+ onFailed(error);
875
+ },
876
+ onSettled: () => {
877
+ submitGate.current = false;
878
+ }
879
+ });
880
+ }, [
881
+ addMutate,
882
+ blockedReason,
883
+ onAdded,
884
+ onFailed,
885
+ value
886
+ ]);
887
+ const change = useCallback((text) => {
888
+ setValue(text);
889
+ setAddError(null);
890
+ }, []);
891
+ return {
892
+ book,
893
+ scope,
894
+ refusal,
895
+ rename: useCallback((id, name) => writeMutate({
896
+ kind: "rename",
897
+ id,
898
+ name
899
+ }), [writeMutate]),
900
+ hide: useCallback((id) => writeMutate({
901
+ kind: "hide",
902
+ id
903
+ }), [writeMutate]),
904
+ unhide: useCallback((id) => writeMutate({
905
+ kind: "unhide",
906
+ id
907
+ }), [writeMutate]),
908
+ add: {
909
+ value,
910
+ change,
911
+ submit,
912
+ isSubmitting: addContact.isPending,
913
+ blocked: blockedReason !== null,
914
+ blockedReason,
915
+ error: addError
916
+ }
917
+ };
918
+ }
919
+ /**
920
+ * The read every part stands on. Two placements with the same `show` share one
921
+ * query key, so React Query issues ONE request for them.
922
+ */
923
+ function useContactsList(engine, options) {
924
+ const includeHidden = options.show === "all";
925
+ const { book, refusal } = engine;
926
+ const query = useQuery({
927
+ queryKey: capxulKeys.contactsList(engine.scope, includeHidden),
928
+ queryFn: async () => unwrapCapxulResult(await requireBook(book, "addressBook.list").list({ includeHidden })),
929
+ enabled: book !== null
930
+ });
931
+ const reason = refusal ?? (query.isError ? "unavailable" : query.data === void 0 ? "loading" : null);
932
+ const entries = query.data;
933
+ const { limit } = options;
934
+ const { rename, hide, unhide } = engine;
935
+ return {
936
+ rows: useMemo(() => {
937
+ if (entries === void 0) return [];
938
+ return (limit === void 0 ? entries : entries.slice(0, limit)).map((entry) => Object.assign(toContact(entry), {
939
+ initials: initialsOf(entry.label),
940
+ rename: (name) => rename(entry.id, name),
941
+ hide: () => hide(entry.id),
942
+ unhide: () => unhide(entry.id)
943
+ }));
944
+ }, [
945
+ entries,
946
+ hide,
947
+ limit,
948
+ rename,
949
+ unhide
950
+ ]),
951
+ isLoading: reason === "loading",
952
+ reason
953
+ };
954
+ }
955
+ /** Counts over the same visible read `.List` uses — one request, two parts. */
956
+ function useContactsSummary(engine) {
957
+ const { rows, isLoading, reason } = useContactsList(engine, {});
958
+ const settled = reason === null;
959
+ return {
960
+ total: settled ? rows.length : null,
961
+ activeCount: settled ? rows.filter((row) => row.relationship.includes("paid")).length : null,
962
+ isLoading,
963
+ reason
964
+ };
965
+ }
966
+ function addressBookOf(client, kind, orgId) {
967
+ if (client === null) return null;
968
+ if (kind === "personal") return client.account.addressBook;
969
+ return orgId === void 0 ? null : client.org(orgId).addressBook;
970
+ }
971
+ function requireBook(book, method) {
972
+ if (book === null) throw Errors.wrongState({
973
+ method,
974
+ currentState: "bootstrapping",
975
+ validStates: ["ready"]
976
+ });
977
+ return book;
978
+ }
979
+ function toContact(entry) {
980
+ return {
981
+ id: entry.id,
982
+ name: entry.label,
983
+ relationship: entry.relationship,
984
+ hidden: entry.hidden,
985
+ lastActivityAt: entry.lastActivityAt
986
+ };
987
+ }
988
+ /**
989
+ * One typed field, both shapes. A leading `@` names a handle; an `@` anywhere
990
+ * else names an email — what the app already builds for Quick Pay, and what the
991
+ * backend resolver already accepts.
992
+ */
993
+ function refFromTypedText(text) {
994
+ const trimmed = text.trim();
995
+ return trimmed.includes("@") && !trimmed.startsWith("@") ? {
996
+ kind: "email",
997
+ email: trimmed
998
+ } : {
999
+ kind: "handle",
1000
+ handle: trimmed.replace(/^@/, "")
1001
+ };
1002
+ }
1003
+ /** First letters of the first two words, uppercased. */
1004
+ function initialsOf(name) {
1005
+ return name.trim().split(/\s+/).slice(0, 2).map((word) => word.charAt(0).toUpperCase()).join("");
1006
+ }
1007
+ //#endregion
1008
+ //#region src/headless/contacts/contacts.tsx
1009
+ const ContactsContext = createContext(null);
1010
+ function useContactsContext() {
1011
+ const engine = useContext(ContactsContext);
1012
+ if (engine === null) throw new Error("CapxulContacts parts must be used inside <CapxulContacts>");
1013
+ return engine;
1014
+ }
1015
+ function Root$1({ actor, onAdded, onFailed, children }) {
1016
+ const engine = useContacts({
1017
+ actor,
1018
+ onAdded,
1019
+ onFailed
1020
+ });
1021
+ return /* @__PURE__ */ jsx(ContactsContext.Provider, {
1022
+ value: engine,
1023
+ children
1024
+ });
1025
+ }
1026
+ function Summary({ children }) {
1027
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useContactsSummary(useContactsContext())) });
1028
+ }
1029
+ function List({ limit, show, children }) {
1030
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useContactsList(useContactsContext(), {
1031
+ limit,
1032
+ show
1033
+ })) });
1034
+ }
1035
+ function Add({ children }) {
1036
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useContactsContext().add) });
1037
+ }
1038
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
1039
+ const CapxulContacts = Object.assign(Root$1, {
1040
+ Summary,
1041
+ List,
1042
+ Add
1043
+ });
1044
+ //#endregion
1045
+ //#region src/headless/send-money/signer-status.ts
1046
+ const NO_SUBSCRIPTION = () => () => {};
1047
+ function useSignerStatus(client) {
1048
+ const signer = client?.signer;
1049
+ return useSyncExternalStore(useMemo(() => signer === void 0 ? NO_SUBSCRIPTION : (listener) => signer.subscribe(listener), [signer]), () => signer === void 0 ? "unknown" : signer.status(), () => "unknown");
1050
+ }
1051
+ //#endregion
1052
+ //#region src/headless/send-money/use-recipient-resolution.ts
1053
+ function toTargetReference(method, text) {
1054
+ const trimmed = text.trim();
1055
+ if (trimmed === "") return null;
1056
+ return method === "username" ? {
1057
+ kind: "handle",
1058
+ handle: trimmed.replace(/^@/, "")
1059
+ } : {
1060
+ kind: "email",
1061
+ email: trimmed
1062
+ };
1063
+ }
1064
+ /** How long the engine waits after the last keystroke before resolving. */
1065
+ const RESOLVE_DEBOUNCE_MS = 400;
1066
+ function useRecipientResolution(client) {
1067
+ const [method, setMethodState] = useState("email-address");
1068
+ const [text, setText] = useState("");
1069
+ const reference = useMemo(() => toTargetReference(method, text), [method, text]);
1070
+ const debouncedReference = useDebouncedValue(reference, RESOLVE_DEBOUNCE_MS);
1071
+ const [outcome, setOutcome] = useState(null);
1072
+ useEffect(() => {
1073
+ if (debouncedReference === null || client === null) {
1074
+ setOutcome(null);
1075
+ return;
1076
+ }
1077
+ const controller = new AbortController();
1078
+ setOutcome({
1079
+ reference: debouncedReference,
1080
+ status: "checking",
1081
+ target: null
1082
+ });
1083
+ client.targets.resolve(debouncedReference, { signal: controller.signal }).then((result) => {
1084
+ if (controller.signal.aborted) return;
1085
+ setOutcome(result.ok ? {
1086
+ reference: debouncedReference,
1087
+ status: "found",
1088
+ target: result.value
1089
+ } : {
1090
+ reference: debouncedReference,
1091
+ status: result.error.code === "INVALID_INPUT" ? "not-found" : "failed",
1092
+ target: null
1093
+ });
1094
+ });
1095
+ return () => controller.abort();
1096
+ }, [client, debouncedReference]);
1097
+ const setMethod = useCallback((next) => {
1098
+ setMethodState(next);
1099
+ setText("");
1100
+ }, []);
1101
+ const settled = outcome !== null && outcome.reference === debouncedReference ? outcome : null;
1102
+ const status = reference === null ? "empty" : reference !== debouncedReference || settled === null ? "checking" : settled.status;
1103
+ const resolvedTarget = status === "found" ? settled?.target ?? null : null;
1104
+ return {
1105
+ slice: {
1106
+ method,
1107
+ setMethod,
1108
+ value: text,
1109
+ change: setText,
1110
+ status,
1111
+ label: resolvedTarget?.label ?? null
1112
+ },
1113
+ resolvedTarget,
1114
+ trimmed: text.trim()
1115
+ };
1116
+ }
1117
+ //#endregion
1118
+ //#region src/headless/send-money/use-send-money.ts
1119
+ function useSendMoney(input) {
1120
+ const { actor, onSent, onFailed } = input;
1121
+ const client = useCapxulClientOrNull();
1122
+ const signerStatus = useSignerStatus(client);
1123
+ const balance = useCapxulAccountBalance({ enabled: actor.kind === "personal" });
1124
+ const account = actor.kind === "personal" ? balance.data ?? null : null;
1125
+ const assetOptions = useMemo(() => account === null ? [] : [{
1126
+ id: account.id,
1127
+ symbol: account.available.currency,
1128
+ availableDisplay: formatMoney(account.available, { grammar: "code" })
1129
+ }], [account]);
1130
+ const [selectedAssetId, setSelectedAssetId] = useState(null);
1131
+ useEffect(() => {
1132
+ if (!assetOptions.some((option) => option.id === selectedAssetId)) setSelectedAssetId(assetOptions[0]?.id ?? null);
1133
+ }, [assetOptions, selectedAssetId]);
1134
+ const selectedAssetOption = assetOptions.find((option) => option.id === selectedAssetId) ?? null;
1135
+ const selectedAssetMoney = selectedAssetOption !== null && account !== null ? account.available : null;
1136
+ const selectAsset = useCallback((id) => {
1137
+ setSelectedAssetId((current) => assetOptions.some((option) => option.id === id) ? id : current);
1138
+ }, [assetOptions]);
1139
+ const [amountText, setAmountText] = useState("");
1140
+ const parsed = useMemo(() => selectedAssetMoney === null || amountText.trim() === "" ? null : parseMoney(amountText, selectedAssetMoney), [amountText, selectedAssetMoney]);
1141
+ const parsedMoney = parsed !== null && !isMoneyParseError(parsed) ? parsed : null;
1142
+ const amountError = parsed !== null && isMoneyParseError(parsed) ? parsed.reason : null;
1143
+ const recipient = useRecipientResolution(client);
1144
+ const resolvedTarget = recipient.resolvedTarget;
1145
+ const pay = useCapxulPay();
1146
+ const blockedReason = signerStatus !== "ready" ? "signer-not-ready" : actor.kind === "organization" ? "no-source" : selectedAssetOption === null ? "no-asset" : parsedMoney === null ? "amount-invalid" : resolvedTarget === null ? "recipient-unresolved" : null;
1147
+ const submitGate = useRef(false);
1148
+ const submit = useCallback(() => {
1149
+ if (blockedReason !== null || submitGate.current) return;
1150
+ if (parsedMoney === null || resolvedTarget === null) return;
1151
+ submitGate.current = true;
1152
+ const amount = parsedMoney;
1153
+ const sentRecipient = recipient.trimmed;
1154
+ pay.mutate({
1155
+ to: resolvedTarget.reference,
1156
+ amount
1157
+ }, {
1158
+ onSuccess: (payment) => onSent({
1159
+ payment,
1160
+ amount,
1161
+ recipient: sentRecipient
1162
+ }),
1163
+ onError: (error) => onFailed(error),
1164
+ onSettled: () => {
1165
+ submitGate.current = false;
1166
+ }
1167
+ });
1168
+ }, [
1169
+ blockedReason,
1170
+ onFailed,
1171
+ onSent,
1172
+ parsedMoney,
1173
+ pay,
1174
+ recipient.trimmed,
1175
+ resolvedTarget
1176
+ ]);
1177
+ return {
1178
+ asset: {
1179
+ options: assetOptions,
1180
+ selected: selectedAssetOption,
1181
+ select: selectAsset,
1182
+ error: actor.kind === "personal" && balance.error !== null ? "read-failed" : null
1183
+ },
1184
+ amount: {
1185
+ value: amountText,
1186
+ change: setAmountText,
1187
+ error: amountError,
1188
+ availableDisplay: selectedAssetOption?.availableDisplay ?? null
1189
+ },
1190
+ recipient: recipient.slice,
1191
+ actions: {
1192
+ submit,
1193
+ isSubmitting: pay.isPending,
1194
+ blocked: blockedReason !== null,
1195
+ blockedReason
1196
+ }
1197
+ };
1198
+ }
1199
+ //#endregion
1200
+ //#region src/headless/send-money/send-money.tsx
1201
+ const SendMoneyContext = createContext(null);
1202
+ function useSendMoneyContext() {
1203
+ const engine = useContext(SendMoneyContext);
1204
+ if (engine === null) throw new Error("CapxulSendMoney parts must be used inside <CapxulSendMoney>");
1205
+ return engine;
1206
+ }
1207
+ function Root({ actor, onSent, onFailed, children }) {
1208
+ const engine = useSendMoney({
1209
+ actor,
1210
+ onSent,
1211
+ onFailed
1212
+ });
1213
+ return /* @__PURE__ */ jsx(SendMoneyContext.Provider, {
1214
+ value: engine,
1215
+ children
1216
+ });
1217
+ }
1218
+ function Asset({ children }) {
1219
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().asset) });
1220
+ }
1221
+ function Amount({ children }) {
1222
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().amount) });
1223
+ }
1224
+ function Recipient({ children }) {
1225
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().recipient) });
1226
+ }
1227
+ function Actions({ children }) {
1228
+ return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().actions) });
1229
+ }
1230
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
1231
+ const CapxulSendMoney = Object.assign(Root, {
1232
+ Asset,
1233
+ Amount,
1234
+ Recipient,
1235
+ Actions
1236
+ });
1237
+ //#endregion
1238
+ export { CapxulAuthenticationController, CapxulContacts, CapxulOnboardingController, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, 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 };
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-Chqyy3HR.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-ClhmseFL.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": "2.1.0",
3
+ "version": "2.2.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": "2.1.0"
29
+ "@capxul/sdk": "2.2.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",