@capxul/sdk 0.2.0-alpha.4 → 1.0.0-alpha.10
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 +5 -308
- package/dist/InMemoryAuthCacheAdapter-v5W-XB5M.mjs +457 -0
- package/dist/InMemoryAuthCacheAdapter-v5W-XB5M.mjs.map +1 -0
- package/dist/index-CTXgQ_xR.d.mts +158 -0
- package/dist/index-CTXgQ_xR.d.mts.map +1 -0
- package/dist/index.d.mts +2574 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7974 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node/index.d.mts +55 -0
- package/dist/node/index.d.mts.map +1 -0
- package/dist/node/index.mjs +158 -0
- package/dist/node/index.mjs.map +1 -0
- package/dist/ports/safe-deployment.d.mts +2 -0
- package/dist/ports/safe-deployment.mjs +38 -0
- package/dist/ports/safe-deployment.mjs.map +1 -0
- package/dist/safe-deployment-D3k9yndM.d.mts +136 -0
- package/dist/safe-deployment-D3k9yndM.d.mts.map +1 -0
- package/dist/signer-D9fUJp8o.d.mts +147 -0
- package/dist/signer-D9fUJp8o.d.mts.map +1 -0
- package/package.json +42 -71
- package/CHANGELOG.md +0 -274
- package/LICENSE +0 -44
- package/dist/client-CbUeJoM9.d.ts +0 -1335
- package/dist/client-UEm2oZbZ.d.cts +0 -1335
- package/dist/client.cjs +0 -4042
- package/dist/client.d.cts +0 -6
- package/dist/client.d.ts +0 -6
- package/dist/client.js +0 -4040
- package/dist/errors-CwhCWGxm.d.ts +0 -70
- package/dist/errors-rqxuUhQP.d.cts +0 -70
- package/dist/errors.cjs +0 -35
- package/dist/errors.d.cts +0 -2
- package/dist/errors.d.ts +0 -2
- package/dist/errors.js +0 -31
- package/dist/index.cjs +0 -4273
- package/dist/index.d.cts +0 -461
- package/dist/index.d.ts +0 -461
- package/dist/index.js +0 -4234
- package/dist/next-action-CTGl8wpy.d.cts +0 -177
- package/dist/next-action-CTGl8wpy.d.ts +0 -177
- package/dist/types-BD4VAQb5.d.ts +0 -1205
- package/dist/types-HlwCIjgQ.d.cts +0 -1205
- package/dist/webhooks.cjs +0 -118
- package/dist/webhooks.d.cts +0 -33
- package/dist/webhooks.d.ts +0 -33
- package/dist/webhooks.js +0 -116
package/README.md
CHANGED
|
@@ -1,312 +1,9 @@
|
|
|
1
1
|
# @capxul/sdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
payments, manage organization treasuries, and orchestrate on-chain
|
|
5
|
-
flows backed by audited custody contracts.
|
|
3
|
+
Layer 0 SDK package.
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
- [Getting started](./docs/getting-started.md) — canonical consumer DX
|
|
6
|
+
- [Package docs index](./docs/README.md)
|
|
7
|
+
- [Env module](./docs/env.md)
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
pnpm add @capxul/sdk @capxul/sdk-react
|
|
15
|
-
# or: npm install @capxul/sdk @capxul/sdk-react
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
`@capxul/sdk` is the headless contract — flows, types, errors. The
|
|
19
|
-
React-flavored entry point lives in `@capxul/sdk-react`. Pick:
|
|
20
|
-
|
|
21
|
-
- **Browser apps (recommended).** Install both. Use
|
|
22
|
-
`<CapxulProvider config={{ mode: "publishable-key", publishableKey }}>`
|
|
23
|
-
from `@capxul/sdk-react` and the `useMe` / `useCapxulStatus` hooks.
|
|
24
|
-
See that package's README for the lazy-DX example.
|
|
25
|
-
- **Server / CLI / scripts.** Install only `@capxul/sdk`. Build a
|
|
26
|
-
`CapxulClient` directly with your own auth and Convex adapters
|
|
27
|
-
(see "Server-side construction" below).
|
|
28
|
-
|
|
29
|
-
## Two-layer trust
|
|
30
|
-
|
|
31
|
-
Capxul splits the platform into two layers with different licenses:
|
|
32
|
-
|
|
33
|
-
| Layer | What it does | License |
|
|
34
|
-
| ---------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
35
|
-
| Custody (on-chain) | Safe v1.4.1 + ERC-4337 modules — every contract that holds, transfers, or signs over user funds | Open source, audited, in the [Capxul GitHub repo](https://github.com/Xelmar-tech/Capxul/tree/main/packages/contracts) |
|
|
36
|
-
| Orchestration (this package) | Workflow logic, business rules, integration glue, the `/v1/*` HTTP client | Proprietary — see `LICENSE` |
|
|
37
|
-
|
|
38
|
-
You don't have to take our word for the parts that hold money — those
|
|
39
|
-
contracts are open and auditable. The parts that orchestrate workflows
|
|
40
|
-
on top are our product.
|
|
41
|
-
|
|
42
|
-
## Quickstart (server / CLI)
|
|
43
|
-
|
|
44
|
-
```ts
|
|
45
|
-
import { createCapxulClient, createLocalSigner, tryCatch } from "@capxul/sdk";
|
|
46
|
-
|
|
47
|
-
const signer = createLocalSigner(process.env.CAPXUL_PRIVATE_KEY!);
|
|
48
|
-
const capxul = createCapxulClient({
|
|
49
|
-
apiKey: process.env.CAPXUL_API_KEY!, // server-to-server partner key
|
|
50
|
-
signer,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const [err, payment] = await tryCatch(
|
|
54
|
-
capxul.payments.create({
|
|
55
|
-
to: { email: "vendor@example.com" },
|
|
56
|
-
amount: { value: "100", currency: "USD" },
|
|
57
|
-
}),
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
if (err) {
|
|
61
|
-
if (err.code === "INSUFFICIENT_BALANCE") {
|
|
62
|
-
// narrow `err.code` to route the UI / reply
|
|
63
|
-
}
|
|
64
|
-
throw err;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
console.log(payment.id);
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Quickstart (browser via React)
|
|
71
|
-
|
|
72
|
-
See [`@capxul/sdk-react`](https://www.npmjs.com/package/@capxul/sdk-react).
|
|
73
|
-
The browser path uses a publishable key (`cap_pk_…`) and bootstraps
|
|
74
|
-
runtime URLs lazily — no need to ship secrets to the client:
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
import { CapxulProvider, useMe, useCapxulStatus } from "@capxul/sdk-react";
|
|
78
|
-
|
|
79
|
-
<CapxulProvider
|
|
80
|
-
config={{
|
|
81
|
-
mode: "publishable-key",
|
|
82
|
-
publishableKey: process.env.NEXT_PUBLIC_CAPXUL_PUBLISHABLE_KEY!,
|
|
83
|
-
}}
|
|
84
|
-
>
|
|
85
|
-
<App />
|
|
86
|
-
</CapxulProvider>;
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Publishable-key transport
|
|
90
|
-
|
|
91
|
-
The browser transport accepts a publishable key, then lazily resolves
|
|
92
|
-
runtime URLs by POSTing to `/v1/client/bootstrap` on the first auth or
|
|
93
|
-
`ensureRuntime()` call. The successful backend response is intentionally
|
|
94
|
-
small:
|
|
95
|
-
|
|
96
|
-
```json
|
|
97
|
-
{
|
|
98
|
-
"authBaseUrl": "https://<deployment>.convex.site/api/auth",
|
|
99
|
-
"convexUrl": "https://<deployment>.convex.cloud"
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
The resolved runtime is cached for the lifetime of the transport. Concurrent
|
|
104
|
-
callers share one bootstrap request, successful resolutions are reused, and
|
|
105
|
-
failed bootstrap attempts reset so the next call can retry. Tests and
|
|
106
|
-
non-default deployments can inject both `fetchImpl` and an absolute
|
|
107
|
-
`bootstrapUrl`:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { makeHttpTransport, CapxulError } from "@capxul/sdk";
|
|
111
|
-
|
|
112
|
-
const transport = makeHttpTransport({
|
|
113
|
-
mode: "publishable-key",
|
|
114
|
-
publishableKey: process.env.NEXT_PUBLIC_CAPXUL_PUBLISHABLE_KEY!,
|
|
115
|
-
bootstrapUrl: "https://api.capxul.com/v1/client/bootstrap",
|
|
116
|
-
fetchImpl: fetch,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
await transport.ensureRuntime();
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Local setup errors and backend bootstrap errors both use `CapxulError`, but
|
|
123
|
-
carry different `details.source` values:
|
|
124
|
-
|
|
125
|
-
```ts
|
|
126
|
-
try {
|
|
127
|
-
await transport.ensureRuntime();
|
|
128
|
-
} catch (error) {
|
|
129
|
-
if (error instanceof CapxulError) {
|
|
130
|
-
if (error.details?.source === "sdk-config") {
|
|
131
|
-
// Missing or malformed local config, such as publishableKey or bootstrapUrl.
|
|
132
|
-
}
|
|
133
|
-
if (error.details?.source === "backend-bootstrap") {
|
|
134
|
-
// Sanitized backend refusal, such as NOT_AUTHENTICATED or PERMISSION_DENIED.
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Runtime proof status:
|
|
141
|
-
|
|
142
|
-
| Surface | Source support | Runtime proof | Status |
|
|
143
|
-
| -------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
144
|
-
| SDK transport | `makeHttpTransport({ mode: "publishable-key", publishableKey })` | `packages/sdk/tests/unit/transport.test.ts` proves config validation, singleflight bootstrap, retry after failure, lifecycle transitions, and sanitized backend errors. | Proven with mocked fetch |
|
|
145
|
-
| React provider | `CapxulProvider config={{ mode: "publishable-key", ... }}` | `packages/sdk-react/ops/proof/react-headless.test.tsx` proves bootstrap before a real `useMe()` read through the provider and lazy Convex data client. | Proven with mocked fetch + headless React |
|
|
146
|
-
| Reference CLI | `bootstrap probe --mock --json` | `apps/reference-cli/scripts/agent-driver.ts` phase 0 and the direct CLI command prove provider/bootstrap/auth ordering and sanitized output. | Proven locally; live endpoint remains manual-key gated |
|
|
147
|
-
|
|
148
|
-
Copy-paste local replication:
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
corepack pnpm --filter @capxul/sdk check-types
|
|
152
|
-
corepack pnpm --filter @capxul/sdk build
|
|
153
|
-
corepack pnpm --filter @capxul/sdk-react check-types
|
|
154
|
-
corepack pnpm --filter @capxul/sdk-react build
|
|
155
|
-
corepack pnpm --filter @capxul/reference-cli check-types
|
|
156
|
-
corepack pnpm --filter @capxul/reference-cli build
|
|
157
|
-
node apps/reference-cli/dist/cli.js bootstrap probe --mock --json
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Run the SDK and React SDK builds before the reference CLI typecheck in a
|
|
161
|
-
fresh checkout; the CLI depends on their generated declaration outputs.
|
|
162
|
-
|
|
163
|
-
Expected sanitized pass signal:
|
|
164
|
-
|
|
165
|
-
```json
|
|
166
|
-
{
|
|
167
|
-
"command": "bootstrap.probe",
|
|
168
|
-
"ok": true,
|
|
169
|
-
"mode": "publishable-key",
|
|
170
|
-
"status": "ready",
|
|
171
|
-
"bootstrapRequests": 1,
|
|
172
|
-
"authRequests": 1,
|
|
173
|
-
"keyLengthClass": "provided",
|
|
174
|
-
"mocked": true
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Public surface (alpha)
|
|
179
|
-
|
|
180
|
-
```ts
|
|
181
|
-
capxul.auth // sendOtp, verifyOtp, signOut, serviceTokenMint
|
|
182
|
-
capxul.me // get, update — first-party caller identity
|
|
183
|
-
capxul.accounts // create, retrieve, list
|
|
184
|
-
capxul.organizations // CRUD + members + payments + treasury
|
|
185
|
-
capxul.payments // create, retrieve, list
|
|
186
|
-
capxul.withdrawals // create, retrieve, list
|
|
187
|
-
capxul.documents // personal invoices first; broader document variants typed
|
|
188
|
-
capxul.flows.{auth, onboarding, provisioning} // XState v5 flows
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Personal invoice documents
|
|
192
|
-
|
|
193
|
-
The first `documents` runtime surface is the personal invoice pilot.
|
|
194
|
-
It creates immutable open invoice documents with a canonical
|
|
195
|
-
`invoiceHash`. The backend stores the private invoice payload; the
|
|
196
|
-
chain receives only the hash as `documentHash`.
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
const [err, invoice] = await capxul.documents.create({
|
|
200
|
-
type: "invoice",
|
|
201
|
-
recipient: { email: "client@example.com" },
|
|
202
|
-
amount: { value: "25.00", currency: "USD" },
|
|
203
|
-
lineItems: [
|
|
204
|
-
{ description: "Design", quantity: 1, unitPrice: "25.00", currency: "USD" },
|
|
205
|
-
],
|
|
206
|
-
reference: "May design work",
|
|
207
|
-
dueAt: "2026-05-20T00:00:00.000Z",
|
|
208
|
-
});
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
Use `capxul.documents.retrieve(docId)`, `.list({ type: "invoice" })`,
|
|
212
|
-
and `.cancel(docId)` for the rest of the pilot surface. Org-admin
|
|
213
|
-
invoices, file uploads, PDFs, partial payments, and mutable open
|
|
214
|
-
invoices are outside this pilot.
|
|
215
|
-
|
|
216
|
-
Helpers:
|
|
217
|
-
|
|
218
|
-
- `tryCatch(promise)` — error tuple `[error, data]`; routes on
|
|
219
|
-
`error.code` (typed `CapxulErrorCode` union)
|
|
220
|
-
- `matchError`, `matchStatus`, `matchAction` — exhaustive pattern
|
|
221
|
-
matchers per CANON.md §4.44
|
|
222
|
-
- Branded type constructors — `toEmail`, `toAccountId`,
|
|
223
|
-
`toOrganizationId`, … — never cast raw strings
|
|
224
|
-
|
|
225
|
-
## Organizations
|
|
226
|
-
|
|
227
|
-
Create an organization, manage its treasury, and invite members with
|
|
228
|
-
role-based access:
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
// Create
|
|
232
|
-
const [err, org] = await capxul.organizations.create({ name: "Acme" });
|
|
233
|
-
|
|
234
|
-
// Invite a member — returns the raw token once
|
|
235
|
-
const [err, { member, inviteToken }] =
|
|
236
|
-
await capxul.organizations.members.invite({
|
|
237
|
-
organizationId: org.id,
|
|
238
|
-
email: "alice@example.com",
|
|
239
|
-
role: "finance_manager",
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// List members — defaults to active; pass status to filter
|
|
243
|
-
const [err, list] = await capxul.organizations.members.list({
|
|
244
|
-
organizationId: org.id,
|
|
245
|
-
status: "pending", // "pending" | "active" | "revoked" | "expired" | "all"
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// Accept an invitation (called by the invitee)
|
|
249
|
-
const [err, member] = await capxul.organizations.members.accept({
|
|
250
|
-
token: inviteToken,
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// Revoke a pending invitation
|
|
254
|
-
const [err] = await capxul.organizations.members.revoke({
|
|
255
|
-
organizationId: org.id,
|
|
256
|
-
memberId: member.id,
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// Remove an active member
|
|
260
|
-
const [err] = await capxul.organizations.members.remove({
|
|
261
|
-
organizationId: org.id,
|
|
262
|
-
memberId: member.id,
|
|
263
|
-
});
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Member roles: `owner`, `finance_manager`, `payments_operator`,
|
|
267
|
-
`org_admin`, `viewer`, `accountant`. Only `owner` and `org_admin` can
|
|
268
|
-
invite, revoke, remove, or change roles.
|
|
269
|
-
|
|
270
|
-
Pending invitations auto-accept on first sign-in when the user's email
|
|
271
|
-
matches. Overdue pending invitations expire via a nightly cron.
|
|
272
|
-
|
|
273
|
-
## Error model
|
|
274
|
-
|
|
275
|
-
Every method returns a `CapxulResult<T, Codes>` tuple. Errors are
|
|
276
|
-
instances of `CapxulError` with a typed `code` (narrowed per method).
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
const [err, account] = await tryCatch(capxul.me.get());
|
|
280
|
-
|
|
281
|
-
if (err) {
|
|
282
|
-
switch (err.code) {
|
|
283
|
-
case "PROFILE_NOT_FOUND":
|
|
284
|
-
return router.push("/onboarding");
|
|
285
|
-
case "NOT_AUTHENTICATED":
|
|
286
|
-
return router.push("/login");
|
|
287
|
-
default:
|
|
288
|
-
throw err; // unhandled — bubble to the error boundary
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
There is no second error type. Backend `CapxulError` → Convex
|
|
294
|
-
serialization → SDK deserialization → frontend `CapxulError` — one
|
|
295
|
-
class, 34 codes, end-to-end.
|
|
296
|
-
|
|
297
|
-
## Telemetry (opt-out)
|
|
298
|
-
|
|
299
|
-
The SDK reports operational telemetry (operation IDs, latencies,
|
|
300
|
-
correlation IDs, error codes) to Capxul. **PII is never sent** — events
|
|
301
|
-
are scrubbed at the source. Disable by passing
|
|
302
|
-
`{ telemetry: { enabled: false } }` (coming in `0.2.0`); current alpha
|
|
303
|
-
sends only operational signals which Capxul Terms disclose explicitly.
|
|
304
|
-
|
|
305
|
-
## License
|
|
306
|
-
|
|
307
|
-
Proprietary — see [`LICENSE`](./LICENSE). The orchestration code in
|
|
308
|
-
this package is governed by the Capxul Terms of Service. The
|
|
309
|
-
value-bearing custody contracts are open source — see "Two-layer trust"
|
|
310
|
-
above.
|
|
311
|
-
|
|
312
|
-
Contact: [legal@capxul.com](mailto:legal@capxul.com)
|
|
9
|
+
React apps: [`@capxul/sdk-react` provider docs](../sdk-react/docs/provider.md).
|