@witnium-tech/witniumchain 0.5.0 → 0.6.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/FRONTEND-INTEGRATION.md +265 -0
- package/dist/index.d.mts +215 -9
- package/dist/index.d.ts +215 -9
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -5
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# WitniumChain — Frontend Integration Guide
|
|
2
|
+
|
|
3
|
+
Audience: the team building the WitniumChain dashboard frontend. This is the
|
|
4
|
+
contract between the backend (accounts + chain-api) and your UI. It covers the
|
|
5
|
+
end-to-end user flows, where keys live, the recovery-file format, and the
|
|
6
|
+
known sharp edges discovered during backend validation.
|
|
7
|
+
|
|
8
|
+
The SDK that backs all of this is **`@witnium-tech/witniumchain`** (npm). Every
|
|
9
|
+
flow below has a typed method on it.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. The custody model — read this first
|
|
14
|
+
|
|
15
|
+
Two ed25519 keys are generated **client-side** at signup and never leave the
|
|
16
|
+
user's device in plaintext:
|
|
17
|
+
|
|
18
|
+
| Key | Controls | Used for |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **Owner key** | The contract's signing-key set (add/revoke), pause/unpause | Authorizing changes. Never signs witnesses. |
|
|
21
|
+
| **Signing key** | — | Signing witnesses day-to-day |
|
|
22
|
+
|
|
23
|
+
Witnium only ever receives the **public** halves. The backend enforces
|
|
24
|
+
`ownerPublicKey !== initialSigningPublicKey`.
|
|
25
|
+
|
|
26
|
+
**Your job on the frontend:** generate these keys, store them encrypted, let
|
|
27
|
+
the user export/import them, and produce owner-key signatures when the backend
|
|
28
|
+
asks for them (the MCP-CUSTODY ceremony, §6). You are the custody surface. If
|
|
29
|
+
you lose the keys with no recovery file, the account's contract is
|
|
30
|
+
unrecoverable — there is no server-side escrow by design.
|
|
31
|
+
|
|
32
|
+
### Recommended storage (production)
|
|
33
|
+
|
|
34
|
+
The throwaway test frontend stored keys as plain hex in `localStorage`. **Do
|
|
35
|
+
not ship that.** The intended production design:
|
|
36
|
+
|
|
37
|
+
- Wrap the two private keys with a key derived from a **WebAuthn PRF** assertion
|
|
38
|
+
(passkey). The user authenticates with their passkey to decrypt.
|
|
39
|
+
- Issue **recovery codes** at signup (one-time display) as the fallback when no
|
|
40
|
+
passkey is available (new device, lost authenticator).
|
|
41
|
+
- Persist the wrapped blob in IndexedDB.
|
|
42
|
+
|
|
43
|
+
The backend does not need to know how you wrap the keys — it only sees public
|
|
44
|
+
keys + signatures. But see §7 for the **same-origin requirement**, which is a
|
|
45
|
+
hard constraint on where this storage lives.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install @witnium-tech/witniumchain
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { WitniumchainClient } from '@witnium-tech/witniumchain';
|
|
57
|
+
|
|
58
|
+
const client = new WitniumchainClient({
|
|
59
|
+
baseUrl: 'https://auth.witniumchain.com', // accounts
|
|
60
|
+
chainBaseUrl: 'https://api.witniumchain.com', // chain-api (read methods)
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Generate keys with any ed25519 lib. The backend + SDK speak 64-hex-char
|
|
65
|
+
public keys (no `0x`). Example with `@noble/ed25519`:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import * as ed from '@noble/ed25519';
|
|
69
|
+
const priv = ed.utils.randomPrivateKey();
|
|
70
|
+
const pub = await ed.getPublicKeyAsync(priv); // hex-encode both halves
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 3. Signup → org → contract (one call)
|
|
76
|
+
|
|
77
|
+
`createOrg` is the self-serve path. It creates the admin user, the
|
|
78
|
+
organization, the org-admin membership, **and deploys the contract** with the
|
|
79
|
+
client-generated keys — all in one request.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const result = await client.createOrg({
|
|
83
|
+
orgName: 'Acme Inc.',
|
|
84
|
+
adminEmail: 'you@example.com',
|
|
85
|
+
adminPassword: '≥12 chars',
|
|
86
|
+
ownerPublicKey: ownerPubHex,
|
|
87
|
+
initialSigningPublicKey: signingPubHex,
|
|
88
|
+
});
|
|
89
|
+
// → { orgId, userId, contractAddress, contractVersion, emailVerifyToken }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Persist the two private keys + `contractAddress` locally (wrapped, per §1) and
|
|
93
|
+
prompt a recovery-file download (§5) before doing anything else.
|
|
94
|
+
|
|
95
|
+
`emailVerifyToken` is also emailed to the admin. It's echoed in the response so
|
|
96
|
+
you can render a "click to verify" link inline if you prefer. **The email is
|
|
97
|
+
the login gate, not the contract-deploy gate** — the contract is already live
|
|
98
|
+
when this returns.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Auth flows
|
|
103
|
+
|
|
104
|
+
### Email verify
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
await client.verifyEmail(token); // GET /v1/auth/verify?token=…
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> ⚠️ This is a **GET**, not POST. (Caught in testing — easy to get wrong.)
|
|
111
|
+
|
|
112
|
+
### Password login
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
await client.login({ email, password }); // sets wac_session cookie
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
In a browser the `wac_session` cookie is set automatically (the SDK uses
|
|
119
|
+
`credentials: 'include'`). Server-side callers must capture + replay the cookie.
|
|
120
|
+
|
|
121
|
+
### Magic-link sign-in
|
|
122
|
+
|
|
123
|
+
`beginOAuthLogin` / passwordless paths exist; see the SDK's `OauthNamespace`
|
|
124
|
+
and the accounts OpenAPI for `/v1/auth/magic/*`.
|
|
125
|
+
|
|
126
|
+
### MFA (TOTP)
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const { secret, otpauthUrl } = await client.mfa.totp.enroll(); // render QR from otpauthUrl
|
|
130
|
+
const { recoveryCodes } = await client.mfa.totp.confirm({ code }); // show ONCE
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### OAuth 2.1 + PKCE (for when your dashboard is itself an OAuth client)
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
const { authorizationUrl } = await client.beginOAuthLogin({ … });
|
|
137
|
+
// …redirect, then on callback:
|
|
138
|
+
await client.completeOAuthLogin({ … }); // PKCE verifier from sessionStorage
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Access token held in memory; refresh token delivered as an HttpOnly
|
|
142
|
+
`wac_refresh` cookie scoped to `/token` (JS never touches it). The SDK does
|
|
143
|
+
transparent single-flight refresh on 401.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 5. Recovery-file format
|
|
148
|
+
|
|
149
|
+
The throwaway frontend used this shape. **Treat it as a starting point** —
|
|
150
|
+
production should wrap `record` with WebAuthn/recovery-code encryption rather
|
|
151
|
+
than storing cleartext keys.
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"version": 1,
|
|
156
|
+
"type": "witnium-recovery",
|
|
157
|
+
"created": "<ISO 8601>",
|
|
158
|
+
"record": {
|
|
159
|
+
"email": "you@example.com",
|
|
160
|
+
"orgId": "<uuid>",
|
|
161
|
+
"userId": "<uuid>",
|
|
162
|
+
"contractAddress": "0x… (lowercase)",
|
|
163
|
+
"contractVersion": "5.0.0",
|
|
164
|
+
"ownerPublicKey": "<64 hex>",
|
|
165
|
+
"ownerPrivateKey": "<64 hex — ENCRYPT THIS>",
|
|
166
|
+
"signingPublicKey": "<64 hex>",
|
|
167
|
+
"signingPrivateKey": "<64 hex — ENCRYPT THIS>"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Import = restore `record` into local storage. The owner private key must be
|
|
173
|
+
retrievable for the MCP-CUSTODY ceremony (§6).
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 6. MCP-CUSTODY consent ceremony
|
|
178
|
+
|
|
179
|
+
When a user connects an AI agent (claude.ai's MCP connector, or a self-hosted
|
|
180
|
+
one) the backend runs a ceremony at OAuth-consent time that mints a **fresh
|
|
181
|
+
ephemeral signing key per connection** and asks the user to sign two owner-key
|
|
182
|
+
operations:
|
|
183
|
+
|
|
184
|
+
1. `addSigningKey(<ephemeral key>)` — registers it on the contract (submitted now)
|
|
185
|
+
2. `revokeSigningKey(<same key>)` — pre-signed, stored, fired automatically on disconnect
|
|
186
|
+
|
|
187
|
+
**What the frontend must provide:** the page that collects these two
|
|
188
|
+
signatures is currently *server-rendered by accounts* at
|
|
189
|
+
`/interaction/:uid/sign-keys`. It runs inline JS that reads the owner key from
|
|
190
|
+
`localStorage['witnium.ownerPrivateKey:<contractAddress>']`, signs both
|
|
191
|
+
messages, and form-POSTs them back.
|
|
192
|
+
|
|
193
|
+
You have two choices:
|
|
194
|
+
|
|
195
|
+
- **Let accounts render it** (current behavior). Then your only job is to make
|
|
196
|
+
sure the owner key is in `localStorage` under that exact key, **on the
|
|
197
|
+
accounts origin** (see §7).
|
|
198
|
+
- **Render it yourself** and POST the two signatures to
|
|
199
|
+
`/interaction/:uid/sign-keys` (`addOwnerSignature`, `revokeOwnerSignature`,
|
|
200
|
+
`revokeNonce`). Gives you full UX control. The signed message formats are:
|
|
201
|
+
- add: `{"op":1,"contract":"<addr>","nonce":<ownerNonce+1>,"newKey":"<pub>"}`
|
|
202
|
+
- revoke: `{"op":2,"contract":"<addr>","nonce":<ownerNonce+2>,"key":"<pub>"}`
|
|
203
|
+
(canonical JSON, signed as UTF-8 bytes with the owner key)
|
|
204
|
+
|
|
205
|
+
To get refresh tokens (required for the agent to stay connected + for the
|
|
206
|
+
disconnect-on-revoke cascade), the OAuth client **must request
|
|
207
|
+
`prompt=consent`** and include `offline_access` in scope. Without
|
|
208
|
+
`prompt=consent` the AS silently drops `offline_access` and no refresh token is
|
|
209
|
+
issued — this is standard OIDC, not a bug.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 7. Same-origin requirement (architectural — needs a decision)
|
|
214
|
+
|
|
215
|
+
**The dashboard that stores keys and the accounts OIDC interaction pages must
|
|
216
|
+
share an origin**, because `localStorage` is origin-scoped. Discovered in
|
|
217
|
+
testing: keys saved on `test-frontend.witniumchain.com` were invisible to the
|
|
218
|
+
sign-keys page rendered at `auth.witniumchain.com` → the ceremony couldn't find
|
|
219
|
+
the owner key.
|
|
220
|
+
|
|
221
|
+
Pick one:
|
|
222
|
+
|
|
223
|
+
- **(Recommended) Serve the dashboard from `auth.witniumchain.com`** (a path,
|
|
224
|
+
or accounts serving the SPA). Owner key in localStorage is naturally visible
|
|
225
|
+
to the OIDC interaction pages. Simplest, no cross-origin plumbing.
|
|
226
|
+
- **Cross-origin with `postMessage`** — dashboard on its own domain passes the
|
|
227
|
+
owner-key signature to the accounts interaction page via a `postMessage`
|
|
228
|
+
handshake. More moving parts; partially erodes the "keys never leave your
|
|
229
|
+
page" story. Only do this if a separate dashboard domain is a hard
|
|
230
|
+
requirement.
|
|
231
|
+
|
|
232
|
+
This decision blocks the key-storage implementation, so settle it early.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 8. Known limitations / sharp edges
|
|
237
|
+
|
|
238
|
+
| Issue | Impact | Status |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| **Pre-signed revoke nonce drift** | If a user opens several agent connections in a row without disconnecting, older connections' on-chain `revokeSigningKey` fails when finally fired (the pre-signed sig is bound to a stale ownerNonce). The Vault key is still destroyed — Witnium genuinely loses signing ability — but the on-chain key stays listed as active. | Known. On-chain cleanup is best-effort under serial grants. Mitigation TBD (revoke-then-add atomic, or periodic re-sign). |
|
|
241
|
+
| **`prompt=consent` required for refresh tokens** | Omitting it silently drops `offline_access`. | Working as designed (OIDC). Document in your OAuth client. |
|
|
242
|
+
| **Email verify is GET** | POST returns "Cannot POST". | Working as designed. |
|
|
243
|
+
| **Same-origin localStorage** | §7. | Architectural decision required. |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 9. API reference
|
|
248
|
+
|
|
249
|
+
- **accounts OpenAPI**: `https://auth.witniumchain.com/openapi.json` (or the
|
|
250
|
+
committed `specs/accounts.openapi.json` in the SDK repo)
|
|
251
|
+
- **chain-api OpenAPI**: `specs/chain-api.openapi.json` in the SDK repo
|
|
252
|
+
- Every SDK method's request/response type is derived from these specs via
|
|
253
|
+
`openapi-typescript`, so they stay in lockstep. Re-export aliases (e.g.
|
|
254
|
+
`CreateOrgRequest`, `SignupResponse`) are in `src/types.ts`.
|
|
255
|
+
|
|
256
|
+
## 10. SDK clients at a glance
|
|
257
|
+
|
|
258
|
+
| Client | For | Auth |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| `WitniumchainClient` | end-users (signup, login, OAuth, MFA, delegated keys, witness reads) | session cookie / access token |
|
|
261
|
+
| `WitniumchainOrgClient` | org admins managing members | org API key |
|
|
262
|
+
| `WitniumchainAdminClient` | sysadmin org lifecycle | admin token |
|
|
263
|
+
| `WitniumchainChainAdminClient` | **service-to-service only** — not for frontend use | admin token / service-principal JWT |
|
|
264
|
+
|
|
265
|
+
The frontend lives almost entirely in `WitniumchainClient`.
|
package/dist/index.d.mts
CHANGED
|
@@ -915,6 +915,139 @@ interface paths$1 {
|
|
|
915
915
|
patch?: never;
|
|
916
916
|
trace?: never;
|
|
917
917
|
};
|
|
918
|
+
"/v1/orgs": {
|
|
919
|
+
parameters: {
|
|
920
|
+
query?: never;
|
|
921
|
+
header?: never;
|
|
922
|
+
path?: never;
|
|
923
|
+
cookie?: never;
|
|
924
|
+
};
|
|
925
|
+
get?: never;
|
|
926
|
+
put?: never;
|
|
927
|
+
/**
|
|
928
|
+
* Create an organisation with client-generated keys
|
|
929
|
+
* @description Phase RBAC Thread D — explicit org creation. The caller generates the owner key and the initial signing key client-side; Witnium never holds the private bytes. The response includes the freshly-deployed contract address and a one-time email-verify token.
|
|
930
|
+
*/
|
|
931
|
+
post: {
|
|
932
|
+
parameters: {
|
|
933
|
+
query?: never;
|
|
934
|
+
header?: never;
|
|
935
|
+
path?: never;
|
|
936
|
+
cookie?: never;
|
|
937
|
+
};
|
|
938
|
+
requestBody?: {
|
|
939
|
+
content: {
|
|
940
|
+
"application/json": {
|
|
941
|
+
/** @description Display name of the organisation. */
|
|
942
|
+
orgName: string;
|
|
943
|
+
/**
|
|
944
|
+
* Format: email
|
|
945
|
+
* @description Email of the founding org-admin. Receives the email-verify link.
|
|
946
|
+
* @example user@example.com
|
|
947
|
+
*/
|
|
948
|
+
adminEmail: string;
|
|
949
|
+
/** @description Password for the founding org-admin. argon2id-hashed server-side. Minimum 12 chars; callers are expected to gate via a strength meter. */
|
|
950
|
+
adminPassword: string;
|
|
951
|
+
/**
|
|
952
|
+
* @description Client-generated Ed25519 public key that controls signing-key add/revoke on the new contract. Witnium never sees the private bytes (non-custodial).
|
|
953
|
+
* @example 4cdde7a3e3a1d8a48d2b9eaf2bcbe2db1d57d3e1a8d6c20e0a86c0f9c4b6cf2e
|
|
954
|
+
*/
|
|
955
|
+
ownerPublicKey: string;
|
|
956
|
+
/**
|
|
957
|
+
* @description First signing key registered on the contract. Often the same identity as the org-admin's browser-held key (Mode 1) but may also be the public half of a separately-registered Vault-Transit delegated key (Mode 3).
|
|
958
|
+
* @example 4cdde7a3e3a1d8a48d2b9eaf2bcbe2db1d57d3e1a8d6c20e0a86c0f9c4b6cf2e
|
|
959
|
+
*/
|
|
960
|
+
initialSigningPublicKey: string;
|
|
961
|
+
/** @description Captcha proof. Not yet wired (no captcha provider configured); reserved for when one is added. Public endpoint without it relies on downstream billing/credit-ledger gates against abuse. */
|
|
962
|
+
captchaToken?: string;
|
|
963
|
+
};
|
|
964
|
+
};
|
|
965
|
+
};
|
|
966
|
+
responses: {
|
|
967
|
+
/** @description Success */
|
|
968
|
+
200: {
|
|
969
|
+
headers: {
|
|
970
|
+
[name: string]: unknown;
|
|
971
|
+
};
|
|
972
|
+
content: {
|
|
973
|
+
"application/json": {
|
|
974
|
+
/**
|
|
975
|
+
* @description UUID v4
|
|
976
|
+
* @example 550e8400-e29b-41d4-a716-446655440000
|
|
977
|
+
*/
|
|
978
|
+
orgId: string;
|
|
979
|
+
/**
|
|
980
|
+
* @description UUID v4
|
|
981
|
+
* @example 550e8400-e29b-41d4-a716-446655440000
|
|
982
|
+
*/
|
|
983
|
+
userId: string;
|
|
984
|
+
/** @description Address of the freshly-deployed contract. */
|
|
985
|
+
contractAddress: string;
|
|
986
|
+
/** @description Semantic on-chain Solidity version (e.g. "5.0.0"). */
|
|
987
|
+
contractVersion: string;
|
|
988
|
+
/** @description Email-verify token. Already sent to adminEmail; echoed here for flows that prefer to surface a "click this link" in their own UI. */
|
|
989
|
+
emailVerifyToken: string;
|
|
990
|
+
};
|
|
991
|
+
};
|
|
992
|
+
};
|
|
993
|
+
/** @description Bad Request — validation failed */
|
|
994
|
+
400: {
|
|
995
|
+
headers: {
|
|
996
|
+
[name: string]: unknown;
|
|
997
|
+
};
|
|
998
|
+
content: {
|
|
999
|
+
"application/json": {
|
|
1000
|
+
/**
|
|
1001
|
+
* @description HTTP status code
|
|
1002
|
+
* @example 400
|
|
1003
|
+
*/
|
|
1004
|
+
statusCode?: number;
|
|
1005
|
+
/**
|
|
1006
|
+
* @description Short error label
|
|
1007
|
+
* @example Bad Request
|
|
1008
|
+
*/
|
|
1009
|
+
error?: string;
|
|
1010
|
+
/**
|
|
1011
|
+
* @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
|
|
1012
|
+
* @example Validation failed
|
|
1013
|
+
*/
|
|
1014
|
+
message: string | string[];
|
|
1015
|
+
};
|
|
1016
|
+
};
|
|
1017
|
+
};
|
|
1018
|
+
/** @description Conflict */
|
|
1019
|
+
409: {
|
|
1020
|
+
headers: {
|
|
1021
|
+
[name: string]: unknown;
|
|
1022
|
+
};
|
|
1023
|
+
content: {
|
|
1024
|
+
"application/json": {
|
|
1025
|
+
/**
|
|
1026
|
+
* @description HTTP status code
|
|
1027
|
+
* @example 400
|
|
1028
|
+
*/
|
|
1029
|
+
statusCode?: number;
|
|
1030
|
+
/**
|
|
1031
|
+
* @description Short error label
|
|
1032
|
+
* @example Bad Request
|
|
1033
|
+
*/
|
|
1034
|
+
error?: string;
|
|
1035
|
+
/**
|
|
1036
|
+
* @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
|
|
1037
|
+
* @example Validation failed
|
|
1038
|
+
*/
|
|
1039
|
+
message: string | string[];
|
|
1040
|
+
};
|
|
1041
|
+
};
|
|
1042
|
+
};
|
|
1043
|
+
};
|
|
1044
|
+
};
|
|
1045
|
+
delete?: never;
|
|
1046
|
+
options?: never;
|
|
1047
|
+
head?: never;
|
|
1048
|
+
patch?: never;
|
|
1049
|
+
trace?: never;
|
|
1050
|
+
};
|
|
918
1051
|
"/v1/orgs/me": {
|
|
919
1052
|
parameters: {
|
|
920
1053
|
query?: never;
|
|
@@ -9142,6 +9275,8 @@ type PublicOrgResponse = Res<'/v1/orgs/me', 'get'>;
|
|
|
9142
9275
|
type CreateUserRequest = Req<'/v1/orgs/me/users', 'post'>;
|
|
9143
9276
|
type CreateUserResponse = Res<'/v1/orgs/me/users', 'post'>;
|
|
9144
9277
|
type ListUsersResponse = Res<'/v1/orgs/me/users', 'get'>;
|
|
9278
|
+
type CreateOrgRequest = Req<'/v1/orgs', 'post'>;
|
|
9279
|
+
type CreateOrgResponse = Res<'/v1/orgs', 'post'>;
|
|
9145
9280
|
type CreateOrganizationRequest = Req<'/v1/admin/organizations', 'post'>;
|
|
9146
9281
|
type CreateOrganizationResponse = Res<'/v1/admin/organizations', 'post'>;
|
|
9147
9282
|
type SetAccountTypeRequest = Req<'/v1/admin/organizations/{id}/account-type', 'patch'>;
|
|
@@ -9160,11 +9295,11 @@ type SignRequest = Req<'/v1/sign', 'post'>;
|
|
|
9160
9295
|
type SignResponse = Res<'/v1/sign', 'post'>;
|
|
9161
9296
|
type ProvisionContractRequest = Req<'/v1/contracts/provision', 'post'>;
|
|
9162
9297
|
type ProvisionContractResponse = Res<'/v1/contracts/provision', 'post'>;
|
|
9163
|
-
type AddSigningKeyRequest = Req<'/v1/keys', 'post'>;
|
|
9298
|
+
type AddSigningKeyRequest$1 = Req<'/v1/keys', 'post'>;
|
|
9164
9299
|
type AddSigningKeyResponse = Res<'/v1/keys', 'post'>;
|
|
9165
|
-
type RevokeSigningKeyRequest = Req<'/v1/keys/revoke', 'post'>;
|
|
9300
|
+
type RevokeSigningKeyRequest$1 = Req<'/v1/keys/revoke', 'post'>;
|
|
9166
9301
|
type RevokeSigningKeyResponse = Res<'/v1/keys/revoke', 'post'>;
|
|
9167
|
-
type PauseRequest = Req<'/v1/contracts/pause', 'post'>;
|
|
9302
|
+
type PauseRequest$1 = Req<'/v1/contracts/pause', 'post'>;
|
|
9168
9303
|
type PauseResponse = Res<'/v1/contracts/pause', 'post'>;
|
|
9169
9304
|
type UnpauseRequest = Req<'/v1/contracts/unpause', 'post'>;
|
|
9170
9305
|
type UnpauseResponse = Res<'/v1/contracts/unpause', 'post'>;
|
|
@@ -9441,6 +9576,17 @@ declare class WitniumchainClient {
|
|
|
9441
9576
|
*/
|
|
9442
9577
|
me(): Promise<AccountResponse>;
|
|
9443
9578
|
signup(body: SignupRequest): Promise<SignupResponse>;
|
|
9579
|
+
/**
|
|
9580
|
+
* Self-serve org creation (Phase RBAC Thread D). One public call that
|
|
9581
|
+
* creates the admin user, the org, the org-admin membership, and deploys
|
|
9582
|
+
* the contract with the caller's client-generated `ownerPublicKey` +
|
|
9583
|
+
* `initialSigningPublicKey`. Witnium never sees the private bytes.
|
|
9584
|
+
*
|
|
9585
|
+
* Returns `{ orgId, userId, contractAddress, contractVersion,
|
|
9586
|
+
* emailVerifyToken }`. The verify token is also emailed; it's echoed here
|
|
9587
|
+
* for UIs that prefer to render the verify link themselves.
|
|
9588
|
+
*/
|
|
9589
|
+
createOrg(body: CreateOrgRequest): Promise<CreateOrgResponse>;
|
|
9444
9590
|
verifyEmail(token: string): Promise<VerifyEmailResponse>;
|
|
9445
9591
|
login(body: LoginRequest): Promise<LoginResponse>;
|
|
9446
9592
|
logout(): Promise<LogoutResponse>;
|
|
@@ -9465,9 +9611,9 @@ declare class WitniumchainClient {
|
|
|
9465
9611
|
revokeDelegatedKey(id: string): Promise<RevokeDelegatedKeyResponse>;
|
|
9466
9612
|
sign(body: SignRequest, requestId?: string): Promise<SignResponse>;
|
|
9467
9613
|
provisionContract(body: ProvisionContractRequest): Promise<ProvisionContractResponse>;
|
|
9468
|
-
addSigningKey(body: AddSigningKeyRequest): Promise<AddSigningKeyResponse>;
|
|
9469
|
-
revokeSigningKey(body: RevokeSigningKeyRequest): Promise<RevokeSigningKeyResponse>;
|
|
9470
|
-
pauseContract(body: PauseRequest): Promise<PauseResponse>;
|
|
9614
|
+
addSigningKey(body: AddSigningKeyRequest$1): Promise<AddSigningKeyResponse>;
|
|
9615
|
+
revokeSigningKey(body: RevokeSigningKeyRequest$1): Promise<RevokeSigningKeyResponse>;
|
|
9616
|
+
pauseContract(body: PauseRequest$1): Promise<PauseResponse>;
|
|
9471
9617
|
unpauseContract(body: UnpauseRequest): Promise<UnpauseResponse>;
|
|
9472
9618
|
proposeWitness(contractAddress: string, body: ProposeWitnessRequest, idempotencyKey?: string): Promise<ProposeWitnessResponse>;
|
|
9473
9619
|
signWitness(contractAddress: string, witnessId: string, body: SignWitnessRequest): Promise<SignWitnessResponse>;
|
|
@@ -9690,8 +9836,8 @@ declare class SigningKeys {
|
|
|
9690
9836
|
* WitniumchainClient.getAccount} and returns the `signingKeys` slice.
|
|
9691
9837
|
*/
|
|
9692
9838
|
list(): Promise<AccountResponse['signingKeys']>;
|
|
9693
|
-
add(body: AddSigningKeyRequest): Promise<AddSigningKeyResponse>;
|
|
9694
|
-
revoke(body: RevokeSigningKeyRequest): Promise<RevokeSigningKeyResponse>;
|
|
9839
|
+
add(body: AddSigningKeyRequest$1): Promise<AddSigningKeyResponse>;
|
|
9840
|
+
revoke(body: RevokeSigningKeyRequest$1): Promise<RevokeSigningKeyResponse>;
|
|
9695
9841
|
}
|
|
9696
9842
|
/** `client.oauth.sessions.*` — list and revoke active OAuth sessions. */
|
|
9697
9843
|
declare class OauthNamespace {
|
|
@@ -9792,6 +9938,66 @@ declare class WitniumchainAdminClient {
|
|
|
9792
9938
|
adjustCredits(orgId: string, delta: number, note?: string): Promise<AdjustCreditsResponse>;
|
|
9793
9939
|
}
|
|
9794
9940
|
|
|
9941
|
+
type Body<T> = T extends {
|
|
9942
|
+
content: {
|
|
9943
|
+
'application/json': infer J;
|
|
9944
|
+
};
|
|
9945
|
+
} ? J : never;
|
|
9946
|
+
type Resp<T> = T extends {
|
|
9947
|
+
content: {
|
|
9948
|
+
'application/json': infer J;
|
|
9949
|
+
};
|
|
9950
|
+
} ? J : never;
|
|
9951
|
+
type DeployContractRequest = Body<NonNullable<paths['/v5/contracts/deploy']['post']['requestBody']>>;
|
|
9952
|
+
type DeployContractResponse = Resp<paths['/v5/contracts/deploy']['post']['responses']['200']>;
|
|
9953
|
+
type AddSigningKeyRequest = Body<NonNullable<paths['/v5/contracts/{contractAddress}/keys']['post']['requestBody']>>;
|
|
9954
|
+
type OwnerOpResponse = Resp<paths['/v5/contracts/{contractAddress}/keys']['post']['responses']['200']>;
|
|
9955
|
+
type RevokeSigningKeyRequest = {
|
|
9956
|
+
keyToRevoke: string;
|
|
9957
|
+
ownerNonce: number;
|
|
9958
|
+
ownerSignature: string;
|
|
9959
|
+
};
|
|
9960
|
+
type PauseRequest = {
|
|
9961
|
+
ownerNonce: number;
|
|
9962
|
+
ownerSignature: string;
|
|
9963
|
+
};
|
|
9964
|
+
interface WitniumchainChainAdminClientConfig {
|
|
9965
|
+
/** chain-api base URL, e.g. https://api.witniumchain.com. Trailing slash optional. */
|
|
9966
|
+
baseUrl: string;
|
|
9967
|
+
/**
|
|
9968
|
+
* Static bearer token (legacy `BEARER_TOKEN`). Mutually exclusive with
|
|
9969
|
+
* `adminTokenProvider`. Phase RBAC checkpoint 3 retires this in favour of
|
|
9970
|
+
* the provider.
|
|
9971
|
+
*/
|
|
9972
|
+
adminToken?: string;
|
|
9973
|
+
/**
|
|
9974
|
+
* Async function that yields a fresh accounts-minted service-principal JWT
|
|
9975
|
+
* with `aud=https://api.witniumchain.com/admin` + `role=org-admin` on each
|
|
9976
|
+
* call. Implementations typically cache against the token's `exp`. Returned
|
|
9977
|
+
* tokens MUST satisfy chain-api's DashboardJwtGuard.
|
|
9978
|
+
*/
|
|
9979
|
+
adminTokenProvider?: () => Promise<string>;
|
|
9980
|
+
/** Per-request timeout in milliseconds. Default 30000. */
|
|
9981
|
+
timeout?: number;
|
|
9982
|
+
/** Alternate fetch implementation, e.g. for tests. Default globalThis.fetch. */
|
|
9983
|
+
fetch?: typeof fetch;
|
|
9984
|
+
}
|
|
9985
|
+
declare class WitniumchainChainAdminClient {
|
|
9986
|
+
private readonly baseUrl;
|
|
9987
|
+
private readonly adminToken;
|
|
9988
|
+
private readonly adminTokenProvider;
|
|
9989
|
+
private readonly timeout;
|
|
9990
|
+
private readonly fetchImpl;
|
|
9991
|
+
constructor(config: WitniumchainChainAdminClientConfig);
|
|
9992
|
+
deployContract(body: DeployContractRequest): Promise<DeployContractResponse>;
|
|
9993
|
+
addSigningKey(contractAddress: string, body: AddSigningKeyRequest): Promise<OwnerOpResponse>;
|
|
9994
|
+
revokeSigningKey(contractAddress: string, body: RevokeSigningKeyRequest): Promise<OwnerOpResponse>;
|
|
9995
|
+
pauseContract(contractAddress: string, body: PauseRequest): Promise<OwnerOpResponse>;
|
|
9996
|
+
unpauseContract(contractAddress: string, body: PauseRequest): Promise<OwnerOpResponse>;
|
|
9997
|
+
private resolveToken;
|
|
9998
|
+
private req;
|
|
9999
|
+
}
|
|
10000
|
+
|
|
9795
10001
|
/**
|
|
9796
10002
|
* WitniumchainOrgClient — org-admin facade over the accounts API.
|
|
9797
10003
|
*
|
|
@@ -9864,4 +10070,4 @@ declare class WitniumchainApiError extends Error {
|
|
|
9864
10070
|
});
|
|
9865
10071
|
}
|
|
9866
10072
|
|
|
9867
|
-
export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OauthNamespace, OauthSessions, OrgUsers, type OwnerSigner, type PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, defaultVerifierStorage };
|
|
10073
|
+
export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest$1 as AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrgRequest, type CreateOrgResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OauthNamespace, OauthSessions, OrgUsers, type OwnerSigner, type PauseRequest$1 as PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest$1 as RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainChainAdminClient, type WitniumchainChainAdminClientConfig, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, defaultVerifierStorage };
|