@mcsherrylabs/evolver-client 0.8.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/LICENSE +202 -0
- package/README.md +42 -0
- package/dist/api.d.ts +172 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +508 -0
- package/dist/api.js.map +1 -0
- package/dist/bodies.d.ts +86 -0
- package/dist/bodies.d.ts.map +1 -0
- package/dist/bodies.js +145 -0
- package/dist/bodies.js.map +1 -0
- package/dist/crypto/auth.d.ts +25 -0
- package/dist/crypto/auth.d.ts.map +1 -0
- package/dist/crypto/auth.js +71 -0
- package/dist/crypto/auth.js.map +1 -0
- package/dist/crypto/canonical.d.ts +21 -0
- package/dist/crypto/canonical.d.ts.map +1 -0
- package/dist/crypto/canonical.js +68 -0
- package/dist/crypto/canonical.js.map +1 -0
- package/dist/crypto/group.d.ts +29 -0
- package/dist/crypto/group.d.ts.map +1 -0
- package/dist/crypto/group.js +107 -0
- package/dist/crypto/group.js.map +1 -0
- package/dist/crypto/hash.d.ts +7 -0
- package/dist/crypto/hash.d.ts.map +1 -0
- package/dist/crypto/hash.js +34 -0
- package/dist/crypto/hash.js.map +1 -0
- package/dist/crypto/stream.d.ts +27 -0
- package/dist/crypto/stream.d.ts.map +1 -0
- package/dist/crypto/stream.js +186 -0
- package/dist/crypto/stream.js.map +1 -0
- package/dist/envelope.d.ts +28 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +68 -0
- package/dist/envelope.js.map +1 -0
- package/dist/generated/codecs.d.ts +145 -0
- package/dist/generated/codecs.d.ts.map +1 -0
- package/dist/generated/codecs.js +240 -0
- package/dist/generated/codecs.js.map +1 -0
- package/dist/identity.d.ts +17 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +52 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/signers.d.ts +52 -0
- package/dist/signers.d.ts.map +1 -0
- package/dist/signers.js +75 -0
- package/dist/signers.js.map +1 -0
- package/dist/types.d.ts +103 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -0
- package/dist/wire.d.ts +13 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +71 -0
- package/dist/wire.js.map +1 -0
- package/package.json +41 -0
package/dist/api.js
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
// Node HTTP client: submit txs, read identities, drive the channel stream.
|
|
2
|
+
//
|
|
3
|
+
// Transport is injectable (defaults to the global `fetch`). `baseUrl` defaults
|
|
4
|
+
// to "" — relative paths, which is what the browser app uses behind its dev
|
|
5
|
+
// proxy; pass an absolute origin (e.g. "https://node:8440") from Node.
|
|
6
|
+
import { FAILURE_REASONS } from "./types.js";
|
|
7
|
+
import { faucetClaimDigest } from "./identity.js";
|
|
8
|
+
import { blsSign, edSign } from "./crypto/auth.js";
|
|
9
|
+
import { bytesToHex } from "./crypto/hash.js";
|
|
10
|
+
function asFailureReason(s) {
|
|
11
|
+
// FAILURE_REASONS is the single declaration of these codes (see types.ts); anything
|
|
12
|
+
// the node sends that is not in it degrades to "internal" rather than being trusted.
|
|
13
|
+
return (FAILURE_REASONS.includes(s) ? s : "internal");
|
|
14
|
+
}
|
|
15
|
+
function base64ToBytes(b64) {
|
|
16
|
+
const bin = atob(b64);
|
|
17
|
+
const out = new Uint8Array(bin.length);
|
|
18
|
+
for (let i = 0; i < bin.length; i++)
|
|
19
|
+
out[i] = bin.charCodeAt(i);
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
/** Content-path transfers are bounded by INACTIVITY, never total duration (143 FR-016):
|
|
23
|
+
* a healthy ~10 Mbps link must be able to move an arbitrarily large object. */
|
|
24
|
+
const BODY_INACTIVITY_MS = 300_000;
|
|
25
|
+
/** POST /content request headers (139 §1 + 142 grants). A non-empty grant list whose
|
|
26
|
+
* entries are all blank throws: restriction was intended, so never publish open. */
|
|
27
|
+
function publishHeaders(label, size, authorizedPrincipals) {
|
|
28
|
+
const headers = {
|
|
29
|
+
"Content-Type": "application/octet-stream",
|
|
30
|
+
"Content-Length": String(size),
|
|
31
|
+
};
|
|
32
|
+
const provided = authorizedPrincipals ?? [];
|
|
33
|
+
const grants = provided.map((p) => p.trim()).filter((p) => p.length > 0);
|
|
34
|
+
if (provided.length > 0 && grants.length === 0)
|
|
35
|
+
throw new Error(`${label}: authorizedPrincipals given but contains no usable name — refusing an open publish`);
|
|
36
|
+
if (grants.length > 0)
|
|
37
|
+
headers["X-Evolver-Authorized-Principal"] = grants.join(",");
|
|
38
|
+
return headers;
|
|
39
|
+
}
|
|
40
|
+
/** The 201 `{key,size}` contract; any other status throws with the server's JSON body. */
|
|
41
|
+
function parsePublished(label, status, text, size) {
|
|
42
|
+
if (status !== 201)
|
|
43
|
+
throw new Error(`${label}: HTTP ${status} ${text}`);
|
|
44
|
+
let body = {};
|
|
45
|
+
try {
|
|
46
|
+
body = JSON.parse(text);
|
|
47
|
+
}
|
|
48
|
+
catch { /* reported below */ }
|
|
49
|
+
if (!body.key)
|
|
50
|
+
throw new Error(`${label}: no key in response`);
|
|
51
|
+
return { key: body.key, size: body.size ?? size };
|
|
52
|
+
}
|
|
53
|
+
async function loadNodeModule(name) {
|
|
54
|
+
try {
|
|
55
|
+
return (await import(/* @vite-ignore */ `node:${name}`));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Streaming POST on Node, via `node:http`/`node:https` — `Readable.fromWeb(body)` piped
|
|
63
|
+
* into the request so the SOCKET paces the body (FR-006). `fetch` is not usable here:
|
|
64
|
+
* undici does not backpressure a ReadableStream request body and drains it into memory
|
|
65
|
+
* (0.89–0.93× of the body as RSS growth; node:http is flat).
|
|
66
|
+
*
|
|
67
|
+
* Returns null when not running on Node (or the modules are unavailable), so the caller
|
|
68
|
+
* falls back to fetch. A response that arrives MID-body (the node's 507/413 refusals
|
|
69
|
+
* close early) is the answer — the write-side reset it causes is not an error.
|
|
70
|
+
*/
|
|
71
|
+
async function nodeStreamPost(url, headers, body, inactivityMs) {
|
|
72
|
+
const versions = globalThis.process?.versions;
|
|
73
|
+
if (typeof versions?.node !== "string")
|
|
74
|
+
return null;
|
|
75
|
+
const https = new URL(url, "http://localhost").protocol === "https:";
|
|
76
|
+
const http = await loadNodeModule(https ? "https" : "http");
|
|
77
|
+
const streams = await loadNodeModule("stream");
|
|
78
|
+
if (http === null || streams === null)
|
|
79
|
+
return null;
|
|
80
|
+
return await new Promise((resolve, reject) => {
|
|
81
|
+
let settled = false;
|
|
82
|
+
let status = 0;
|
|
83
|
+
let text = "";
|
|
84
|
+
const answer = () => { if (!settled) {
|
|
85
|
+
settled = true;
|
|
86
|
+
resolve({ status, text });
|
|
87
|
+
} };
|
|
88
|
+
const failWith = (e) => {
|
|
89
|
+
if (!settled) {
|
|
90
|
+
settled = true;
|
|
91
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const req = http.request(url, { method: "POST", headers }, (res) => {
|
|
95
|
+
status = typeof res.statusCode === "number" ? res.statusCode : 0;
|
|
96
|
+
res.setEncoding("utf8");
|
|
97
|
+
res.on("data", (chunk) => { text += String(chunk ?? ""); });
|
|
98
|
+
res.on("end", answer);
|
|
99
|
+
res.on("aborted", answer);
|
|
100
|
+
res.on("error", answer);
|
|
101
|
+
});
|
|
102
|
+
// inactivity only — no total deadline
|
|
103
|
+
req.setTimeout(inactivityMs, () => req.destroy(new Error(`upload stalled (no socket activity for ${inactivityMs} ms)`)));
|
|
104
|
+
// A write-side reset can be emitted BEFORE the response that caused it is parsed, so
|
|
105
|
+
// no error decides on its own: the verdict is taken at close, when it is known whether
|
|
106
|
+
// a response arrived. Otherwise an early 507/413 would surface as EPIPE.
|
|
107
|
+
let writeError = null;
|
|
108
|
+
const recordError = (e) => { if (writeError === null)
|
|
109
|
+
writeError = e; };
|
|
110
|
+
req.on("error", recordError);
|
|
111
|
+
req.on("close", () => {
|
|
112
|
+
if (settled)
|
|
113
|
+
return;
|
|
114
|
+
if (status !== 0)
|
|
115
|
+
answer();
|
|
116
|
+
else
|
|
117
|
+
failWith(writeError ?? new Error("upload closed without a response"));
|
|
118
|
+
});
|
|
119
|
+
streams.pipeline(streams.Readable.fromWeb(body), req, recordError);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
export class NodeClient {
|
|
123
|
+
baseUrl;
|
|
124
|
+
contentBaseUrl;
|
|
125
|
+
fetchImpl;
|
|
126
|
+
constructor(opts = {}) {
|
|
127
|
+
this.baseUrl = (opts.baseUrl ?? "").replace(/\/$/, "");
|
|
128
|
+
this.contentBaseUrl = (opts.contentBaseUrl ?? opts.baseUrl ?? "").replace(/\/$/, "");
|
|
129
|
+
this.fetchImpl = opts.fetch ?? fetch;
|
|
130
|
+
}
|
|
131
|
+
url(path) {
|
|
132
|
+
return this.baseUrl + path;
|
|
133
|
+
}
|
|
134
|
+
contentUrl(path) {
|
|
135
|
+
return this.contentBaseUrl + path;
|
|
136
|
+
}
|
|
137
|
+
/** POST raw SignedTx protobuf bytes to /api/tx/submit. Never throws. */
|
|
138
|
+
async submitTx(signedTx) {
|
|
139
|
+
let resp;
|
|
140
|
+
try {
|
|
141
|
+
resp = await this.fetchImpl(this.url("/api/tx/submit"), {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: { "Content-Type": "application/x-protobuf", Accept: "application/json" },
|
|
144
|
+
body: signedTx,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
return { kind: "failed", reason: "internal", message: e instanceof Error ? e.message : String(e) };
|
|
149
|
+
}
|
|
150
|
+
let body;
|
|
151
|
+
try {
|
|
152
|
+
body = await resp.json();
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
return { kind: "failed", reason: "internal", message: `bad JSON: ${e instanceof Error ? e.message : String(e)}` };
|
|
156
|
+
}
|
|
157
|
+
return parseSubmit(body);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* POST a sender-auth-only body-form SignedTx to /api/channel/submit-da (098):
|
|
161
|
+
* the gateway node collects the channel's DA attestations over the overlay,
|
|
162
|
+
* assembles the fully-attested tx, and submits it. Use this for DA-enforced
|
|
163
|
+
* channels — the client does NOT collect attestations or build DA_ATTEST auths
|
|
164
|
+
* itself. Returns the commit outcome (or a `da_unavailable` failure if the DA
|
|
165
|
+
* group couldn't be mustered in time). Safe for non-DA channels too (the
|
|
166
|
+
* gateway submits immediately). Never throws.
|
|
167
|
+
*/
|
|
168
|
+
async submitTxWithDa(signedTx) {
|
|
169
|
+
let resp;
|
|
170
|
+
try {
|
|
171
|
+
resp = await this.fetchImpl(this.url("/api/channel/submit-da"), {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: { "Content-Type": "application/x-protobuf", Accept: "application/json" },
|
|
174
|
+
body: signedTx,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
return { kind: "failed", reason: "internal", message: e instanceof Error ? e.message : String(e) };
|
|
179
|
+
}
|
|
180
|
+
let body;
|
|
181
|
+
try {
|
|
182
|
+
body = await resp.json();
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
return { kind: "failed", reason: "internal", message: `bad JSON: ${e instanceof Error ? e.message : String(e)}` };
|
|
186
|
+
}
|
|
187
|
+
return parseSubmit(body);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Faucet identity claim (102): register `id` on-chain via the node-sponsored
|
|
191
|
+
* POST /api/identity/{prepare,create} — no funded sender and no admin key needed
|
|
192
|
+
* (the node sponsors 5000 credits). The PoP digest is recomputed LOCALLY and the
|
|
193
|
+
* claim aborts on mismatch, so the keys never sign server-chosen bytes. A 200
|
|
194
|
+
* means the sponsored CreateIdentity COMMITTED (the node commit-waits); an
|
|
195
|
+
* already-on-chain identity reports `exists`. Never throws.
|
|
196
|
+
*/
|
|
197
|
+
async claimIdentity(id) {
|
|
198
|
+
const digest = faucetClaimDigest(id);
|
|
199
|
+
const pubs = {
|
|
200
|
+
node_id: id.nodeId,
|
|
201
|
+
bls_pubkey_hex: bytesToHex(id.bls.pub),
|
|
202
|
+
ed25519_pubkey_hex: bytesToHex(id.ed.pub),
|
|
203
|
+
};
|
|
204
|
+
const post = async (path, body) => this.fetchImpl(this.url(path), {
|
|
205
|
+
method: "POST",
|
|
206
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
207
|
+
body: JSON.stringify(body),
|
|
208
|
+
});
|
|
209
|
+
try {
|
|
210
|
+
const prep = await post("/api/identity/prepare", pubs);
|
|
211
|
+
const p = (await prep.json().catch(() => ({})));
|
|
212
|
+
if (!prep.ok)
|
|
213
|
+
return { kind: "failed", error: p.error ?? `http_${prep.status}`, message: p.message ?? "" };
|
|
214
|
+
if ((p.tx_hash_hex ?? "").toLowerCase() !== bytesToHex(digest).toLowerCase()) {
|
|
215
|
+
return {
|
|
216
|
+
kind: "failed",
|
|
217
|
+
error: "digest_mismatch",
|
|
218
|
+
message: `server tx_hash ${p.tx_hash_hex} != locally computed PoP digest — refusing to sign`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const create = await post("/api/identity/create", {
|
|
222
|
+
...pubs,
|
|
223
|
+
bls_pop_sig_hex: bytesToHex(blsSign(digest, id.bls.priv)),
|
|
224
|
+
ed25519_pop_sig_hex: bytesToHex(edSign(digest, id.ed.priv)),
|
|
225
|
+
});
|
|
226
|
+
const c = (await create.json().catch(() => ({})));
|
|
227
|
+
if (create.ok)
|
|
228
|
+
return { kind: "committed", blockHeight: c.block_height ?? 0 };
|
|
229
|
+
if (c.error === "identity_already_exists")
|
|
230
|
+
return { kind: "exists" };
|
|
231
|
+
return { kind: "failed", error: c.error ?? `http_${create.status}`, message: c.message ?? "" };
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
return { kind: "failed", error: "internal", message: e instanceof Error ? e.message : String(e) };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** GET /api/identity/:nodeId → { nodeId, balance }, or null if not yet on-chain. */
|
|
238
|
+
async getIdentity(nodeId) {
|
|
239
|
+
const res = await this.fetchImpl(this.url(`/api/identity/${encodeURIComponent(nodeId)}`));
|
|
240
|
+
if (res.status === 404)
|
|
241
|
+
return null;
|
|
242
|
+
if (!res.ok)
|
|
243
|
+
throw new Error(`getIdentity ${nodeId}: HTTP ${res.status}`);
|
|
244
|
+
const b = (await res.json());
|
|
245
|
+
return { nodeId: b.node_id, balance: b.balance };
|
|
246
|
+
}
|
|
247
|
+
/** Latest committed round (chain tip), via the explorer blocks list (orderDesc). 0 if none. */
|
|
248
|
+
async currentRound() {
|
|
249
|
+
const res = await this.fetchImpl(this.url("/api/explorer/blocks?limit=1&offset=0"), {
|
|
250
|
+
headers: { Accept: "application/json" },
|
|
251
|
+
});
|
|
252
|
+
if (!res.ok)
|
|
253
|
+
throw new Error(`currentRound: HTTP ${res.status}`);
|
|
254
|
+
const b = (await res.json());
|
|
255
|
+
return b.blocks && b.blocks.length > 0 ? b.blocks[0].roundNum : 0;
|
|
256
|
+
}
|
|
257
|
+
/** Members of a group, from the on-chain group_members (/api/explorer/groups/:g/members). */
|
|
258
|
+
async getGroupMembers(group) {
|
|
259
|
+
const res = await this.fetchImpl(this.url(`/api/explorer/groups/${encodeURIComponent(group)}/members`), {
|
|
260
|
+
headers: { Accept: "application/json" },
|
|
261
|
+
});
|
|
262
|
+
if (!res.ok)
|
|
263
|
+
throw new Error(`getGroupMembers ${group}: HTTP ${res.status}`);
|
|
264
|
+
const b = (await res.json());
|
|
265
|
+
return b.members ?? [];
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Principal name search (`/api/explorer/search`) — the read behind a recipient picker.
|
|
269
|
+
*
|
|
270
|
+
* THREE node-side facts shape every caller, and they are the reason this wrapper does not
|
|
271
|
+
* pretend to be more than a transport (all three are issue #64):
|
|
272
|
+
*
|
|
273
|
+
* 1. a query shorter than 2 characters is REFUSED (400 `invalid_query`), so a caller that
|
|
274
|
+
* wants to filter on one keystroke cannot use this route at all;
|
|
275
|
+
* 2. the route applies NO result limit — `node_id LIKE '%q%'` with no LIMIT — so the caller
|
|
276
|
+
* must bound what it keeps, and unescaped wildcards in `q` match aggressively;
|
|
277
|
+
* 3. the rows come back UNORDERED and de-duplicated by `(nodeId, type)` only, so a name that
|
|
278
|
+
* is both an identity and a current committee member arrives TWICE.
|
|
279
|
+
*
|
|
280
|
+
* Returns the rows as given. Ranking, bounding and de-duplication belong to the caller until
|
|
281
|
+
* #64 lands.
|
|
282
|
+
*/
|
|
283
|
+
async searchPrincipals(q) {
|
|
284
|
+
const res = await this.fetchImpl(this.url(`/api/explorer/search?q=${encodeURIComponent(q)}`), {
|
|
285
|
+
headers: { Accept: "application/json" },
|
|
286
|
+
});
|
|
287
|
+
if (!res.ok)
|
|
288
|
+
throw new Error(`searchPrincipals ${q}: HTTP ${res.status}`);
|
|
289
|
+
const b = (await res.json());
|
|
290
|
+
return b.results ?? [];
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Recent committed transactions, newest first, decoded to their core view
|
|
294
|
+
* (`/api/explorer/transactions`).
|
|
295
|
+
*
|
|
296
|
+
* Used to resolve a submit whose outcome is unknown: a transaction id is a digest of the
|
|
297
|
+
* transaction's own fields, so it can be looked up rather than resubmitted. `limit` is capped
|
|
298
|
+
* at 200 by the node, and deep paging is expensive — each request re-walks committed blocks
|
|
299
|
+
* from the tip, decoding payloads, so treat this as a live tail and not a history API.
|
|
300
|
+
*/
|
|
301
|
+
async recentTransactions(limit = 50, offset = 0) {
|
|
302
|
+
const res = await this.fetchImpl(this.url(`/api/explorer/transactions?limit=${limit}&offset=${offset}`), { headers: { Accept: "application/json" } });
|
|
303
|
+
if (!res.ok)
|
|
304
|
+
throw new Error(`recentTransactions: HTTP ${res.status}`);
|
|
305
|
+
const b = (await res.json());
|
|
306
|
+
return (b.transactions ?? []).map((t) => ({ ...t, details: t.details ?? [] }));
|
|
307
|
+
}
|
|
308
|
+
/** All on-chain identity keys (paginated). Filter by nodeId/keyType/label client-side. */
|
|
309
|
+
async getKeys(limit = 500, offset = 0) {
|
|
310
|
+
const res = await this.fetchImpl(this.url(`/api/explorer/keys?limit=${limit}&offset=${offset}`), {
|
|
311
|
+
headers: { Accept: "application/json" },
|
|
312
|
+
});
|
|
313
|
+
if (!res.ok)
|
|
314
|
+
throw new Error(`getKeys: HTTP ${res.status}`);
|
|
315
|
+
const b = (await res.json());
|
|
316
|
+
return b.keys ?? [];
|
|
317
|
+
}
|
|
318
|
+
/** Publish raw bytes to this node's loopback content cache (139): POST /content -> 201 {key,size}. Throws on non-201.
|
|
319
|
+
*
|
|
320
|
+
* `opts.authorizedPrincipals` (142): principal names (identity or group) granted READ
|
|
321
|
+
* on the peer route, sent as `X-Evolver-Authorized-Principal` (comma-joined — the
|
|
322
|
+
* server splits; names can never contain a comma). Each name is resolved at POST
|
|
323
|
+
* time: unknown ⇒ HTTP 400 and nothing is stored. The grant set persists as the
|
|
324
|
+
* `.acl` sidecar on EVERY key of the object (blob, or manifest + all chunks).
|
|
325
|
+
* Omitted or an explicit empty array ⇒ an OPEN publish; a non-empty array whose
|
|
326
|
+
* entries are all blank throws locally (restriction was intended — never publish
|
|
327
|
+
* open by accident). */
|
|
328
|
+
async postContent(bytes, opts) {
|
|
329
|
+
return this.postContentCore("postContent", bytes, bytes.length, opts?.authorizedPrincipals);
|
|
330
|
+
}
|
|
331
|
+
/** Streaming publish (143): `size` is REQUIRED (it becomes Content-Length, which
|
|
332
|
+
* drives the node's up-front free-disk guard — every real caller knows the
|
|
333
|
+
* plaintext/ciphertext size). Grant semantics are identical to postContent. Throws
|
|
334
|
+
* on non-201 with the server's status + JSON (507 insufficient-storage, 413 too
|
|
335
|
+
* large, 400 unknown-principal).
|
|
336
|
+
*
|
|
337
|
+
* ON NODE the request goes through `node:http`/`node:https`, NOT fetch: undici does
|
|
338
|
+
* not apply backpressure to a ReadableStream request body — it drains the body into
|
|
339
|
+
* memory (measured RSS growth 0.89–0.93× of the body, vs flat via node:http), which
|
|
340
|
+
* FR-006 forbids. Browsers keep the fetch path (they never stream a body to a node). */
|
|
341
|
+
async postContentStream(body, opts) {
|
|
342
|
+
const label = "postContentStream";
|
|
343
|
+
const headers = publishHeaders(label, opts.size, opts.authorizedPrincipals);
|
|
344
|
+
const viaNode = await nodeStreamPost(this.contentUrl("/content"), headers, body, BODY_INACTIVITY_MS);
|
|
345
|
+
if (viaNode !== null)
|
|
346
|
+
return parsePublished(label, viaNode.status, viaNode.text, opts.size);
|
|
347
|
+
return this.postViaFetch(label, body, headers, opts.size);
|
|
348
|
+
}
|
|
349
|
+
async postContentCore(label, body, size, authorizedPrincipals) {
|
|
350
|
+
return this.postViaFetch(label, body, publishHeaders(label, size, authorizedPrincipals), size);
|
|
351
|
+
}
|
|
352
|
+
async postViaFetch(label, body, headers, size) {
|
|
353
|
+
// duplex is required by undici for a ReadableStream body; harmless for bytes.
|
|
354
|
+
const init = { method: "POST", headers, body, duplex: "half" };
|
|
355
|
+
const resp = await this.fetchImpl(this.contentUrl("/content"), init);
|
|
356
|
+
const text = resp.status === 201 ? await resp.text() : await resp.text().catch(() => "");
|
|
357
|
+
return parsePublished(label, resp.status, text, size);
|
|
358
|
+
}
|
|
359
|
+
/** Fetch bytes by content-cache key (139): GET /content/{key}. Returns null on 404 (no holder reachable). */
|
|
360
|
+
async getContent(key) {
|
|
361
|
+
const got = await this.getContentStream(key);
|
|
362
|
+
if (got === null)
|
|
363
|
+
return null;
|
|
364
|
+
const parts = [];
|
|
365
|
+
const reader = got.stream.getReader();
|
|
366
|
+
for (;;) {
|
|
367
|
+
const { done, value } = await reader.read();
|
|
368
|
+
if (done)
|
|
369
|
+
break;
|
|
370
|
+
parts.push(value);
|
|
371
|
+
}
|
|
372
|
+
const out = new Uint8Array(parts.reduce((n, c) => n + c.length, 0));
|
|
373
|
+
let off = 0;
|
|
374
|
+
for (const c of parts) {
|
|
375
|
+
out.set(c, off);
|
|
376
|
+
off += c.length;
|
|
377
|
+
}
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
380
|
+
/** Streaming fetch (143): null on 404; `size` from Content-Length (the node always
|
|
381
|
+
* sets it). CALLER CONTRACT: the transfer is complete iff the stream yields exactly
|
|
382
|
+
* `size` bytes — the node signals a mid-serve failure (e.g. chunk verification) by
|
|
383
|
+
* ABORTING the connection, so a short read errors the stream and ALL output must be
|
|
384
|
+
* discarded. `range` maps to a single HTTP Range (both bounds inclusive). No total
|
|
385
|
+
* deadline is applied: Node's fetch enforces a 300 s INACTIVITY (bodyTimeout) guard
|
|
386
|
+
* between chunks, which is the FR-016 semantic. */
|
|
387
|
+
async getContentStream(key, opts) {
|
|
388
|
+
const headers = {};
|
|
389
|
+
if (opts?.range)
|
|
390
|
+
headers["Range"] = `bytes=${opts.range.from}-${opts.range.toInclusive}`;
|
|
391
|
+
// The key is encoded, not interpolated: callers pre-validate 64-hex, but a path
|
|
392
|
+
// segment built from a value that arrived over the wire must not be able to re-point
|
|
393
|
+
// the request at another route.
|
|
394
|
+
const resp = await this.fetchImpl(this.contentUrl(`/content/${encodeURIComponent(key)}`), { method: "GET", headers });
|
|
395
|
+
if (resp.status === 404)
|
|
396
|
+
return null;
|
|
397
|
+
if (!resp.ok)
|
|
398
|
+
throw new Error(`getContentStream ${key.slice(0, 12)}: HTTP ${resp.status}`);
|
|
399
|
+
const size = Number(resp.headers.get("content-length") ?? -1);
|
|
400
|
+
if (!Number.isSafeInteger(size) || size < 0)
|
|
401
|
+
throw new Error(`getContentStream ${key.slice(0, 12)}: missing Content-Length`);
|
|
402
|
+
if (resp.body === null)
|
|
403
|
+
throw new Error(`getContentStream ${key.slice(0, 12)}: no body`);
|
|
404
|
+
// enforce the exact-length contract even if the runtime tolerates early close
|
|
405
|
+
let seen = 0;
|
|
406
|
+
const check = new TransformStream({
|
|
407
|
+
transform(chunk, ctrl) { seen += chunk.length; ctrl.enqueue(chunk); },
|
|
408
|
+
flush() { if (seen !== size)
|
|
409
|
+
throw new Error(`content transfer aborted (${seen}/${size} bytes)`); },
|
|
410
|
+
});
|
|
411
|
+
return { stream: resp.body.pipeThrough(check), size };
|
|
412
|
+
}
|
|
413
|
+
/** GET /api/channel/next?round&index — one poll of the ordered channel stream. */
|
|
414
|
+
async pullChannel(round, index) {
|
|
415
|
+
const res = await this.fetchImpl(this.url(`/api/channel/next?round=${round}&index=${index}`));
|
|
416
|
+
const text = await res.text();
|
|
417
|
+
try {
|
|
418
|
+
return { httpStatus: res.status, ...JSON.parse(text) };
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
return { httpStatus: res.status, status: "error", message: text };
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Drive the channel cursor forward, invoking onDeliver per ordered message.
|
|
426
|
+
* Returns when `max` deliveries seen or after `idleStops` consecutive
|
|
427
|
+
* not-ready / body-pending polls.
|
|
428
|
+
*/
|
|
429
|
+
async drainChannel(start, onDeliver, opts = {}) {
|
|
430
|
+
const max = opts.max ?? Infinity;
|
|
431
|
+
const idleStops = opts.idleStops ?? 40;
|
|
432
|
+
const pollMs = opts.pollMs ?? 250;
|
|
433
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
434
|
+
let { round, index } = start;
|
|
435
|
+
let seen = 0;
|
|
436
|
+
let idle = 0;
|
|
437
|
+
while (seen < max && idle < idleStops) {
|
|
438
|
+
const r = await this.pullChannel(round, index);
|
|
439
|
+
switch (r.status) {
|
|
440
|
+
case "deliver":
|
|
441
|
+
round = Number(r.round);
|
|
442
|
+
index = Number(r.index);
|
|
443
|
+
await onDeliver({
|
|
444
|
+
round,
|
|
445
|
+
index,
|
|
446
|
+
txId: r.txId ?? "",
|
|
447
|
+
ledgerId: r.ledgerId ?? "",
|
|
448
|
+
sender: r.sender ?? "",
|
|
449
|
+
body: base64ToBytes(r.body ?? ""),
|
|
450
|
+
});
|
|
451
|
+
index += 1;
|
|
452
|
+
seen += 1;
|
|
453
|
+
idle = 0;
|
|
454
|
+
break;
|
|
455
|
+
case "end-of-block":
|
|
456
|
+
round = Number(r.round) + 1;
|
|
457
|
+
index = 0;
|
|
458
|
+
idle = 0;
|
|
459
|
+
break;
|
|
460
|
+
case "body-pending":
|
|
461
|
+
case "not-ready":
|
|
462
|
+
idle += 1;
|
|
463
|
+
await sleep(pollMs);
|
|
464
|
+
break;
|
|
465
|
+
default:
|
|
466
|
+
throw new Error(`channel pull error: ${JSON.stringify(r)}`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return { round, index };
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function parseSubmit(body) {
|
|
473
|
+
if (typeof body !== "object" || body === null) {
|
|
474
|
+
return { kind: "failed", reason: "internal", message: "non-object response" };
|
|
475
|
+
}
|
|
476
|
+
const b = body;
|
|
477
|
+
const result = typeof b.result === "string" ? b.result : "";
|
|
478
|
+
if (result === "committed" && typeof b.tx_id_hex === "string")
|
|
479
|
+
return { kind: "committed", txIdHex: b.tx_id_hex };
|
|
480
|
+
if (result === "timeout" && typeof b.tx_id_hex === "string")
|
|
481
|
+
return { kind: "timeout", txIdHex: b.tx_id_hex };
|
|
482
|
+
// 155: `expired` (409) and `backpressure` (503) are two more shapes the node emits
|
|
483
|
+
// (`SubmitResponder`), and neither was recognised here — both landed in the catch-all below as
|
|
484
|
+
// `internal`, which is the SAME answer as "the response could not be read at all". That
|
|
485
|
+
// matters in one direction especially: an EXPIRED transaction provably never committed, so
|
|
486
|
+
// reporting it as unknown makes a caller keep looking for something that cannot exist. This is
|
|
487
|
+
// the same defect 154 fixed for `reason` codes, one level up in the envelope.
|
|
488
|
+
// 155 review: the `?wait=false` receipt. Admitted, not committed, id supplied — which is
|
|
489
|
+
// exactly the `timeout` contract ("outcome not yet known, here is the id"), and nothing like
|
|
490
|
+
// `internal` ("we could not read the answer"). Emitted by SubmitTxHandler, not SubmitResponder,
|
|
491
|
+
// which is why the first pass missed it.
|
|
492
|
+
if (result === "accepted" && typeof b.tx_id_hex === "string")
|
|
493
|
+
return { kind: "timeout", txIdHex: b.tx_id_hex };
|
|
494
|
+
if (result === "expired")
|
|
495
|
+
return { kind: "failed", reason: "ttl_expired", message: "the transaction's TTL passed before it was ordered" };
|
|
496
|
+
if (result === "backpressure") {
|
|
497
|
+
const reason = typeof b.reason === "string" ? asFailureReason(b.reason) : "queue_full";
|
|
498
|
+
const message = typeof b.message === "string" ? b.message : "the node is shedding load";
|
|
499
|
+
return { kind: "failed", reason, message };
|
|
500
|
+
}
|
|
501
|
+
if (result === "failed") {
|
|
502
|
+
const reason = typeof b.reason === "string" ? asFailureReason(b.reason) : "internal";
|
|
503
|
+
const message = typeof b.message === "string" ? b.message : "";
|
|
504
|
+
return { kind: "failed", reason, message };
|
|
505
|
+
}
|
|
506
|
+
return { kind: "failed", reason: "internal", message: `unrecognized response: ${JSON.stringify(body)}` };
|
|
507
|
+
}
|
|
508
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/bodies.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { KeyEntry } from "./types.js";
|
|
2
|
+
export declare const LEDGER: {
|
|
3
|
+
readonly identity: "ce.evolver.ledger.identity";
|
|
4
|
+
readonly groups: "ce.evolver.ledger.groups";
|
|
5
|
+
readonly owners: "ce.evolver.ledger.owners";
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Inner CreateIdentityTxBody — the PROTO body that goes on the wire.
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ 148: this is NO LONGER the PoP preimage. Proof of possession uses the canonical field
|
|
11
|
+
* encoding (`popCreateIdentity` in ./generated/codecs), not a hash of these proto bytes. The two
|
|
12
|
+
* were the same function before, which is why `withPoP` existed; the wire body still needs proto,
|
|
13
|
+
* so the function stays — it just no longer serves double duty.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createIdentityInner(nodeId: string, initialCredit: number | bigint, keys: KeyEntry[], withPoP: boolean): Uint8Array;
|
|
16
|
+
/** Wrap a CreateIdentityTxBody as the tx_body (TxBody.create_identity = 1). */
|
|
17
|
+
export declare function createIdentityBody(inner: Uint8Array): Uint8Array;
|
|
18
|
+
export interface AddKeyArgs {
|
|
19
|
+
publicKey: Uint8Array;
|
|
20
|
+
keyType: string;
|
|
21
|
+
keyLabel: string;
|
|
22
|
+
popSignature: Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
/** Inner AddKeyTxBody: 1 public_key | 2 key_type | 3 key_label | 5 pop_signature (omit when empty).
|
|
25
|
+
*
|
|
26
|
+
* ⚠️ This is NOT the PoP preimage and has not been since 148 — that is `popAddKey` in
|
|
27
|
+
* ./generated/codecs. This comment claimed otherwise for two features, which is the exact reason
|
|
28
|
+
* a recipe is now stated once, as data, instead of in prose beside each function that touches it. */
|
|
29
|
+
export declare function addKeyInner(args: AddKeyArgs): Uint8Array;
|
|
30
|
+
export declare function addKeyBody(args: AddKeyArgs): Uint8Array;
|
|
31
|
+
export interface ReplaceKeyArgs {
|
|
32
|
+
publicKey: Uint8Array;
|
|
33
|
+
keyType: string;
|
|
34
|
+
keyLabel: string;
|
|
35
|
+
popSignature: Uint8Array;
|
|
36
|
+
}
|
|
37
|
+
/** Inner ReplaceKeyTxBody: 1 public_key | 2 key_type | 3 key_label | 5 pop_signature (omit when empty).
|
|
38
|
+
* Mirrors AddKeyTxBody exactly on the wire. The PoP preimage is `popReplaceKey` in
|
|
39
|
+
* ./generated/codecs — a DIFFERENT digest from AddKey's despite the identical layout, because the
|
|
40
|
+
* two descriptions carry different tags. */
|
|
41
|
+
export declare function replaceKeyInner(args: ReplaceKeyArgs): Uint8Array;
|
|
42
|
+
export declare function replaceKeyBody(args: ReplaceKeyArgs): Uint8Array;
|
|
43
|
+
export declare function deleteKeyBody(args: {
|
|
44
|
+
keyType: string;
|
|
45
|
+
keyLabel: string;
|
|
46
|
+
}): Uint8Array;
|
|
47
|
+
/** One instruction of a 154 credit transfer: give `amount` credit to `recipient`. */
|
|
48
|
+
export interface TransferEntryArg {
|
|
49
|
+
recipient: string;
|
|
50
|
+
/** >= 1. A `bigint`, NOT a `number`: a credit amount is exactly the kind of value
|
|
51
|
+
* Principle VIII exists for — beyond 2^53 a JS number silently loses precision. */
|
|
52
|
+
amount: bigint;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Credit transfer (154): move credit from the signing identity to 1..20 recipients.
|
|
56
|
+
*
|
|
57
|
+
* TransferTxBody{ 1 transfers (repeated) }, TransferEntry{ 1 recipient, 2 amount },
|
|
58
|
+
* TxBody.transfer = 6.
|
|
59
|
+
*
|
|
60
|
+
* The entries are encoded IN THE ORDER GIVEN and nothing here sorts, merges or
|
|
61
|
+
* deduplicates them — the order is part of the meaning, because it decides which
|
|
62
|
+
* transfers survive if the sender runs short at apply time. The node's own rules
|
|
63
|
+
* (1..20 entries, amounts >= 1, distinct recipients, none of them the sender,
|
|
64
|
+
* every recipient an existing identity) are enforced there and refused at submit;
|
|
65
|
+
* this function encodes what it is given.
|
|
66
|
+
*/
|
|
67
|
+
export declare function transferBody(entries: TransferEntryArg[]): Uint8Array;
|
|
68
|
+
export declare function createGroupBody(name: string): Uint8Array;
|
|
69
|
+
export declare function addMemberBody(groupName: string, memberNodeId: string): Uint8Array;
|
|
70
|
+
export declare function removeMemberBody(groupName: string, memberNodeId: string): Uint8Array;
|
|
71
|
+
export declare function claimBody(args: {
|
|
72
|
+
ledgerId: string;
|
|
73
|
+
groupOwner?: string;
|
|
74
|
+
daGroup?: string;
|
|
75
|
+
daThresholdM?: number;
|
|
76
|
+
tollAmount?: number | bigint;
|
|
77
|
+
tollRecipient?: string;
|
|
78
|
+
}): Uint8Array;
|
|
79
|
+
export declare function removeOwnerBody(ledgerId: string): Uint8Array;
|
|
80
|
+
export declare function updateChannelTollBody(args: {
|
|
81
|
+
ledgerId: string;
|
|
82
|
+
tollAmount?: number | bigint;
|
|
83
|
+
tollRecipient?: string;
|
|
84
|
+
}): Uint8Array;
|
|
85
|
+
export declare function channelBody(payload: Uint8Array): Uint8Array;
|
|
86
|
+
//# sourceMappingURL=bodies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bodies.d.ts","sourceRoot":"","sources":["../src/bodies.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAeX;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GAAG,MAAM,EAC9B,IAAI,EAAE,QAAQ,EAAE,EAChB,OAAO,EAAE,OAAO,GACf,UAAU,CAOZ;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEhE;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,UAAU,CAAC;CAC1B;AAED;;;;sGAIsG;AACtG,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAOxD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEvD;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,UAAU,CAAC;CAC1B;AAED;;;6CAG6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAOhE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAE/D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAIrF;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB;wFACoF;IACpF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,UAAU,CAKpE;AAKD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAExD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAEjF;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAEpF;AASD,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,UAAU,CAQb;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE5D;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,UAAU,CAKb;AAID,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAE3D"}
|