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