@capxul/sdk-react 0.2.0-alpha.4 → 1.0.0-alpha.6

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 DELETED
@@ -1,187 +0,0 @@
1
- # @capxul/sdk-react
2
-
3
- React provider + hooks for Capxul. Wraps [`@capxul/sdk`](https://www.npmjs.com/package/@capxul/sdk)
4
- in a synchronously-mounting provider with lazy bootstrap and a
5
- discriminated-union return shape on every read hook.
6
-
7
- > **Alpha — `0.x` is pre-release.** APIs can change between alpha
8
- > versions. Pin to an exact version and read the changelog before
9
- > upgrading.
10
-
11
- ## Install
12
-
13
- ```bash
14
- pnpm add @capxul/sdk @capxul/sdk-react react @tanstack/react-query
15
- # or: npm install @capxul/sdk @capxul/sdk-react react @tanstack/react-query
16
- ```
17
-
18
- Peer requirements:
19
-
20
- - React `>= 19.0.0`
21
- - `@tanstack/react-query` `^5`
22
- - `@xstate/react` `^5` (only if you use the flow hooks)
23
-
24
- ## Two-layer trust
25
-
26
- This package is the **orchestration** half of Capxul's two-layer
27
- architecture. Funds are custodied by audited, open-source Safe v1.4.1
28
- contracts published in the [Capxul GitHub repo](https://github.com/Xelmar-tech/Capxul/tree/main/packages/contracts).
29
- The React glue here is proprietary — see [`LICENSE`](./LICENSE).
30
-
31
- ## Quickstart
32
-
33
- Wrap your app once with `CapxulProvider`. Pass a publishable key
34
- (`cap_pk_live_…` / `cap_pk_test_…`). The provider mounts synchronously
35
- — no Suspense gate, no async-mount stall — and lazily bootstraps the
36
- runtime URLs from `/v1/client/bootstrap` on the first SDK call:
37
-
38
- ```tsx
39
- import { CapxulProvider } from "@capxul/sdk-react";
40
-
41
- export default function RootLayout({ children }) {
42
- return (
43
- <CapxulProvider
44
- config={{
45
- mode: "publishable-key",
46
- publishableKey: process.env.NEXT_PUBLIC_CAPXUL_PUBLISHABLE_KEY!,
47
- }}
48
- >
49
- {children}
50
- </CapxulProvider>
51
- );
52
- }
53
- ```
54
-
55
- Inside the tree, read identity with `useMe()`. The hook collapses the
56
- multi-step lifecycle (not-bootstrapped, bootstrapping, no-session,
57
- no-data, live) into three states the consumer cares about:
58
-
59
- ```tsx
60
- import { useMe } from "@capxul/sdk-react";
61
-
62
- function Header() {
63
- const me = useMe();
64
-
65
- if (me.isPending) return <span>Loading…</span>;
66
- if (me.isError) return <span>Couldn't load profile.</span>;
67
- return <span>Hi, {me.data.username}</span>;
68
- }
69
- ```
70
-
71
- Drive an OTP sign-in flow with `useAuth()` — the canonical React auth
72
- wrapper over `AuthService`:
73
-
74
- ```tsx
75
- import { useAuth } from "@capxul/sdk-react";
76
-
77
- function SignIn() {
78
- const auth = useAuth();
79
-
80
- if (auth.state === "idle") {
81
- return (
82
- <button onClick={() => auth.signIn("alice@example.com")}>
83
- Send code
84
- </button>
85
- );
86
- }
87
- // … handle "sendingOtp", "awaitingOtp", "bootstrapping", "authenticated"
88
- }
89
- ```
90
-
91
- ## Lifecycle observability — `useCapxulStatus()`
92
-
93
- Need a status indicator or a gate UI? Subscribe to the underlying
94
- transport state machine:
95
-
96
- ```tsx
97
- import { useCapxulStatus } from "@capxul/sdk-react";
98
-
99
- function Banner() {
100
- const status = useCapxulStatus();
101
-
102
- switch (status.status) {
103
- case "idle": // no network call yet
104
- case "bootstrapping": // /v1/client/bootstrap in flight
105
- return <Spinner />;
106
- case "ready": // bootstrapped, no session
107
- case "authenticated": // bootstrapped + session live
108
- return null;
109
- case "error":
110
- return <ErrorBanner error={status.error} />;
111
- }
112
- }
113
- ```
114
-
115
- `useCapxulStatus()` is a thin
116
- [`useSyncExternalStore`](https://react.dev/reference/react/useSyncExternalStore)
117
- subscription against the transport singleton — only the components
118
- that actually call it re-render when state changes. The provider
119
- itself never re-renders.
120
-
121
- ## Publishable-key proof status
122
-
123
- The publishable-key path is runtime-proven where the repo can run it
124
- without secrets:
125
-
126
- | Surface | Runtime proof | Expected safe signal |
127
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
128
- | Provider + `useMe()` | `corepack pnpm --filter @capxul/sdk-react check-types` plus the headless proof tests under `packages/sdk-react/ops/proof` | provider reaches `useCapxulStatus().status === "ready"` after one bootstrap request |
129
- | Reference CLI mock | `corepack pnpm --filter @capxul/reference-cli build && node apps/reference-cli/dist/cli.js bootstrap probe --mock --json` | `ok:true`, `mode:"publishable-key"`, `bootstrapRequests:1`, `authRequests:1`, `keyLengthClass:"provided"` |
130
- | Reference CLI live | same command without `--mock`, with `CAPXUL_REF_PUBLISHABLE_KEY` and optional `CAPXUL_REF_BOOTSTRAP_URL` set locally | success only when the key/origin/runtime are valid; otherwise sanitized SDK error JSON |
131
-
132
- Do not paste or commit publishable keys, session tokens, Convex JWTs,
133
- cookies, or provider payloads. Proof output reports only
134
- `keyLengthClass`.
135
-
136
- ## Hooks catalogue
137
-
138
- | Surface | Hook |
139
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
- | Imperative client | `useCapxul()` |
141
- | Identity | `useMe`, `useAccount` |
142
- | Organizations | `useOrganization`, `useOrganizations`, `useMember`, `useMembers` |
143
- | Payments | `usePayment`, `usePayments`, `useOrgPayments` |
144
- | Transfers | `useTransfer`, `useTransfers`, `useOrgTransfers` |
145
- | Withdrawals | `useWithdrawal`, `useWithdrawals`, `useOrgWithdrawals` |
146
- | Documents | `useDocument`, `useDocuments`, `useOrgDocuments` |
147
- | Sub-accounts / virtual | `useSubAccount`, `useSubAccounts`, `useVirtualAccount`, `useVirtualAccounts`, `useVirtualCard`, `useVirtualCards` |
148
- | Settings | `useApiKey`, `useApiKeys`, `useWebhookEndpoint`, `useWebhookEndpoints`, `useWebhookEvent`, `useExternalAccount`, `useExternalAccounts`, `useBalanceLedgerEntry`, `useBalanceLedger` |
149
- | KYC / KYB | `useKycProfile` |
150
- | Treasury | `useTreasury`, `useSafe` |
151
- | Operations | `useOperation` (correlation join key per CANON.md §3.3) |
152
- | Lifecycle | `useCapxulStatus` |
153
- | Flows | `useOnboardingFlow`, `useProvisioningFlow` |
154
-
155
- Most "not-yet-implemented" verticals return a `QueryResult<T>` in the
156
- `error` state with `code: "NOT_IMPLEMENTED"` — they compile, render
157
- without crashing, and surface a clear runtime signal.
158
-
159
- ## Three-state read shape (`QueryResult<T>`)
160
-
161
- Read hooks return a discriminated union:
162
-
163
- ```ts
164
- type QueryResult<T> =
165
- | { readonly status: "loading" }
166
- | { readonly status: "data"; readonly data: T }
167
- | { readonly status: "error"; readonly error: CapxulError };
168
- ```
169
-
170
- Hooks **never throw** for a "still loading" condition. Pattern-match
171
- on `status`. (`useMe()` is the first hook migrated to TanStack Query
172
- — it returns `UseQueryResult<Account, CapxulError>` for now; the
173
- remaining hooks lift to that shape over time.)
174
-
175
- ## Server / CLI consumers
176
-
177
- `@capxul/sdk-react` is browser-only. For server, CLI, and harness
178
- code, build a `CapxulClient` directly with `createCapxulClient` from
179
- `@capxul/sdk` — no provider, no React. See that package's README.
180
-
181
- ## License
182
-
183
- Proprietary — see [`LICENSE`](./LICENSE). The orchestration code in
184
- this package is governed by the Capxul Terms of Service. The
185
- value-bearing custody contracts are open source.
186
-
187
- Contact: [legal@capxul.com](mailto:legal@capxul.com)