@hesohq/verify-wasm 0.1.0 → 0.1.1-dev.19
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/heso_wasm.d.ts +92 -11
- package/heso_wasm.js +140 -6
- package/heso_wasm_bg.wasm +0 -0
- package/heso_wasm_bg.wasm.d.ts +11 -7
- package/package.json +4 -1
package/heso_wasm.d.ts
CHANGED
|
@@ -31,6 +31,10 @@ export class ApprovalTokenClaims {
|
|
|
31
31
|
* Base64-encoded Ed25519 public key of the approver.
|
|
32
32
|
*/
|
|
33
33
|
approver_public_key: string;
|
|
34
|
+
/**
|
|
35
|
+
* The verdict the human signed into the token: `"approved"` or `"rejected"`.
|
|
36
|
+
*/
|
|
37
|
+
decision: string;
|
|
34
38
|
/**
|
|
35
39
|
* Expiry as Unix seconds (`BigInt`).
|
|
36
40
|
*/
|
|
@@ -144,6 +148,43 @@ export function chainHashHex(prev_hex: string, action_hex: string): string;
|
|
|
144
148
|
*/
|
|
145
149
|
export function contentHash(content_json: string): string;
|
|
146
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Return the EXACT bytes a hosted approver must sign to co-sign a suspended
|
|
153
|
+
* (L0) action into an L1 receipt: `APPROVAL_SIGNING_DOMAIN` (17 bytes) ++
|
|
154
|
+
* `action_canonical_bytes` of the promoted L1 body.
|
|
155
|
+
*
|
|
156
|
+
* The browser promotes the suspended L0 body to its L1 form with the same pure
|
|
157
|
+
* builder the operator process uses
|
|
158
|
+
* ([`heso_action::receipt::build_l1_content_anchored`]), then derives the
|
|
159
|
+
* approval payload ([`approval_cosign_payload`]). This compiles under
|
|
160
|
+
* heso-wasm's DEFAULT heso-action features (NO `sign`) precisely because both
|
|
161
|
+
* builders live in the always-compiled `receipt.rs`; the wasm surface never
|
|
162
|
+
* holds a key, so it only ASSEMBLES the bytes a remote signer returns a detached
|
|
163
|
+
* signature over.
|
|
164
|
+
*
|
|
165
|
+
* ANCHORED BODIES: unlike the bare [`build_l1_content`] path (which fails closed
|
|
166
|
+
* on any present anchor), this browser export ACCEPTS a suspended body that
|
|
167
|
+
* already carries a relayed `time_anchor`. The operator will later sign over
|
|
168
|
+
* that same full anchored body, so the approver must co-sign the anchored
|
|
169
|
+
* canonical too. We lift the anchor off the suspended input and thread it
|
|
170
|
+
* through `build_l1_content_anchored` as the relayed-anchor argument: the
|
|
171
|
+
* `AnchorOnAsyncL1Path` guard (which only fires on the SUSPENDED INPUT) no longer
|
|
172
|
+
* rejects, and the anchor is stamped BEFORE the final `action_hash` so the
|
|
173
|
+
* resulting body — and therefore the approver payload — is byte-identical to
|
|
174
|
+
* what the operator signs. An anchorless body promotes EXACTLY as before
|
|
175
|
+
* (`anchor = None`), so the f599f21b single-approver L1 golden never moves.
|
|
176
|
+
*
|
|
177
|
+
* `suspendedContentJson` — the suspended L0 `ActionContent` JSON (optionally
|
|
178
|
+
* already carrying a relayed `time_anchor`).
|
|
179
|
+
* `approverRecordJson` — the human's `ApproverRecord` (decision, identity,
|
|
180
|
+
* reason, decided_at, sla_minutes) as JSON.
|
|
181
|
+
*
|
|
182
|
+
* Throws a `JsError` with a stable `[CODE]` prefix per [`BuildL1Error`]:
|
|
183
|
+
* `[AlreadyDecided]` (the body is already decided or is not a clean L0). The
|
|
184
|
+
* `[AnchorOnAsyncL1Path]` reject is RELAXED here — a present anchor is accepted.
|
|
185
|
+
*/
|
|
186
|
+
export function l1CosignPayload(suspended_content_json: string, approver_record_json: string): Uint8Array;
|
|
187
|
+
|
|
147
188
|
/**
|
|
148
189
|
* Parse + validate policy TOML, running the load-time dangerous-lane floor check.
|
|
149
190
|
* Throws a `[PARSE]` or `[FLOOR_BYPASS]` `JsError` on failure; returns nothing on
|
|
@@ -161,6 +202,35 @@ export function parsePolicy(toml_src: string): void;
|
|
|
161
202
|
*/
|
|
162
203
|
export function policyRulesFromToml(toml_src: string): string;
|
|
163
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Return the EXACT bytes ONE approver must sign to co-sign a suspended (L0)
|
|
207
|
+
* action under the multi-approver k-of-n QUORUM lane:
|
|
208
|
+
* `APPROVAL_SIGNING_DOMAIN` (17 bytes) ++ `multi_approver_canonical` of the quorum
|
|
209
|
+
* body with `approvers = [thisRecord]` ONLY. (A quorum receipt derives L1 WITH a
|
|
210
|
+
* multi_approval block — not a higher level.)
|
|
211
|
+
*
|
|
212
|
+
* Per the two-canonical (M-B) rule each approver vouches ONLY their own record,
|
|
213
|
+
* never the assembled set: the browser promotes the suspended L0 body to the
|
|
214
|
+
* quorum base ([`build_quorum_base`] — `multi_approval = {threshold, roster,
|
|
215
|
+
* approvers: []}`), folds in this single record, and derives the per-record
|
|
216
|
+
* approval payload ([`multi_approval_cosign_payload`]). Both builders live in the
|
|
217
|
+
* always-compiled `receipt.rs`, so this compiles under heso-wasm's DEFAULT
|
|
218
|
+
* heso-action features (NO `sign`); the wasm surface never holds a key, it only
|
|
219
|
+
* ASSEMBLES the bytes a remote signer returns a detached signature over. The
|
|
220
|
+
* key-holding assembler [`heso_action::sign::assemble_quorum_from_parts`] verifies
|
|
221
|
+
* each returned signature over exactly these bytes.
|
|
222
|
+
*
|
|
223
|
+
* `suspendedContentJson` — the suspended L0 `ActionContent` JSON.
|
|
224
|
+
* `threshold` — the k-of-n approval threshold (`>= 1`).
|
|
225
|
+
* `rosterJson` — JSON array of base64 admissible approver public keys.
|
|
226
|
+
* `approverRecordJson` — THIS approver's `ApproverRecord` as JSON.
|
|
227
|
+
*
|
|
228
|
+
* Throws a `JsError` with a stable `[CODE]` prefix per [`BuildQuorumError`]:
|
|
229
|
+
* `[AnchorOnAsyncL1Path]`, `[AlreadyDecided]`, `[ThresholdZero]`, or
|
|
230
|
+
* `[EmptyRoster]`.
|
|
231
|
+
*/
|
|
232
|
+
export function quorumCosignPayload(suspended_content_json: string, threshold: number, roster_json: string, approver_record_json: string): Uint8Array;
|
|
233
|
+
|
|
164
234
|
/**
|
|
165
235
|
* Render a single rule (JSON [`PolicyRule`]) into the canonical English sentence
|
|
166
236
|
* — the SAME `rule_display` stamped on signed receipts. Replaces the drifting JS
|
|
@@ -189,8 +259,11 @@ export function validateNoFloorBypass(rules_json: string): void;
|
|
|
189
259
|
*
|
|
190
260
|
* Never panics — structural failures return an `ActionVerdict` with
|
|
191
261
|
* `verdict = "Malformed:…"`. This is the browser replacement for the
|
|
192
|
-
* `verifyReceipt` function in `crypto.ts`, backed by the
|
|
193
|
-
*
|
|
262
|
+
* `verifyReceipt` function in `crypto.ts`, backed by the SAME Rust JCS +
|
|
263
|
+
* BLAKE3 + Ed25519 core as Node for canonicalization, hashing, and signature
|
|
264
|
+
* verification. NOTE: this is NOT byte-identical to Node for EVERY receipt —
|
|
265
|
+
* the `tsa` feature is OFF here, so a TIME-ANCHORED receipt that Node verifies
|
|
266
|
+
* against its TSA stack is handled differently on the browser surface.
|
|
194
267
|
*/
|
|
195
268
|
export function verifyActionReceipt(receipt_bytes: Uint8Array): ActionVerdict;
|
|
196
269
|
|
|
@@ -206,9 +279,11 @@ export function verifyActionReceipt(receipt_bytes: Uint8Array): ActionVerdict;
|
|
|
206
279
|
* `now_unix_secs` — current time as BigInt Unix seconds
|
|
207
280
|
* `seen_nonces` — array of already-seen 32-byte nonces (Uint8Array each)
|
|
208
281
|
* `required_scope` — the required scope string
|
|
282
|
+
* `required_decision` — the verdict the token must carry ("approved"/"rejected"),
|
|
283
|
+
* NON-DEFAULTED (the SEC-02 decision binding)
|
|
209
284
|
* `registered_keys_b64` — array of base64 Ed25519 public keys on the allowlist
|
|
210
285
|
*/
|
|
211
|
-
export function verifyApprovalToken(token: Uint8Array, action_canonical: Uint8Array, now_unix_secs: bigint, seen_nonces: Array<any>, required_scope: string, registered_keys_b64: Array<any>): ApprovalTokenClaims;
|
|
286
|
+
export function verifyApprovalToken(token: Uint8Array, action_canonical: Uint8Array, now_unix_secs: bigint, seen_nonces: Array<any>, required_scope: string, required_decision: string, registered_keys_b64: Array<any>): ApprovalTokenClaims;
|
|
212
287
|
|
|
213
288
|
/**
|
|
214
289
|
* Verify an ordered array of `ActionReceipt`s as a tamper-evident chain.
|
|
@@ -236,9 +311,11 @@ export function verifyConsistency(old_size: number, old_root_hex: string, new_si
|
|
|
236
311
|
* `action_hash` — the raw 32-byte BLAKE3 action digest being authorized
|
|
237
312
|
* `approval_token` — the human co-sign bearer token presented by K
|
|
238
313
|
* `required_scope` — the required scope string
|
|
314
|
+
* `required_decision` — the verdict the co-sign must carry ("approved"/"rejected"),
|
|
315
|
+
* NON-DEFAULTED (the SEC-02 decision binding)
|
|
239
316
|
* `now_unix_secs` — current time as BigInt Unix seconds
|
|
240
317
|
*/
|
|
241
|
-
export function verifyDelegation(wire: Uint8Array, registered_operator_key: Uint8Array, action_hash: Uint8Array, approval_token: Uint8Array, required_scope: string, now_unix_secs: bigint): VerifiedDelegation;
|
|
318
|
+
export function verifyDelegation(wire: Uint8Array, registered_operator_key: Uint8Array, action_hash: Uint8Array, approval_token: Uint8Array, required_scope: string, required_decision: string, now_unix_secs: bigint): VerifiedDelegation;
|
|
242
319
|
|
|
243
320
|
/**
|
|
244
321
|
* RFC-6962 inclusion proof verification (SHA-256 Merkle tree).
|
|
@@ -290,21 +367,29 @@ export interface InitOutput {
|
|
|
290
367
|
readonly __wbg_set_approvaltokenclaims_nonce: (a: number, b: any) => void;
|
|
291
368
|
readonly __wbg_get_approvaltokenclaims_expiry_unix_secs: (a: number) => any;
|
|
292
369
|
readonly __wbg_set_approvaltokenclaims_expiry_unix_secs: (a: number, b: any) => void;
|
|
370
|
+
readonly __wbg_get_approvaltokenclaims_decision: (a: number) => [number, number];
|
|
293
371
|
readonly __wbg_get_approvaltokenclaims_scope: (a: number) => [number, number];
|
|
294
372
|
readonly __wbg_get_approvaltokenclaims_approver_public_key: (a: number) => [number, number];
|
|
373
|
+
readonly __wbg_set_approvaltokenclaims_approver_public_key: (a: number, b: number, c: number) => void;
|
|
295
374
|
readonly __wbg_verifieddelegation_free: (a: number, b: number) => void;
|
|
375
|
+
readonly __wbg_get_verifieddelegation_authorized_key: (a: number) => any;
|
|
376
|
+
readonly __wbg_set_verifieddelegation_authorized_key: (a: number, b: any) => void;
|
|
296
377
|
readonly __wbg_get_verifieddelegation_sub: (a: number) => [number, number];
|
|
297
378
|
readonly __wbg_get_verifieddelegation_scope: (a: number) => [number, number];
|
|
379
|
+
readonly __wbg_get_verifieddelegation_expiry_unix_secs: (a: number) => any;
|
|
380
|
+
readonly __wbg_set_verifieddelegation_expiry_unix_secs: (a: number, b: any) => void;
|
|
298
381
|
readonly __wbg_get_verifieddelegation_not_before_unix_secs: (a: number) => any;
|
|
299
382
|
readonly __wbg_set_verifieddelegation_not_before_unix_secs: (a: number, b: any) => void;
|
|
300
383
|
readonly verifyActionReceipt: (a: number, b: number) => number;
|
|
301
384
|
readonly actionCanonicalBytes: (a: number, b: number) => [number, number, number];
|
|
385
|
+
readonly l1CosignPayload: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
386
|
+
readonly quorumCosignPayload: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
|
|
302
387
|
readonly contentHash: (a: number, b: number) => [number, number, number, number];
|
|
303
388
|
readonly anchoredContentHash: (a: number, b: number) => [number, number, number, number];
|
|
304
389
|
readonly shortHash: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
305
390
|
readonly chainHashHex: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
306
|
-
readonly verifyApprovalToken: (a: number, b: number, c: number, d: number, e: any, f: any, g: number, h: number, i: any) => [number, number, number];
|
|
307
|
-
readonly verifyDelegation: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: any) => [number, number, number];
|
|
391
|
+
readonly verifyApprovalToken: (a: number, b: number, c: number, d: number, e: any, f: any, g: number, h: number, i: number, j: number, k: any) => [number, number, number];
|
|
392
|
+
readonly verifyDelegation: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: any) => [number, number, number];
|
|
308
393
|
readonly verifyChain: (a: number, b: number) => [number, number, number];
|
|
309
394
|
readonly verifySessionChain: (a: number, b: number) => [number, number, number];
|
|
310
395
|
readonly verifySessionChainWithRotation: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
|
|
@@ -314,12 +399,8 @@ export interface InitOutput {
|
|
|
314
399
|
readonly ruleToSentence: (a: number, b: number) => [number, number, number, number];
|
|
315
400
|
readonly policyRulesFromToml: (a: number, b: number) => [number, number, number, number];
|
|
316
401
|
readonly validateNoFloorBypass: (a: number, b: number) => [number, number];
|
|
317
|
-
readonly
|
|
318
|
-
readonly __wbg_set_verifieddelegation_expiry_unix_secs: (a: number, b: any) => void;
|
|
319
|
-
readonly __wbg_get_verifieddelegation_authorized_key: (a: number) => any;
|
|
320
|
-
readonly __wbg_get_verifieddelegation_expiry_unix_secs: (a: number) => any;
|
|
402
|
+
readonly __wbg_set_approvaltokenclaims_decision: (a: number, b: number, c: number) => void;
|
|
321
403
|
readonly __wbg_set_approvaltokenclaims_scope: (a: number, b: number, c: number) => void;
|
|
322
|
-
readonly __wbg_set_approvaltokenclaims_approver_public_key: (a: number, b: number, c: number) => void;
|
|
323
404
|
readonly __wbg_set_verifieddelegation_sub: (a: number, b: number, c: number) => void;
|
|
324
405
|
readonly __wbg_set_verifieddelegation_scope: (a: number, b: number, c: number) => void;
|
|
325
406
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
package/heso_wasm.js
CHANGED
|
@@ -113,6 +113,22 @@ export class ApprovalTokenClaims {
|
|
|
113
113
|
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* The verdict the human signed into the token: `"approved"` or `"rejected"`.
|
|
118
|
+
* @returns {string}
|
|
119
|
+
*/
|
|
120
|
+
get decision() {
|
|
121
|
+
let deferred1_0;
|
|
122
|
+
let deferred1_1;
|
|
123
|
+
try {
|
|
124
|
+
const ret = wasm.__wbg_get_approvaltokenclaims_decision(this.__wbg_ptr);
|
|
125
|
+
deferred1_0 = ret[0];
|
|
126
|
+
deferred1_1 = ret[1];
|
|
127
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
128
|
+
} finally {
|
|
129
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
116
132
|
/**
|
|
117
133
|
* Expiry as Unix seconds (`BigInt`).
|
|
118
134
|
* @returns {bigint}
|
|
@@ -154,6 +170,15 @@ export class ApprovalTokenClaims {
|
|
|
154
170
|
const len0 = WASM_VECTOR_LEN;
|
|
155
171
|
wasm.__wbg_set_approvaltokenclaims_approver_public_key(this.__wbg_ptr, ptr0, len0);
|
|
156
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* The verdict the human signed into the token: `"approved"` or `"rejected"`.
|
|
175
|
+
* @param {string} arg0
|
|
176
|
+
*/
|
|
177
|
+
set decision(arg0) {
|
|
178
|
+
const ptr0 = passStringToWasm0(arg0, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
179
|
+
const len0 = WASM_VECTOR_LEN;
|
|
180
|
+
wasm.__wbg_set_approvaltokenclaims_decision(this.__wbg_ptr, ptr0, len0);
|
|
181
|
+
}
|
|
157
182
|
/**
|
|
158
183
|
* Expiry as Unix seconds (`BigInt`).
|
|
159
184
|
* @param {bigint} arg0
|
|
@@ -511,6 +536,56 @@ export function contentHash(content_json) {
|
|
|
511
536
|
}
|
|
512
537
|
}
|
|
513
538
|
|
|
539
|
+
/**
|
|
540
|
+
* Return the EXACT bytes a hosted approver must sign to co-sign a suspended
|
|
541
|
+
* (L0) action into an L1 receipt: `APPROVAL_SIGNING_DOMAIN` (17 bytes) ++
|
|
542
|
+
* `action_canonical_bytes` of the promoted L1 body.
|
|
543
|
+
*
|
|
544
|
+
* The browser promotes the suspended L0 body to its L1 form with the same pure
|
|
545
|
+
* builder the operator process uses
|
|
546
|
+
* ([`heso_action::receipt::build_l1_content_anchored`]), then derives the
|
|
547
|
+
* approval payload ([`approval_cosign_payload`]). This compiles under
|
|
548
|
+
* heso-wasm's DEFAULT heso-action features (NO `sign`) precisely because both
|
|
549
|
+
* builders live in the always-compiled `receipt.rs`; the wasm surface never
|
|
550
|
+
* holds a key, so it only ASSEMBLES the bytes a remote signer returns a detached
|
|
551
|
+
* signature over.
|
|
552
|
+
*
|
|
553
|
+
* ANCHORED BODIES: unlike the bare [`build_l1_content`] path (which fails closed
|
|
554
|
+
* on any present anchor), this browser export ACCEPTS a suspended body that
|
|
555
|
+
* already carries a relayed `time_anchor`. The operator will later sign over
|
|
556
|
+
* that same full anchored body, so the approver must co-sign the anchored
|
|
557
|
+
* canonical too. We lift the anchor off the suspended input and thread it
|
|
558
|
+
* through `build_l1_content_anchored` as the relayed-anchor argument: the
|
|
559
|
+
* `AnchorOnAsyncL1Path` guard (which only fires on the SUSPENDED INPUT) no longer
|
|
560
|
+
* rejects, and the anchor is stamped BEFORE the final `action_hash` so the
|
|
561
|
+
* resulting body — and therefore the approver payload — is byte-identical to
|
|
562
|
+
* what the operator signs. An anchorless body promotes EXACTLY as before
|
|
563
|
+
* (`anchor = None`), so the f599f21b single-approver L1 golden never moves.
|
|
564
|
+
*
|
|
565
|
+
* `suspendedContentJson` — the suspended L0 `ActionContent` JSON (optionally
|
|
566
|
+
* already carrying a relayed `time_anchor`).
|
|
567
|
+
* `approverRecordJson` — the human's `ApproverRecord` (decision, identity,
|
|
568
|
+
* reason, decided_at, sla_minutes) as JSON.
|
|
569
|
+
*
|
|
570
|
+
* Throws a `JsError` with a stable `[CODE]` prefix per [`BuildL1Error`]:
|
|
571
|
+
* `[AlreadyDecided]` (the body is already decided or is not a clean L0). The
|
|
572
|
+
* `[AnchorOnAsyncL1Path]` reject is RELAXED here — a present anchor is accepted.
|
|
573
|
+
* @param {string} suspended_content_json
|
|
574
|
+
* @param {string} approver_record_json
|
|
575
|
+
* @returns {Uint8Array}
|
|
576
|
+
*/
|
|
577
|
+
export function l1CosignPayload(suspended_content_json, approver_record_json) {
|
|
578
|
+
const ptr0 = passStringToWasm0(suspended_content_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
579
|
+
const len0 = WASM_VECTOR_LEN;
|
|
580
|
+
const ptr1 = passStringToWasm0(approver_record_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
581
|
+
const len1 = WASM_VECTOR_LEN;
|
|
582
|
+
const ret = wasm.l1CosignPayload(ptr0, len0, ptr1, len1);
|
|
583
|
+
if (ret[2]) {
|
|
584
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
585
|
+
}
|
|
586
|
+
return takeFromExternrefTable0(ret[0]);
|
|
587
|
+
}
|
|
588
|
+
|
|
514
589
|
/**
|
|
515
590
|
* Parse + validate policy TOML, running the load-time dangerous-lane floor check.
|
|
516
591
|
* Throws a `[PARSE]` or `[FLOOR_BYPASS]` `JsError` on failure; returns nothing on
|
|
@@ -557,6 +632,52 @@ export function policyRulesFromToml(toml_src) {
|
|
|
557
632
|
}
|
|
558
633
|
}
|
|
559
634
|
|
|
635
|
+
/**
|
|
636
|
+
* Return the EXACT bytes ONE approver must sign to co-sign a suspended (L0)
|
|
637
|
+
* action under the multi-approver k-of-n QUORUM lane:
|
|
638
|
+
* `APPROVAL_SIGNING_DOMAIN` (17 bytes) ++ `multi_approver_canonical` of the quorum
|
|
639
|
+
* body with `approvers = [thisRecord]` ONLY. (A quorum receipt derives L1 WITH a
|
|
640
|
+
* multi_approval block — not a higher level.)
|
|
641
|
+
*
|
|
642
|
+
* Per the two-canonical (M-B) rule each approver vouches ONLY their own record,
|
|
643
|
+
* never the assembled set: the browser promotes the suspended L0 body to the
|
|
644
|
+
* quorum base ([`build_quorum_base`] — `multi_approval = {threshold, roster,
|
|
645
|
+
* approvers: []}`), folds in this single record, and derives the per-record
|
|
646
|
+
* approval payload ([`multi_approval_cosign_payload`]). Both builders live in the
|
|
647
|
+
* always-compiled `receipt.rs`, so this compiles under heso-wasm's DEFAULT
|
|
648
|
+
* heso-action features (NO `sign`); the wasm surface never holds a key, it only
|
|
649
|
+
* ASSEMBLES the bytes a remote signer returns a detached signature over. The
|
|
650
|
+
* key-holding assembler [`heso_action::sign::assemble_quorum_from_parts`] verifies
|
|
651
|
+
* each returned signature over exactly these bytes.
|
|
652
|
+
*
|
|
653
|
+
* `suspendedContentJson` — the suspended L0 `ActionContent` JSON.
|
|
654
|
+
* `threshold` — the k-of-n approval threshold (`>= 1`).
|
|
655
|
+
* `rosterJson` — JSON array of base64 admissible approver public keys.
|
|
656
|
+
* `approverRecordJson` — THIS approver's `ApproverRecord` as JSON.
|
|
657
|
+
*
|
|
658
|
+
* Throws a `JsError` with a stable `[CODE]` prefix per [`BuildQuorumError`]:
|
|
659
|
+
* `[AnchorOnAsyncL1Path]`, `[AlreadyDecided]`, `[ThresholdZero]`, or
|
|
660
|
+
* `[EmptyRoster]`.
|
|
661
|
+
* @param {string} suspended_content_json
|
|
662
|
+
* @param {number} threshold
|
|
663
|
+
* @param {string} roster_json
|
|
664
|
+
* @param {string} approver_record_json
|
|
665
|
+
* @returns {Uint8Array}
|
|
666
|
+
*/
|
|
667
|
+
export function quorumCosignPayload(suspended_content_json, threshold, roster_json, approver_record_json) {
|
|
668
|
+
const ptr0 = passStringToWasm0(suspended_content_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
669
|
+
const len0 = WASM_VECTOR_LEN;
|
|
670
|
+
const ptr1 = passStringToWasm0(roster_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
671
|
+
const len1 = WASM_VECTOR_LEN;
|
|
672
|
+
const ptr2 = passStringToWasm0(approver_record_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
673
|
+
const len2 = WASM_VECTOR_LEN;
|
|
674
|
+
const ret = wasm.quorumCosignPayload(ptr0, len0, threshold, ptr1, len1, ptr2, len2);
|
|
675
|
+
if (ret[2]) {
|
|
676
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
677
|
+
}
|
|
678
|
+
return takeFromExternrefTable0(ret[0]);
|
|
679
|
+
}
|
|
680
|
+
|
|
560
681
|
/**
|
|
561
682
|
* Render a single rule (JSON [`PolicyRule`]) into the canonical English sentence
|
|
562
683
|
* — the SAME `rule_display` stamped on signed receipts. Replaces the drifting JS
|
|
@@ -638,8 +759,11 @@ export function validateNoFloorBypass(rules_json) {
|
|
|
638
759
|
*
|
|
639
760
|
* Never panics — structural failures return an `ActionVerdict` with
|
|
640
761
|
* `verdict = "Malformed:…"`. This is the browser replacement for the
|
|
641
|
-
* `verifyReceipt` function in `crypto.ts`, backed by the
|
|
642
|
-
*
|
|
762
|
+
* `verifyReceipt` function in `crypto.ts`, backed by the SAME Rust JCS +
|
|
763
|
+
* BLAKE3 + Ed25519 core as Node for canonicalization, hashing, and signature
|
|
764
|
+
* verification. NOTE: this is NOT byte-identical to Node for EVERY receipt —
|
|
765
|
+
* the `tsa` feature is OFF here, so a TIME-ANCHORED receipt that Node verifies
|
|
766
|
+
* against its TSA stack is handled differently on the browser surface.
|
|
643
767
|
* @param {Uint8Array} receipt_bytes
|
|
644
768
|
* @returns {ActionVerdict}
|
|
645
769
|
*/
|
|
@@ -662,23 +786,28 @@ export function verifyActionReceipt(receipt_bytes) {
|
|
|
662
786
|
* `now_unix_secs` — current time as BigInt Unix seconds
|
|
663
787
|
* `seen_nonces` — array of already-seen 32-byte nonces (Uint8Array each)
|
|
664
788
|
* `required_scope` — the required scope string
|
|
789
|
+
* `required_decision` — the verdict the token must carry ("approved"/"rejected"),
|
|
790
|
+
* NON-DEFAULTED (the SEC-02 decision binding)
|
|
665
791
|
* `registered_keys_b64` — array of base64 Ed25519 public keys on the allowlist
|
|
666
792
|
* @param {Uint8Array} token
|
|
667
793
|
* @param {Uint8Array} action_canonical
|
|
668
794
|
* @param {bigint} now_unix_secs
|
|
669
795
|
* @param {Array<any>} seen_nonces
|
|
670
796
|
* @param {string} required_scope
|
|
797
|
+
* @param {string} required_decision
|
|
671
798
|
* @param {Array<any>} registered_keys_b64
|
|
672
799
|
* @returns {ApprovalTokenClaims}
|
|
673
800
|
*/
|
|
674
|
-
export function verifyApprovalToken(token, action_canonical, now_unix_secs, seen_nonces, required_scope, registered_keys_b64) {
|
|
801
|
+
export function verifyApprovalToken(token, action_canonical, now_unix_secs, seen_nonces, required_scope, required_decision, registered_keys_b64) {
|
|
675
802
|
const ptr0 = passArray8ToWasm0(token, wasm.__wbindgen_malloc);
|
|
676
803
|
const len0 = WASM_VECTOR_LEN;
|
|
677
804
|
const ptr1 = passArray8ToWasm0(action_canonical, wasm.__wbindgen_malloc);
|
|
678
805
|
const len1 = WASM_VECTOR_LEN;
|
|
679
806
|
const ptr2 = passStringToWasm0(required_scope, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
680
807
|
const len2 = WASM_VECTOR_LEN;
|
|
681
|
-
const
|
|
808
|
+
const ptr3 = passStringToWasm0(required_decision, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
809
|
+
const len3 = WASM_VECTOR_LEN;
|
|
810
|
+
const ret = wasm.verifyApprovalToken(ptr0, len0, ptr1, len1, now_unix_secs, seen_nonces, ptr2, len2, ptr3, len3, registered_keys_b64);
|
|
682
811
|
if (ret[2]) {
|
|
683
812
|
throw takeFromExternrefTable0(ret[1]);
|
|
684
813
|
}
|
|
@@ -739,16 +868,19 @@ export function verifyConsistency(old_size, old_root_hex, new_size, new_root_hex
|
|
|
739
868
|
* `action_hash` — the raw 32-byte BLAKE3 action digest being authorized
|
|
740
869
|
* `approval_token` — the human co-sign bearer token presented by K
|
|
741
870
|
* `required_scope` — the required scope string
|
|
871
|
+
* `required_decision` — the verdict the co-sign must carry ("approved"/"rejected"),
|
|
872
|
+
* NON-DEFAULTED (the SEC-02 decision binding)
|
|
742
873
|
* `now_unix_secs` — current time as BigInt Unix seconds
|
|
743
874
|
* @param {Uint8Array} wire
|
|
744
875
|
* @param {Uint8Array} registered_operator_key
|
|
745
876
|
* @param {Uint8Array} action_hash
|
|
746
877
|
* @param {Uint8Array} approval_token
|
|
747
878
|
* @param {string} required_scope
|
|
879
|
+
* @param {string} required_decision
|
|
748
880
|
* @param {bigint} now_unix_secs
|
|
749
881
|
* @returns {VerifiedDelegation}
|
|
750
882
|
*/
|
|
751
|
-
export function verifyDelegation(wire, registered_operator_key, action_hash, approval_token, required_scope, now_unix_secs) {
|
|
883
|
+
export function verifyDelegation(wire, registered_operator_key, action_hash, approval_token, required_scope, required_decision, now_unix_secs) {
|
|
752
884
|
const ptr0 = passArray8ToWasm0(wire, wasm.__wbindgen_malloc);
|
|
753
885
|
const len0 = WASM_VECTOR_LEN;
|
|
754
886
|
const ptr1 = passArray8ToWasm0(registered_operator_key, wasm.__wbindgen_malloc);
|
|
@@ -759,7 +891,9 @@ export function verifyDelegation(wire, registered_operator_key, action_hash, app
|
|
|
759
891
|
const len3 = WASM_VECTOR_LEN;
|
|
760
892
|
const ptr4 = passStringToWasm0(required_scope, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
761
893
|
const len4 = WASM_VECTOR_LEN;
|
|
762
|
-
const
|
|
894
|
+
const ptr5 = passStringToWasm0(required_decision, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
895
|
+
const len5 = WASM_VECTOR_LEN;
|
|
896
|
+
const ret = wasm.verifyDelegation(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, now_unix_secs);
|
|
763
897
|
if (ret[2]) {
|
|
764
898
|
throw takeFromExternrefTable0(ret[1]);
|
|
765
899
|
}
|
package/heso_wasm_bg.wasm
CHANGED
|
Binary file
|
package/heso_wasm_bg.wasm.d.ts
CHANGED
|
@@ -22,21 +22,29 @@ export const __wbg_get_approvaltokenclaims_nonce: (a: number) => any;
|
|
|
22
22
|
export const __wbg_set_approvaltokenclaims_nonce: (a: number, b: any) => void;
|
|
23
23
|
export const __wbg_get_approvaltokenclaims_expiry_unix_secs: (a: number) => any;
|
|
24
24
|
export const __wbg_set_approvaltokenclaims_expiry_unix_secs: (a: number, b: any) => void;
|
|
25
|
+
export const __wbg_get_approvaltokenclaims_decision: (a: number) => [number, number];
|
|
25
26
|
export const __wbg_get_approvaltokenclaims_scope: (a: number) => [number, number];
|
|
26
27
|
export const __wbg_get_approvaltokenclaims_approver_public_key: (a: number) => [number, number];
|
|
28
|
+
export const __wbg_set_approvaltokenclaims_approver_public_key: (a: number, b: number, c: number) => void;
|
|
27
29
|
export const __wbg_verifieddelegation_free: (a: number, b: number) => void;
|
|
30
|
+
export const __wbg_get_verifieddelegation_authorized_key: (a: number) => any;
|
|
31
|
+
export const __wbg_set_verifieddelegation_authorized_key: (a: number, b: any) => void;
|
|
28
32
|
export const __wbg_get_verifieddelegation_sub: (a: number) => [number, number];
|
|
29
33
|
export const __wbg_get_verifieddelegation_scope: (a: number) => [number, number];
|
|
34
|
+
export const __wbg_get_verifieddelegation_expiry_unix_secs: (a: number) => any;
|
|
35
|
+
export const __wbg_set_verifieddelegation_expiry_unix_secs: (a: number, b: any) => void;
|
|
30
36
|
export const __wbg_get_verifieddelegation_not_before_unix_secs: (a: number) => any;
|
|
31
37
|
export const __wbg_set_verifieddelegation_not_before_unix_secs: (a: number, b: any) => void;
|
|
32
38
|
export const verifyActionReceipt: (a: number, b: number) => number;
|
|
33
39
|
export const actionCanonicalBytes: (a: number, b: number) => [number, number, number];
|
|
40
|
+
export const l1CosignPayload: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
41
|
+
export const quorumCosignPayload: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
|
|
34
42
|
export const contentHash: (a: number, b: number) => [number, number, number, number];
|
|
35
43
|
export const anchoredContentHash: (a: number, b: number) => [number, number, number, number];
|
|
36
44
|
export const shortHash: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
37
45
|
export const chainHashHex: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
38
|
-
export const verifyApprovalToken: (a: number, b: number, c: number, d: number, e: any, f: any, g: number, h: number, i: any) => [number, number, number];
|
|
39
|
-
export const verifyDelegation: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: any) => [number, number, number];
|
|
46
|
+
export const verifyApprovalToken: (a: number, b: number, c: number, d: number, e: any, f: any, g: number, h: number, i: number, j: number, k: any) => [number, number, number];
|
|
47
|
+
export const verifyDelegation: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: any) => [number, number, number];
|
|
40
48
|
export const verifyChain: (a: number, b: number) => [number, number, number];
|
|
41
49
|
export const verifySessionChain: (a: number, b: number) => [number, number, number];
|
|
42
50
|
export const verifySessionChainWithRotation: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
|
|
@@ -46,12 +54,8 @@ export const parsePolicy: (a: number, b: number) => [number, number];
|
|
|
46
54
|
export const ruleToSentence: (a: number, b: number) => [number, number, number, number];
|
|
47
55
|
export const policyRulesFromToml: (a: number, b: number) => [number, number, number, number];
|
|
48
56
|
export const validateNoFloorBypass: (a: number, b: number) => [number, number];
|
|
49
|
-
export const
|
|
50
|
-
export const __wbg_set_verifieddelegation_expiry_unix_secs: (a: number, b: any) => void;
|
|
51
|
-
export const __wbg_get_verifieddelegation_authorized_key: (a: number) => any;
|
|
52
|
-
export const __wbg_get_verifieddelegation_expiry_unix_secs: (a: number) => any;
|
|
57
|
+
export const __wbg_set_approvaltokenclaims_decision: (a: number, b: number, c: number) => void;
|
|
53
58
|
export const __wbg_set_approvaltokenclaims_scope: (a: number, b: number, c: number) => void;
|
|
54
|
-
export const __wbg_set_approvaltokenclaims_approver_public_key: (a: number, b: number, c: number) => void;
|
|
55
59
|
export const __wbg_set_verifieddelegation_sub: (a: number, b: number, c: number) => void;
|
|
56
60
|
export const __wbg_set_verifieddelegation_scope: (a: number, b: number, c: number) => void;
|
|
57
61
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hesohq/verify-wasm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1-dev.19",
|
|
4
4
|
"description": "HESO Enterprise trust layer — browser WASM verify-only surface (ESM)",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"prepublishOnly": "for sym in l1CosignPayload quorumCosignPayload; do for f in heso_wasm.js heso_wasm.d.ts heso_wasm_bg.wasm.d.ts heso_wasm_bg.wasm; do grep -aq \"$sym\" \"$f\" || { echo \"prepublishOnly: $sym missing from $f — stale artifact, run \\`just wasm\\` from heso-enterprise root\" >&2; exit 1; }; done; done; echo \"prepublishOnly: l1CosignPayload + quorumCosignPayload present in all 4 artifacts\""
|
|
8
|
+
},
|
|
6
9
|
"exports": {
|
|
7
10
|
".": {
|
|
8
11
|
"import": "./heso_wasm.js",
|