@bcts/provenance-mark 1.0.0-alpha.21 → 1.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +266 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -8
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +84 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +365 -252
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +261 -147
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/mark-info.ts +2 -2
- package/src/mark.ts +194 -42
- package/src/resolution.ts +2 -2
- package/src/validate.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _bcts_dcbor = require("@bcts/dcbor");
|
|
3
3
|
let _noble_hashes_sha2_js = require("@noble/hashes/sha2.js");
|
|
4
4
|
let _noble_hashes_hkdf_js = require("@noble/hashes/hkdf.js");
|
|
@@ -7,7 +7,6 @@ let _bcts_rand = require("@bcts/rand");
|
|
|
7
7
|
let _bcts_tags = require("@bcts/tags");
|
|
8
8
|
let _bcts_uniform_resources = require("@bcts/uniform-resources");
|
|
9
9
|
let _bcts_envelope = require("@bcts/envelope");
|
|
10
|
-
|
|
11
10
|
//#region src/error.ts
|
|
12
11
|
/**
|
|
13
12
|
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
@@ -87,34 +86,33 @@ var ProvenanceMarkError = class ProvenanceMarkError extends Error {
|
|
|
87
86
|
return JSON.stringify(value);
|
|
88
87
|
};
|
|
89
88
|
switch (type) {
|
|
90
|
-
case
|
|
91
|
-
case
|
|
92
|
-
case
|
|
93
|
-
case
|
|
94
|
-
case
|
|
95
|
-
case
|
|
96
|
-
case
|
|
97
|
-
case
|
|
98
|
-
case
|
|
99
|
-
case
|
|
100
|
-
case
|
|
101
|
-
case
|
|
102
|
-
case
|
|
103
|
-
case
|
|
104
|
-
case
|
|
105
|
-
case
|
|
106
|
-
case
|
|
107
|
-
case
|
|
108
|
-
case
|
|
109
|
-
case
|
|
110
|
-
case
|
|
111
|
-
case
|
|
112
|
-
case
|
|
89
|
+
case "InvalidSeedLength": return `invalid seed length: expected 32 bytes, got ${d("actual")} bytes`;
|
|
90
|
+
case "DuplicateKey": return `duplicate key: ${d("key")}`;
|
|
91
|
+
case "MissingKey": return `missing key: ${d("key")}`;
|
|
92
|
+
case "InvalidKey": return `invalid key: ${d("key")}`;
|
|
93
|
+
case "ExtraKeys": return `wrong number of keys: expected ${d("expected")}, got ${d("actual")}`;
|
|
94
|
+
case "InvalidKeyLength": return `invalid key length: expected ${d("expected")}, got ${d("actual")}`;
|
|
95
|
+
case "InvalidNextKeyLength": return `invalid next key length: expected ${d("expected")}, got ${d("actual")}`;
|
|
96
|
+
case "InvalidChainIdLength": return `invalid chain ID length: expected ${d("expected")}, got ${d("actual")}`;
|
|
97
|
+
case "InvalidMessageLength": return `invalid message length: expected at least ${d("expected")}, got ${d("actual")}`;
|
|
98
|
+
case "InvalidInfoCbor": return "invalid CBOR data in info field";
|
|
99
|
+
case "DateOutOfRange": return `date out of range: ${d("details")}`;
|
|
100
|
+
case "InvalidDate": return `invalid date: ${d("details")}`;
|
|
101
|
+
case "MissingUrlParameter": return `missing required URL parameter: ${d("parameter")}`;
|
|
102
|
+
case "YearOutOfRange": return `year out of range for 2-byte serialization: must be between 2023-2150, got ${d("year")}`;
|
|
103
|
+
case "InvalidMonthOrDay": return `invalid month (${d("month")}) or day (${d("day")}) for year ${d("year")}`;
|
|
104
|
+
case "ResolutionError": return `resolution serialization error: ${d("details")}`;
|
|
105
|
+
case "BytewordsError": return `bytewords error: ${d("message")}`;
|
|
106
|
+
case "CborError": return `CBOR error: ${d("message")}`;
|
|
107
|
+
case "UrlError": return `URL parsing error: ${d("message")}`;
|
|
108
|
+
case "Base64Error": return `base64 decoding error: ${d("message")}`;
|
|
109
|
+
case "JsonError": return `JSON error: ${d("message")}`;
|
|
110
|
+
case "IntegerConversionError": return `integer conversion error: ${d("message")}`;
|
|
111
|
+
case "ValidationError": return `validation error: ${d("message")}`;
|
|
113
112
|
default: return type;
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
};
|
|
117
|
-
|
|
118
116
|
//#endregion
|
|
119
117
|
//#region src/date.ts
|
|
120
118
|
/**
|
|
@@ -153,8 +151,8 @@ function serialize2Bytes(date) {
|
|
|
153
151
|
const month = date.getUTCMonth() + 1;
|
|
154
152
|
const day = date.getUTCDate();
|
|
155
153
|
const yy = year - 2023;
|
|
156
|
-
if (yy < 0 || yy >= 128) throw new ProvenanceMarkError(
|
|
157
|
-
if (month < 1 || month > 12 || day < 1 || day > 31) throw new ProvenanceMarkError(
|
|
154
|
+
if (yy < 0 || yy >= 128) throw new ProvenanceMarkError("YearOutOfRange", void 0, { year });
|
|
155
|
+
if (month < 1 || month > 12 || day < 1 || day > 31) throw new ProvenanceMarkError("InvalidMonthOrDay", void 0, {
|
|
158
156
|
year,
|
|
159
157
|
month,
|
|
160
158
|
day
|
|
@@ -169,12 +167,12 @@ function serialize2Bytes(date) {
|
|
|
169
167
|
* Deserialize 2 bytes to a date.
|
|
170
168
|
*/
|
|
171
169
|
function deserialize2Bytes(bytes) {
|
|
172
|
-
if (bytes.length !== 2) throw new ProvenanceMarkError(
|
|
170
|
+
if (bytes.length !== 2) throw new ProvenanceMarkError("InvalidDate", void 0, { details: `expected 2 bytes, got ${bytes.length}` });
|
|
173
171
|
const value = bytes[0] << 8 | bytes[1];
|
|
174
172
|
const day = value & 31;
|
|
175
173
|
const month = value >> 5 & 15;
|
|
176
174
|
const year = (value >> 9 & 127) + 2023;
|
|
177
|
-
if (month < 1 || month > 12 || !isValidDay(year, month, day)) throw new ProvenanceMarkError(
|
|
175
|
+
if (month < 1 || month > 12 || !isValidDay(year, month, day)) throw new ProvenanceMarkError("InvalidMonthOrDay", void 0, {
|
|
178
176
|
year,
|
|
179
177
|
month,
|
|
180
178
|
day
|
|
@@ -187,7 +185,7 @@ function deserialize2Bytes(bytes) {
|
|
|
187
185
|
function serialize4Bytes(date) {
|
|
188
186
|
const duration = date.getTime() - REFERENCE_DATE;
|
|
189
187
|
const seconds = Math.floor(duration / 1e3);
|
|
190
|
-
if (seconds < 0 || seconds > 4294967295) throw new ProvenanceMarkError(
|
|
188
|
+
if (seconds < 0 || seconds > 4294967295) throw new ProvenanceMarkError("DateOutOfRange", void 0, { details: "seconds value out of range for u32" });
|
|
191
189
|
const buf = new Uint8Array(4);
|
|
192
190
|
buf[0] = seconds >> 24 & 255;
|
|
193
191
|
buf[1] = seconds >> 16 & 255;
|
|
@@ -199,7 +197,7 @@ function serialize4Bytes(date) {
|
|
|
199
197
|
* Deserialize 4 bytes to a date.
|
|
200
198
|
*/
|
|
201
199
|
function deserialize4Bytes(bytes) {
|
|
202
|
-
if (bytes.length !== 4) throw new ProvenanceMarkError(
|
|
200
|
+
if (bytes.length !== 4) throw new ProvenanceMarkError("InvalidDate", void 0, { details: `expected 4 bytes, got ${bytes.length}` });
|
|
203
201
|
const seconds = (bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) >>> 0;
|
|
204
202
|
return new Date(REFERENCE_DATE + seconds * 1e3);
|
|
205
203
|
}
|
|
@@ -209,7 +207,7 @@ function deserialize4Bytes(bytes) {
|
|
|
209
207
|
function serialize6Bytes(date) {
|
|
210
208
|
const duration = date.getTime() - REFERENCE_DATE;
|
|
211
209
|
const milliseconds = BigInt(duration);
|
|
212
|
-
if (milliseconds < 0n || milliseconds > BigInt(MAX_6_BYTE_VALUE)) throw new ProvenanceMarkError(
|
|
210
|
+
if (milliseconds < 0n || milliseconds > BigInt(MAX_6_BYTE_VALUE)) throw new ProvenanceMarkError("DateOutOfRange", void 0, { details: "date exceeds maximum representable value" });
|
|
213
211
|
const buf = new Uint8Array(6);
|
|
214
212
|
buf[0] = Number(milliseconds >> 40n & 255n);
|
|
215
213
|
buf[1] = Number(milliseconds >> 32n & 255n);
|
|
@@ -223,9 +221,9 @@ function serialize6Bytes(date) {
|
|
|
223
221
|
* Deserialize 6 bytes to a date.
|
|
224
222
|
*/
|
|
225
223
|
function deserialize6Bytes(bytes) {
|
|
226
|
-
if (bytes.length !== 6) throw new ProvenanceMarkError(
|
|
224
|
+
if (bytes.length !== 6) throw new ProvenanceMarkError("InvalidDate", void 0, { details: `expected 6 bytes, got ${bytes.length}` });
|
|
227
225
|
const milliseconds = BigInt(bytes[0]) << 40n | BigInt(bytes[1]) << 32n | BigInt(bytes[2]) << 24n | BigInt(bytes[3]) << 16n | BigInt(bytes[4]) << 8n | BigInt(bytes[5]);
|
|
228
|
-
if (milliseconds > BigInt(MAX_6_BYTE_VALUE)) throw new ProvenanceMarkError(
|
|
226
|
+
if (milliseconds > BigInt(MAX_6_BYTE_VALUE)) throw new ProvenanceMarkError("DateOutOfRange", void 0, { details: "date exceeds maximum representable value" });
|
|
229
227
|
return new Date(REFERENCE_DATE + Number(milliseconds));
|
|
230
228
|
}
|
|
231
229
|
/**
|
|
@@ -248,7 +246,7 @@ function dateToIso8601(date) {
|
|
|
248
246
|
*/
|
|
249
247
|
function dateFromIso8601(str) {
|
|
250
248
|
const date = new Date(str);
|
|
251
|
-
if (isNaN(date.getTime())) throw new ProvenanceMarkError(
|
|
249
|
+
if (isNaN(date.getTime())) throw new ProvenanceMarkError("InvalidDate", void 0, { details: `cannot parse date: ${str}` });
|
|
252
250
|
return date;
|
|
253
251
|
}
|
|
254
252
|
/**
|
|
@@ -257,7 +255,6 @@ function dateFromIso8601(str) {
|
|
|
257
255
|
function dateToDateString(date) {
|
|
258
256
|
return `${date.getUTCFullYear()}-${(date.getUTCMonth() + 1).toString().padStart(2, "0")}-${date.getUTCDate().toString().padStart(2, "0")}`;
|
|
259
257
|
}
|
|
260
|
-
|
|
261
258
|
//#endregion
|
|
262
259
|
//#region src/resolution.ts
|
|
263
260
|
/**
|
|
@@ -287,11 +284,11 @@ function resolutionToNumber(res) {
|
|
|
287
284
|
*/
|
|
288
285
|
function resolutionFromNumber(value) {
|
|
289
286
|
switch (value) {
|
|
290
|
-
case 0: return
|
|
291
|
-
case 1: return
|
|
292
|
-
case 2: return
|
|
293
|
-
case 3: return
|
|
294
|
-
default: throw new ProvenanceMarkError(
|
|
287
|
+
case 0: return 0;
|
|
288
|
+
case 1: return 1;
|
|
289
|
+
case 2: return 2;
|
|
290
|
+
case 3: return 3;
|
|
291
|
+
default: throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid provenance mark resolution value: ${value}` });
|
|
295
292
|
}
|
|
296
293
|
}
|
|
297
294
|
/**
|
|
@@ -299,10 +296,10 @@ function resolutionFromNumber(value) {
|
|
|
299
296
|
*/
|
|
300
297
|
function linkLength(res) {
|
|
301
298
|
switch (res) {
|
|
302
|
-
case
|
|
303
|
-
case
|
|
304
|
-
case
|
|
305
|
-
case
|
|
299
|
+
case 0: return 4;
|
|
300
|
+
case 1: return 8;
|
|
301
|
+
case 2: return 16;
|
|
302
|
+
case 3: return 32;
|
|
306
303
|
}
|
|
307
304
|
}
|
|
308
305
|
/**
|
|
@@ -310,10 +307,10 @@ function linkLength(res) {
|
|
|
310
307
|
*/
|
|
311
308
|
function seqBytesLength(res) {
|
|
312
309
|
switch (res) {
|
|
313
|
-
case
|
|
314
|
-
case
|
|
315
|
-
case
|
|
316
|
-
case
|
|
310
|
+
case 0: return 2;
|
|
311
|
+
case 1:
|
|
312
|
+
case 2:
|
|
313
|
+
case 3: return 4;
|
|
317
314
|
}
|
|
318
315
|
}
|
|
319
316
|
/**
|
|
@@ -321,10 +318,10 @@ function seqBytesLength(res) {
|
|
|
321
318
|
*/
|
|
322
319
|
function dateBytesLength(res) {
|
|
323
320
|
switch (res) {
|
|
324
|
-
case
|
|
325
|
-
case
|
|
326
|
-
case
|
|
327
|
-
case
|
|
321
|
+
case 0: return 2;
|
|
322
|
+
case 1: return 4;
|
|
323
|
+
case 2:
|
|
324
|
+
case 3: return 6;
|
|
328
325
|
}
|
|
329
326
|
}
|
|
330
327
|
/**
|
|
@@ -392,10 +389,10 @@ function infoRangeStart(res) {
|
|
|
392
389
|
*/
|
|
393
390
|
function serializeDate(res, date) {
|
|
394
391
|
switch (res) {
|
|
395
|
-
case
|
|
396
|
-
case
|
|
397
|
-
case
|
|
398
|
-
case
|
|
392
|
+
case 0: return serialize2Bytes(date);
|
|
393
|
+
case 1: return serialize4Bytes(date);
|
|
394
|
+
case 2:
|
|
395
|
+
case 3: return serialize6Bytes(date);
|
|
399
396
|
}
|
|
400
397
|
}
|
|
401
398
|
/**
|
|
@@ -403,15 +400,15 @@ function serializeDate(res, date) {
|
|
|
403
400
|
*/
|
|
404
401
|
function deserializeDate(res, data) {
|
|
405
402
|
switch (res) {
|
|
406
|
-
case
|
|
407
|
-
if (data.length !== 2) throw new ProvenanceMarkError(
|
|
403
|
+
case 0:
|
|
404
|
+
if (data.length !== 2) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid date length: expected 2 bytes, got ${data.length}` });
|
|
408
405
|
return deserialize2Bytes(data);
|
|
409
|
-
case
|
|
410
|
-
if (data.length !== 4) throw new ProvenanceMarkError(
|
|
406
|
+
case 1:
|
|
407
|
+
if (data.length !== 4) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid date length: expected 4 bytes, got ${data.length}` });
|
|
411
408
|
return deserialize4Bytes(data);
|
|
412
|
-
case
|
|
413
|
-
case
|
|
414
|
-
if (data.length !== 6) throw new ProvenanceMarkError(
|
|
409
|
+
case 2:
|
|
410
|
+
case 3:
|
|
411
|
+
if (data.length !== 6) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid date length: expected 6 bytes, got ${data.length}` });
|
|
415
412
|
return deserialize6Bytes(data);
|
|
416
413
|
}
|
|
417
414
|
}
|
|
@@ -420,7 +417,7 @@ function deserializeDate(res, data) {
|
|
|
420
417
|
*/
|
|
421
418
|
function serializeSeq(res, seq) {
|
|
422
419
|
if (seqBytesLength(res) === 2) {
|
|
423
|
-
if (seq > 65535) throw new ProvenanceMarkError(
|
|
420
|
+
if (seq > 65535) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `sequence number ${seq} out of range for 2-byte format (max 65535)` });
|
|
424
421
|
const buf = new Uint8Array(2);
|
|
425
422
|
buf[0] = seq >> 8 & 255;
|
|
426
423
|
buf[1] = seq & 255;
|
|
@@ -439,10 +436,10 @@ function serializeSeq(res, seq) {
|
|
|
439
436
|
*/
|
|
440
437
|
function deserializeSeq(res, data) {
|
|
441
438
|
if (seqBytesLength(res) === 2) {
|
|
442
|
-
if (data.length !== 2) throw new ProvenanceMarkError(
|
|
439
|
+
if (data.length !== 2) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid sequence number length: expected 2 bytes, got ${data.length}` });
|
|
443
440
|
return data[0] << 8 | data[1];
|
|
444
441
|
} else {
|
|
445
|
-
if (data.length !== 4) throw new ProvenanceMarkError(
|
|
442
|
+
if (data.length !== 4) throw new ProvenanceMarkError("ResolutionError", void 0, { details: `invalid sequence number length: expected 4 bytes, got ${data.length}` });
|
|
446
443
|
return (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) >>> 0;
|
|
447
444
|
}
|
|
448
445
|
}
|
|
@@ -451,10 +448,10 @@ function deserializeSeq(res, data) {
|
|
|
451
448
|
*/
|
|
452
449
|
function resolutionToString(res) {
|
|
453
450
|
switch (res) {
|
|
454
|
-
case
|
|
455
|
-
case
|
|
456
|
-
case
|
|
457
|
-
case
|
|
451
|
+
case 0: return "low";
|
|
452
|
+
case 1: return "medium";
|
|
453
|
+
case 2: return "quartile";
|
|
454
|
+
case 3: return "high";
|
|
458
455
|
}
|
|
459
456
|
}
|
|
460
457
|
/**
|
|
@@ -470,7 +467,6 @@ function resolutionFromCbor(cborValue) {
|
|
|
470
467
|
const value = (0, _bcts_dcbor.expectUnsigned)(cborValue);
|
|
471
468
|
return resolutionFromNumber(Number(value));
|
|
472
469
|
}
|
|
473
|
-
|
|
474
470
|
//#endregion
|
|
475
471
|
//#region src/crypto-utils.ts
|
|
476
472
|
/**
|
|
@@ -514,7 +510,6 @@ function obfuscate(key, message) {
|
|
|
514
510
|
for (let i = 0; i < 12; i++) iv[i] = extendedKey[31 - i];
|
|
515
511
|
return (0, _noble_ciphers_chacha_js.chacha20)(extendedKey, iv, message instanceof Uint8Array ? message : new Uint8Array(message));
|
|
516
512
|
}
|
|
517
|
-
|
|
518
513
|
//#endregion
|
|
519
514
|
//#region src/xoshiro256starstar.ts
|
|
520
515
|
/**
|
|
@@ -642,7 +637,6 @@ var Xoshiro256StarStar = class Xoshiro256StarStar {
|
|
|
642
637
|
this.s[3] = this.rotateLeft64(this.s[3], 45n);
|
|
643
638
|
}
|
|
644
639
|
};
|
|
645
|
-
|
|
646
640
|
//#endregion
|
|
647
641
|
//#region src/rng-state.ts
|
|
648
642
|
/**
|
|
@@ -669,7 +663,7 @@ var RngState = class RngState {
|
|
|
669
663
|
* Create from a 32-byte array.
|
|
670
664
|
*/
|
|
671
665
|
static fromBytes(bytes) {
|
|
672
|
-
if (bytes.length !==
|
|
666
|
+
if (bytes.length !== 32) throw new ProvenanceMarkError("InvalidSeedLength", void 0, { actual: bytes.length });
|
|
673
667
|
return new RngState(new Uint8Array(bytes));
|
|
674
668
|
}
|
|
675
669
|
/**
|
|
@@ -698,7 +692,6 @@ var RngState = class RngState {
|
|
|
698
692
|
return RngState.fromBytes(bytes);
|
|
699
693
|
}
|
|
700
694
|
};
|
|
701
|
-
|
|
702
695
|
//#endregion
|
|
703
696
|
//#region src/seed.ts
|
|
704
697
|
/**
|
|
@@ -719,15 +712,15 @@ var ProvenanceSeed = class ProvenanceSeed {
|
|
|
719
712
|
* Create a new random seed using secure random number generation.
|
|
720
713
|
*/
|
|
721
714
|
static new() {
|
|
722
|
-
const data = (0, _bcts_rand.randomData)(
|
|
715
|
+
const data = (0, _bcts_rand.randomData)(32);
|
|
723
716
|
return ProvenanceSeed.fromBytes(data);
|
|
724
717
|
}
|
|
725
718
|
/**
|
|
726
719
|
* Create a new seed using custom random data.
|
|
727
720
|
*/
|
|
728
721
|
static newUsing(randomData) {
|
|
729
|
-
if (randomData.length <
|
|
730
|
-
return ProvenanceSeed.fromBytes(randomData.slice(0,
|
|
722
|
+
if (randomData.length < 32) throw new ProvenanceMarkError("InvalidSeedLength", void 0, { actual: randomData.length });
|
|
723
|
+
return ProvenanceSeed.fromBytes(randomData.slice(0, 32));
|
|
731
724
|
}
|
|
732
725
|
/**
|
|
733
726
|
* Create a new seed from a passphrase.
|
|
@@ -746,7 +739,7 @@ var ProvenanceSeed = class ProvenanceSeed {
|
|
|
746
739
|
* Create from a 32-byte array.
|
|
747
740
|
*/
|
|
748
741
|
static fromBytes(bytes) {
|
|
749
|
-
if (bytes.length !==
|
|
742
|
+
if (bytes.length !== 32) throw new ProvenanceMarkError("InvalidSeedLength", void 0, { actual: bytes.length });
|
|
750
743
|
return new ProvenanceSeed(new Uint8Array(bytes));
|
|
751
744
|
}
|
|
752
745
|
/**
|
|
@@ -775,7 +768,6 @@ var ProvenanceSeed = class ProvenanceSeed {
|
|
|
775
768
|
return ProvenanceSeed.fromBytes(bytes);
|
|
776
769
|
}
|
|
777
770
|
};
|
|
778
|
-
|
|
779
771
|
//#endregion
|
|
780
772
|
//#region src/utils.ts
|
|
781
773
|
/**
|
|
@@ -824,7 +816,6 @@ function fromBase64(base64) {
|
|
|
824
816
|
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
825
817
|
return bytes;
|
|
826
818
|
}
|
|
827
|
-
|
|
828
819
|
//#endregion
|
|
829
820
|
//#region src/validate.ts
|
|
830
821
|
/**
|
|
@@ -899,7 +890,7 @@ function formatText(report) {
|
|
|
899
890
|
if (!chain.hasGenesis) lines.push(" Warning: No genesis mark found");
|
|
900
891
|
for (const seq of chain.sequences) for (const flaggedMark of seq.marks) {
|
|
901
892
|
const mark = flaggedMark.mark;
|
|
902
|
-
const shortId = mark.
|
|
893
|
+
const shortId = mark.idHex().slice(0, 8);
|
|
903
894
|
const seqNum = mark.seq();
|
|
904
895
|
const annotations = [];
|
|
905
896
|
if (mark.isGenesis()) annotations.push("genesis mark");
|
|
@@ -939,9 +930,9 @@ function formatText(report) {
|
|
|
939
930
|
*/
|
|
940
931
|
function formatReport(report, format) {
|
|
941
932
|
switch (format) {
|
|
942
|
-
case
|
|
943
|
-
case
|
|
944
|
-
case
|
|
933
|
+
case "text": return formatText(report);
|
|
934
|
+
case "json-compact": return JSON.stringify(reportToJSON(report));
|
|
935
|
+
case "json-pretty": return JSON.stringify(reportToJSON(report), null, 2);
|
|
945
936
|
}
|
|
946
937
|
}
|
|
947
938
|
/**
|
|
@@ -1097,7 +1088,6 @@ function hexDecode(hex) {
|
|
|
1097
1088
|
for (let i = 0; i < hex.length; i += 2) bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
1098
1089
|
return bytes;
|
|
1099
1090
|
}
|
|
1100
|
-
|
|
1101
1091
|
//#endregion
|
|
1102
1092
|
//#region src/mark.ts
|
|
1103
1093
|
/**
|
|
@@ -1179,15 +1169,15 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1179
1169
|
*/
|
|
1180
1170
|
static new(res, key, nextKey, chainId, seq, date, info) {
|
|
1181
1171
|
const linkLen = linkLength(res);
|
|
1182
|
-
if (key.length !== linkLen) throw new ProvenanceMarkError(
|
|
1172
|
+
if (key.length !== linkLen) throw new ProvenanceMarkError("InvalidKeyLength", void 0, {
|
|
1183
1173
|
expected: linkLen,
|
|
1184
1174
|
actual: key.length
|
|
1185
1175
|
});
|
|
1186
|
-
if (nextKey.length !== linkLen) throw new ProvenanceMarkError(
|
|
1176
|
+
if (nextKey.length !== linkLen) throw new ProvenanceMarkError("InvalidNextKeyLength", void 0, {
|
|
1187
1177
|
expected: linkLen,
|
|
1188
1178
|
actual: nextKey.length
|
|
1189
1179
|
});
|
|
1190
|
-
if (chainId.length !== linkLen) throw new ProvenanceMarkError(
|
|
1180
|
+
if (chainId.length !== linkLen) throw new ProvenanceMarkError("InvalidChainIdLength", void 0, {
|
|
1191
1181
|
expected: linkLen,
|
|
1192
1182
|
actual: chainId.length
|
|
1193
1183
|
});
|
|
@@ -1203,7 +1193,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1203
1193
|
*/
|
|
1204
1194
|
static fromMessage(res, message) {
|
|
1205
1195
|
const minLen = fixedLength(res);
|
|
1206
|
-
if (message.length < minLen) throw new ProvenanceMarkError(
|
|
1196
|
+
if (message.length < minLen) throw new ProvenanceMarkError("InvalidMessageLength", void 0, {
|
|
1207
1197
|
expected: minLen,
|
|
1208
1198
|
actual: message.length
|
|
1209
1199
|
});
|
|
@@ -1226,7 +1216,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1226
1216
|
if (infoBytes.length > 0) try {
|
|
1227
1217
|
(0, _bcts_dcbor.decodeCbor)(infoBytes);
|
|
1228
1218
|
} catch {
|
|
1229
|
-
throw new ProvenanceMarkError(
|
|
1219
|
+
throw new ProvenanceMarkError("InvalidInfoCbor");
|
|
1230
1220
|
}
|
|
1231
1221
|
return new ProvenanceMark(res, new Uint8Array(key), new Uint8Array(hash), new Uint8Array(chainId), new Uint8Array(seqBytes), new Uint8Array(dateBytes), new Uint8Array(infoBytes), seq, date);
|
|
1232
1222
|
}
|
|
@@ -1241,51 +1231,174 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1241
1231
|
]), linkLength(res));
|
|
1242
1232
|
}
|
|
1243
1233
|
/**
|
|
1244
|
-
*
|
|
1234
|
+
* The 32-byte Mark ID.
|
|
1235
|
+
*
|
|
1236
|
+
* The first `linkLength` bytes are the mark's stored hash. The remaining
|
|
1237
|
+
* bytes come from the mark's fingerprint (SHA-256 of CBOR encoding),
|
|
1238
|
+
* ensuring a full 32-byte value is always available regardless of
|
|
1239
|
+
* resolution.
|
|
1240
|
+
*/
|
|
1241
|
+
id() {
|
|
1242
|
+
const result = new Uint8Array(32);
|
|
1243
|
+
const n = this._hash.length;
|
|
1244
|
+
result.set(this._hash, 0);
|
|
1245
|
+
if (n < 32) {
|
|
1246
|
+
const fp = this.fingerprint();
|
|
1247
|
+
result.set(fp.subarray(0, 32 - n), n);
|
|
1248
|
+
}
|
|
1249
|
+
return result;
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* The full 32-byte Mark ID as a 64-character hex string.
|
|
1253
|
+
*/
|
|
1254
|
+
idHex() {
|
|
1255
|
+
return bytesToHex(this.id());
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* The first `wordCount` bytes of the Mark ID as upper-case ByteWords.
|
|
1259
|
+
*
|
|
1260
|
+
* @param wordCount Number of bytes to encode, must be in `4..=32`.
|
|
1261
|
+
* @param prefix If `true`, prepends the provenance-mark prefix character.
|
|
1262
|
+
* @throws if `wordCount` is not in the range `4..=32`.
|
|
1263
|
+
*/
|
|
1264
|
+
idBytewords(wordCount, prefix) {
|
|
1265
|
+
if (!Number.isInteger(wordCount) || wordCount < 4 || wordCount > 32) throw new Error(`word_count must be 4..=32, got ${wordCount}`);
|
|
1266
|
+
const s = (0, _bcts_uniform_resources.encodeToWords)(this.id().subarray(0, wordCount)).toUpperCase();
|
|
1267
|
+
return prefix ? `\u{1F151} ${s}` : s;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* The first `wordCount` bytes of the Mark ID as Bytemoji.
|
|
1271
|
+
*
|
|
1272
|
+
* @param wordCount Number of bytes to encode, must be in `4..=32`.
|
|
1273
|
+
* @param prefix If `true`, prepends the provenance-mark prefix character.
|
|
1274
|
+
* @throws if `wordCount` is not in the range `4..=32`.
|
|
1275
|
+
*/
|
|
1276
|
+
idBytemoji(wordCount, prefix) {
|
|
1277
|
+
if (!Number.isInteger(wordCount) || wordCount < 4 || wordCount > 32) throw new Error(`word_count must be 4..=32, got ${wordCount}`);
|
|
1278
|
+
const s = (0, _bcts_uniform_resources.encodeToBytemojis)(this.id().subarray(0, wordCount)).toUpperCase();
|
|
1279
|
+
return prefix ? `\u{1F151} ${s}` : s;
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* The first `wordCount` bytes of the Mark ID as upper-case minimal
|
|
1283
|
+
* ByteWords (2 letters per byte, concatenated without separator).
|
|
1284
|
+
*
|
|
1285
|
+
* @param wordCount Number of bytes to encode, must be in `4..=32`.
|
|
1286
|
+
* @param prefix If `true`, prepends the provenance-mark prefix character.
|
|
1287
|
+
* @throws if `wordCount` is not in the range `4..=32`.
|
|
1288
|
+
*/
|
|
1289
|
+
idBytewordsMinimal(wordCount, prefix) {
|
|
1290
|
+
if (!Number.isInteger(wordCount) || wordCount < 4 || wordCount > 32) throw new Error(`word_count must be 4..=32, got ${wordCount}`);
|
|
1291
|
+
const s = (0, _bcts_uniform_resources.encodeToMinimalBytewords)(this.id().subarray(0, wordCount)).toUpperCase();
|
|
1292
|
+
return prefix ? `\u{1F151} ${s}` : s;
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Legacy 8-character hex identifier — the first 4 bytes of the Mark ID.
|
|
1296
|
+
*
|
|
1297
|
+
* @deprecated Use {@link idHex} for the full 64-char hex, or
|
|
1298
|
+
* `idHex().slice(0, 8)` for this legacy short form. Retained for
|
|
1299
|
+
* backwards compatibility; will be removed in a future alpha.
|
|
1245
1300
|
*/
|
|
1246
1301
|
identifier() {
|
|
1247
|
-
return
|
|
1302
|
+
return this.idHex().slice(0, 8);
|
|
1248
1303
|
}
|
|
1249
1304
|
/**
|
|
1250
|
-
*
|
|
1305
|
+
* Legacy 4-byte upper-case ByteWords identifier.
|
|
1306
|
+
*
|
|
1307
|
+
* @deprecated Equivalent to `idBytewords(4, prefix)`. Retained for
|
|
1308
|
+
* backwards compatibility; will be removed in a future alpha.
|
|
1251
1309
|
*/
|
|
1252
1310
|
bytewordsIdentifier(prefix) {
|
|
1253
|
-
|
|
1254
|
-
return prefix ? `\u{1F151} ${s}` : s;
|
|
1311
|
+
return this.idBytewords(4, prefix);
|
|
1255
1312
|
}
|
|
1256
1313
|
/**
|
|
1257
|
-
*
|
|
1258
|
-
*
|
|
1259
|
-
* (4 words x 2 letters = 8 letters).
|
|
1314
|
+
* Legacy 8-letter minimal ByteWords identifier (first+last letter of each
|
|
1315
|
+
* of the 4 ByteWords). Example: "ABLE ACID ALSO APEX" -> "AEADAOAX".
|
|
1260
1316
|
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1317
|
+
* @deprecated Equivalent to `idBytewordsMinimal(4, prefix)`. Retained
|
|
1318
|
+
* for backwards compatibility; will be removed in a future alpha.
|
|
1263
1319
|
*/
|
|
1264
1320
|
bytewordsMinimalIdentifier(prefix) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1321
|
+
return this.idBytewordsMinimal(4, prefix);
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Legacy 4-byte upper-case Bytemoji identifier.
|
|
1325
|
+
*
|
|
1326
|
+
* @deprecated Equivalent to `idBytemoji(4, prefix)`. Retained for
|
|
1327
|
+
* backwards compatibility; will be removed in a future alpha.
|
|
1328
|
+
*/
|
|
1329
|
+
bytemojiIdentifier(prefix) {
|
|
1330
|
+
return this.idBytemoji(4, prefix);
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Computes the minimum prefix length (in bytes, `4..=32`) each mark needs
|
|
1334
|
+
* so that every mark in the set has a unique Mark ID prefix.
|
|
1335
|
+
*
|
|
1336
|
+
* Non-colliding marks get the minimum of 4. Only marks whose 4-byte
|
|
1337
|
+
* prefixes collide are extended.
|
|
1338
|
+
*/
|
|
1339
|
+
static minimalNoncollidingPrefixLengths(ids) {
|
|
1340
|
+
const n = ids.length;
|
|
1341
|
+
const lengths = new Array(n).fill(4);
|
|
1342
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1343
|
+
for (let i = 0; i < n; i++) {
|
|
1344
|
+
const key = bytesToHex(ids[i].subarray(0, 4));
|
|
1345
|
+
const g = groups.get(key);
|
|
1346
|
+
if (g !== void 0) g.push(i);
|
|
1347
|
+
else groups.set(key, [i]);
|
|
1348
|
+
}
|
|
1349
|
+
for (const indices of groups.values()) {
|
|
1350
|
+
if (indices.length <= 1) continue;
|
|
1351
|
+
ProvenanceMark.resolveCollisionGroup(ids, indices, lengths);
|
|
1272
1352
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1353
|
+
return lengths;
|
|
1354
|
+
}
|
|
1355
|
+
static resolveCollisionGroup(ids, initialIndices, lengths) {
|
|
1356
|
+
let unresolved = [...initialIndices];
|
|
1357
|
+
for (let prefixLen = 5; prefixLen <= 32; prefixLen++) {
|
|
1358
|
+
const subGroups = /* @__PURE__ */ new Map();
|
|
1359
|
+
for (const i of unresolved) {
|
|
1360
|
+
const key = bytesToHex(ids[i].subarray(0, prefixLen));
|
|
1361
|
+
const g = subGroups.get(key);
|
|
1362
|
+
if (g !== void 0) g.push(i);
|
|
1363
|
+
else subGroups.set(key, [i]);
|
|
1279
1364
|
}
|
|
1365
|
+
const nextUnresolved = [];
|
|
1366
|
+
for (const subIndices of subGroups.values()) if (subIndices.length === 1) lengths[subIndices[0]] = prefixLen;
|
|
1367
|
+
else nextUnresolved.push(...subIndices);
|
|
1368
|
+
if (nextUnresolved.length === 0) return;
|
|
1369
|
+
unresolved = nextUnresolved;
|
|
1280
1370
|
}
|
|
1281
|
-
|
|
1371
|
+
for (const i of unresolved) lengths[i] = 32;
|
|
1282
1372
|
}
|
|
1283
1373
|
/**
|
|
1284
|
-
*
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1374
|
+
* Returns disambiguated upper-case ByteWords Mark IDs for a set of marks.
|
|
1375
|
+
*
|
|
1376
|
+
* Non-colliding marks get 4-word identifiers. Only marks whose 4-byte
|
|
1377
|
+
* prefixes collide are extended with additional words (up to 32 bytes
|
|
1378
|
+
* per identifier).
|
|
1379
|
+
*/
|
|
1380
|
+
static disambiguatedIdBytewords(marks, prefix) {
|
|
1381
|
+
const ids = marks.map((m) => m.id());
|
|
1382
|
+
const lengths = ProvenanceMark.minimalNoncollidingPrefixLengths(ids);
|
|
1383
|
+
return ids.map((id, i) => {
|
|
1384
|
+
const s = (0, _bcts_uniform_resources.encodeToWords)(id.subarray(0, lengths[i])).toUpperCase();
|
|
1385
|
+
return prefix ? `\u{1F151} ${s}` : s;
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Returns disambiguated Bytemoji Mark IDs for a set of marks.
|
|
1390
|
+
*
|
|
1391
|
+
* Non-colliding marks get 4-emoji identifiers. Only marks whose 4-byte
|
|
1392
|
+
* prefixes collide are extended with additional emojis (up to 32 bytes
|
|
1393
|
+
* per identifier).
|
|
1394
|
+
*/
|
|
1395
|
+
static disambiguatedIdBytemoji(marks, prefix) {
|
|
1396
|
+
const ids = marks.map((m) => m.id());
|
|
1397
|
+
const lengths = ProvenanceMark.minimalNoncollidingPrefixLengths(ids);
|
|
1398
|
+
return ids.map((id, i) => {
|
|
1399
|
+
const s = (0, _bcts_uniform_resources.encodeToBytemojis)(id.subarray(0, lengths[i])).toUpperCase();
|
|
1400
|
+
return prefix ? `\u{1F151} ${s}` : s;
|
|
1401
|
+
});
|
|
1289
1402
|
}
|
|
1290
1403
|
/**
|
|
1291
1404
|
* Check if this mark precedes another mark in the chain.
|
|
@@ -1304,15 +1417,15 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1304
1417
|
* `Error::Validation(ValidationIssue)` pattern.
|
|
1305
1418
|
*/
|
|
1306
1419
|
precedesOpt(next) {
|
|
1307
|
-
if (next._seq === 0) throw new ProvenanceMarkError(
|
|
1308
|
-
if (arraysEqual(next._key, next._chainId)) throw new ProvenanceMarkError(
|
|
1420
|
+
if (next._seq === 0) throw new ProvenanceMarkError("ValidationError", "non-genesis mark at sequence 0", { validationIssue: { type: "NonGenesisAtZero" } });
|
|
1421
|
+
if (arraysEqual(next._key, next._chainId)) throw new ProvenanceMarkError("ValidationError", "genesis mark must have key equal to chain_id", { validationIssue: { type: "InvalidGenesisKey" } });
|
|
1309
1422
|
if (this._seq !== next._seq - 1) {
|
|
1310
1423
|
const issue = {
|
|
1311
1424
|
type: "SequenceGap",
|
|
1312
1425
|
expected: this._seq + 1,
|
|
1313
1426
|
actual: next._seq
|
|
1314
1427
|
};
|
|
1315
|
-
throw new ProvenanceMarkError(
|
|
1428
|
+
throw new ProvenanceMarkError("ValidationError", `sequence gap: expected ${this._seq + 1}, got ${next._seq}`, { validationIssue: issue });
|
|
1316
1429
|
}
|
|
1317
1430
|
if (this._date > next._date) {
|
|
1318
1431
|
const dateStr = this._date.toISOString().replace(".000Z", "Z");
|
|
@@ -1322,7 +1435,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1322
1435
|
previous: dateStr,
|
|
1323
1436
|
next: nextDateStr
|
|
1324
1437
|
};
|
|
1325
|
-
throw new ProvenanceMarkError(
|
|
1438
|
+
throw new ProvenanceMarkError("ValidationError", `date ordering: ${dateStr} > ${nextDateStr}`, { validationIssue: issue });
|
|
1326
1439
|
}
|
|
1327
1440
|
const expectedHash = ProvenanceMark.makeHash(this._res, this._key, next._key, this._chainId, this._seqBytes, this._dateBytes, this._infoBytes);
|
|
1328
1441
|
if (!arraysEqual(this._hash, expectedHash)) {
|
|
@@ -1331,7 +1444,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1331
1444
|
expected: bytesToHex(expectedHash),
|
|
1332
1445
|
actual: bytesToHex(this._hash)
|
|
1333
1446
|
};
|
|
1334
|
-
throw new ProvenanceMarkError(
|
|
1447
|
+
throw new ProvenanceMarkError("ValidationError", `hash mismatch: expected ${bytesToHex(expectedHash)}, got ${bytesToHex(this._hash)}`, { validationIssue: issue });
|
|
1335
1448
|
}
|
|
1336
1449
|
}
|
|
1337
1450
|
/**
|
|
@@ -1392,7 +1505,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1392
1505
|
*/
|
|
1393
1506
|
static fromURString(urString) {
|
|
1394
1507
|
const ur = _bcts_uniform_resources.UR.fromURString(urString);
|
|
1395
|
-
if (ur.urTypeStr() !== "provenance") throw new ProvenanceMarkError(
|
|
1508
|
+
if (ur.urTypeStr() !== "provenance") throw new ProvenanceMarkError("CborError", void 0, { message: `Expected UR type 'provenance', got '${ur.urTypeStr()}'` });
|
|
1396
1509
|
return ProvenanceMark.fromUntaggedCbor(ur.cbor());
|
|
1397
1510
|
}
|
|
1398
1511
|
/**
|
|
@@ -1408,7 +1521,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1408
1521
|
*/
|
|
1409
1522
|
static fromUrl(url) {
|
|
1410
1523
|
const param = url.searchParams.get("provenance");
|
|
1411
|
-
if (param === null || param === "") throw new ProvenanceMarkError(
|
|
1524
|
+
if (param === null || param === "") throw new ProvenanceMarkError("MissingUrlParameter", void 0, { parameter: "provenance" });
|
|
1412
1525
|
return ProvenanceMark.fromUrlEncoding(param);
|
|
1413
1526
|
}
|
|
1414
1527
|
/**
|
|
@@ -1437,7 +1550,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1437
1550
|
*/
|
|
1438
1551
|
static fromUntaggedCbor(cborValue) {
|
|
1439
1552
|
const arr = (0, _bcts_dcbor.expectArray)(cborValue);
|
|
1440
|
-
if (arr.length !== 2) throw new ProvenanceMarkError(
|
|
1553
|
+
if (arr.length !== 2) throw new ProvenanceMarkError("CborError", void 0, { message: "Invalid provenance mark length" });
|
|
1441
1554
|
const res = resolutionFromCbor(arr[0]);
|
|
1442
1555
|
const message = (0, _bcts_dcbor.expectBytes)(arr[1]);
|
|
1443
1556
|
return ProvenanceMark.fromMessage(res, message);
|
|
@@ -1447,8 +1560,8 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1447
1560
|
*/
|
|
1448
1561
|
static fromTaggedCbor(cborValue) {
|
|
1449
1562
|
const cborObj = cborValue;
|
|
1450
|
-
if (cborObj.tag !== _bcts_tags.PROVENANCE_MARK.value) throw new ProvenanceMarkError(
|
|
1451
|
-
if (cborObj.value === void 0) throw new ProvenanceMarkError(
|
|
1563
|
+
if (cborObj.tag !== _bcts_tags.PROVENANCE_MARK.value) throw new ProvenanceMarkError("CborError", void 0, { message: `Expected tag ${_bcts_tags.PROVENANCE_MARK.value}, got ${String(cborObj.tag)}` });
|
|
1564
|
+
if (cborObj.value === void 0) throw new ProvenanceMarkError("CborError", void 0, { message: "Tagged CBOR value is missing" });
|
|
1452
1565
|
return ProvenanceMark.fromUntaggedCbor(cborObj.value);
|
|
1453
1566
|
}
|
|
1454
1567
|
/**
|
|
@@ -1466,9 +1579,13 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1466
1579
|
}
|
|
1467
1580
|
/**
|
|
1468
1581
|
* Debug string representation.
|
|
1582
|
+
*
|
|
1583
|
+
* As of provenance-mark v0.24, this includes the full 64-character Mark ID
|
|
1584
|
+
* hex (matching rust's `Display` impl). Pre-v0.24 callers that depended on
|
|
1585
|
+
* the 8-character prefix should use `idHex().slice(0, 8)` directly.
|
|
1469
1586
|
*/
|
|
1470
1587
|
toString() {
|
|
1471
|
-
return `ProvenanceMark(${this.
|
|
1588
|
+
return `ProvenanceMark(${this.idHex()})`;
|
|
1472
1589
|
}
|
|
1473
1590
|
/**
|
|
1474
1591
|
* Detailed debug representation.
|
|
@@ -1559,7 +1676,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1559
1676
|
static fromEnvelope(envelope) {
|
|
1560
1677
|
const leaf = envelope.subject().asLeaf();
|
|
1561
1678
|
if (leaf !== void 0) return ProvenanceMark.fromTaggedCbor(leaf);
|
|
1562
|
-
throw new ProvenanceMarkError(
|
|
1679
|
+
throw new ProvenanceMarkError("CborError", void 0, { message: "Could not extract ProvenanceMark from envelope" });
|
|
1563
1680
|
}
|
|
1564
1681
|
};
|
|
1565
1682
|
/**
|
|
@@ -1570,7 +1687,6 @@ function arraysEqual(a, b) {
|
|
|
1570
1687
|
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
1571
1688
|
return true;
|
|
1572
1689
|
}
|
|
1573
|
-
|
|
1574
1690
|
//#endregion
|
|
1575
1691
|
//#region src/generator.ts
|
|
1576
1692
|
/**
|
|
@@ -1644,7 +1760,7 @@ var ProvenanceMarkGenerator = class ProvenanceMarkGenerator {
|
|
|
1644
1760
|
*/
|
|
1645
1761
|
static new(res, seed, chainId, nextSeq, rngState) {
|
|
1646
1762
|
const linkLen = linkLength(res);
|
|
1647
|
-
if (chainId.length !== linkLen) throw new ProvenanceMarkError(
|
|
1763
|
+
if (chainId.length !== linkLen) throw new ProvenanceMarkError("InvalidChainIdLength", void 0, {
|
|
1648
1764
|
expected: linkLen,
|
|
1649
1765
|
actual: chainId.length
|
|
1650
1766
|
});
|
|
@@ -1727,35 +1843,34 @@ var ProvenanceMarkGenerator = class ProvenanceMarkGenerator {
|
|
|
1727
1843
|
*/
|
|
1728
1844
|
static fromEnvelope(envelope) {
|
|
1729
1845
|
const env = envelope;
|
|
1730
|
-
if (!env.hasType("provenance-generator")) throw new ProvenanceMarkError(
|
|
1846
|
+
if (!env.hasType("provenance-generator")) throw new ProvenanceMarkError("CborError", void 0, { message: "Envelope is not a provenance-generator" });
|
|
1731
1847
|
const chainId = env.subject().asByteString();
|
|
1732
|
-
if (chainId === void 0) throw new ProvenanceMarkError(
|
|
1848
|
+
if (chainId === void 0) throw new ProvenanceMarkError("CborError", void 0, { message: "Could not extract chain ID" });
|
|
1733
1849
|
const extractAssertion = (predicate) => {
|
|
1734
1850
|
const assertions = env.assertionsWithPredicate(predicate);
|
|
1735
|
-
if (assertions.length === 0) throw new ProvenanceMarkError(
|
|
1851
|
+
if (assertions.length === 0) throw new ProvenanceMarkError("CborError", void 0, { message: `Missing ${predicate} assertion` });
|
|
1736
1852
|
const assertionCase = assertions[0].case();
|
|
1737
|
-
if (assertionCase.type !== "assertion") throw new ProvenanceMarkError(
|
|
1853
|
+
if (assertionCase.type !== "assertion") throw new ProvenanceMarkError("CborError", void 0, { message: `Invalid ${predicate} assertion` });
|
|
1738
1854
|
const obj = assertionCase.assertion.object();
|
|
1739
1855
|
const objCase = obj.case();
|
|
1740
1856
|
if (objCase.type === "leaf") return {
|
|
1741
1857
|
cbor: objCase.cbor,
|
|
1742
1858
|
bytes: obj.asByteString()
|
|
1743
1859
|
};
|
|
1744
|
-
throw new ProvenanceMarkError(
|
|
1860
|
+
throw new ProvenanceMarkError("CborError", void 0, { message: `Invalid ${predicate} value` });
|
|
1745
1861
|
};
|
|
1746
1862
|
const res = resolutionFromCbor(extractAssertion("res").cbor);
|
|
1747
1863
|
const seedValue = extractAssertion("seed");
|
|
1748
|
-
if (seedValue.bytes === void 0) throw new ProvenanceMarkError(
|
|
1864
|
+
if (seedValue.bytes === void 0) throw new ProvenanceMarkError("CborError", void 0, { message: "Invalid seed data" });
|
|
1749
1865
|
const seed = ProvenanceSeed.fromBytes(seedValue.bytes);
|
|
1750
1866
|
const seqValue = extractAssertion("next-seq");
|
|
1751
1867
|
const nextSeq = Number(seqValue.cbor);
|
|
1752
1868
|
const rngValue = extractAssertion("rng-state");
|
|
1753
|
-
if (rngValue.bytes === void 0) throw new ProvenanceMarkError(
|
|
1869
|
+
if (rngValue.bytes === void 0) throw new ProvenanceMarkError("CborError", void 0, { message: "Invalid rng-state data" });
|
|
1754
1870
|
const rngState = RngState.fromBytes(rngValue.bytes);
|
|
1755
1871
|
return ProvenanceMarkGenerator.new(res, seed, chainId, nextSeq, rngState);
|
|
1756
1872
|
}
|
|
1757
1873
|
};
|
|
1758
|
-
|
|
1759
1874
|
//#endregion
|
|
1760
1875
|
//#region src/mark-info.ts
|
|
1761
1876
|
/**
|
|
@@ -1786,7 +1901,7 @@ var ProvenanceMarkInfo = class ProvenanceMarkInfo {
|
|
|
1786
1901
|
const tagName = _bcts_tags.PROVENANCE_MARK.name;
|
|
1787
1902
|
if (tagName === void 0) throw new Error("PROVENANCE_MARK tag has no name");
|
|
1788
1903
|
const cborValue = (0, _bcts_dcbor.decodeCbor)(mark.toCborData());
|
|
1789
|
-
return new ProvenanceMarkInfo(mark, _bcts_uniform_resources.UR.new(tagName, cborValue), mark.
|
|
1904
|
+
return new ProvenanceMarkInfo(mark, _bcts_uniform_resources.UR.new(tagName, cborValue), mark.idBytewords(4, true), mark.idBytemoji(4, true), comment);
|
|
1790
1905
|
}
|
|
1791
1906
|
mark() {
|
|
1792
1907
|
return this._mark;
|
|
@@ -1850,7 +1965,6 @@ var ProvenanceMarkInfo = class ProvenanceMarkInfo {
|
|
|
1850
1965
|
return new ProvenanceMarkInfo(mark, ur, bytewords, bytemoji, typeof json["comment"] === "string" ? json["comment"] : "");
|
|
1851
1966
|
}
|
|
1852
1967
|
};
|
|
1853
|
-
|
|
1854
1968
|
//#endregion
|
|
1855
1969
|
//#region src/envelope.ts
|
|
1856
1970
|
/**
|
|
@@ -1948,13 +2062,12 @@ function provenanceMarkGeneratorToEnvelope(generator) {
|
|
|
1948
2062
|
function provenanceMarkGeneratorFromEnvelope(envelope) {
|
|
1949
2063
|
return ProvenanceMarkGenerator.fromEnvelope(envelope);
|
|
1950
2064
|
}
|
|
1951
|
-
|
|
1952
2065
|
//#endregion
|
|
1953
|
-
Object.defineProperty(exports,
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
2066
|
+
Object.defineProperty(exports, "FormatContext", {
|
|
2067
|
+
enumerable: true,
|
|
2068
|
+
get: function() {
|
|
2069
|
+
return _bcts_envelope.FormatContext;
|
|
2070
|
+
}
|
|
1958
2071
|
});
|
|
1959
2072
|
exports.PROVENANCE_SEED_LENGTH = PROVENANCE_SEED_LENGTH;
|
|
1960
2073
|
exports.ProvenanceMark = ProvenanceMark;
|
|
@@ -2014,4 +2127,5 @@ exports.serializeSeq = serializeSeq;
|
|
|
2014
2127
|
exports.sha256 = sha256;
|
|
2015
2128
|
exports.sha256Prefix = sha256Prefix;
|
|
2016
2129
|
exports.validate = validate;
|
|
2130
|
+
|
|
2017
2131
|
//# sourceMappingURL=index.cjs.map
|