@bcts/provenance-mark 1.0.0-alpha.12 → 1.0.0-alpha.13
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/dist/index.cjs +232 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +106 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +233 -5
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +227 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
- package/src/envelope.ts +232 -0
- package/src/generator.ts +131 -1
- package/src/index.ts +11 -0
- package/src/mark.ts +81 -3
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { chacha20 } from "@noble/ciphers/chacha.js";
|
|
|
6
6
|
import { randomData } from "@bcts/rand";
|
|
7
7
|
import { PROVENANCE_MARK } from "@bcts/tags";
|
|
8
8
|
import { BytewordsStyle, UR, decodeBytewords, encodeBytemojisIdentifier, encodeBytewords, encodeBytewordsIdentifier } from "@bcts/uniform-resources";
|
|
9
|
+
import { Envelope } from "@bcts/envelope";
|
|
9
10
|
|
|
10
11
|
//#region rolldown:runtime
|
|
11
12
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
@@ -1019,7 +1020,7 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1019
1020
|
return ProvenanceMark.fromMessage(res, message);
|
|
1020
1021
|
}
|
|
1021
1022
|
/**
|
|
1022
|
-
* Encode for URL (minimal bytewords of CBOR).
|
|
1023
|
+
* Encode for URL (minimal bytewords of tagged CBOR).
|
|
1023
1024
|
*/
|
|
1024
1025
|
toUrlEncoding() {
|
|
1025
1026
|
return encodeBytewords(this.toCborData(), BytewordsStyle.Minimal);
|
|
@@ -1032,6 +1033,20 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1032
1033
|
return ProvenanceMark.fromTaggedCbor(cborValue);
|
|
1033
1034
|
}
|
|
1034
1035
|
/**
|
|
1036
|
+
* Get the UR string representation (e.g., "ur:provenance/...").
|
|
1037
|
+
*/
|
|
1038
|
+
urString() {
|
|
1039
|
+
return UR.new("provenance", this.untaggedCbor()).string();
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Create from a UR string.
|
|
1043
|
+
*/
|
|
1044
|
+
static fromURString(urString) {
|
|
1045
|
+
const ur = UR.fromURString(urString);
|
|
1046
|
+
if (ur.urTypeStr() !== "provenance") throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Expected UR type 'provenance', got '${ur.urTypeStr()}'` });
|
|
1047
|
+
return ProvenanceMark.fromUntaggedCbor(ur.cbor());
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1035
1050
|
* Build a URL with this mark as a query parameter.
|
|
1036
1051
|
*/
|
|
1037
1052
|
toUrl(base) {
|
|
@@ -1108,17 +1123,23 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1108
1123
|
}
|
|
1109
1124
|
/**
|
|
1110
1125
|
* Detailed debug representation.
|
|
1126
|
+
* Matches Rust format exactly for parity.
|
|
1111
1127
|
*/
|
|
1112
1128
|
toDebugString() {
|
|
1129
|
+
const dateStr = this._date.toISOString().replace(".000Z", "Z");
|
|
1113
1130
|
const components = [
|
|
1114
1131
|
`key: ${bytesToHex(this._key)}`,
|
|
1115
1132
|
`hash: ${bytesToHex(this._hash)}`,
|
|
1116
1133
|
`chainID: ${bytesToHex(this._chainId)}`,
|
|
1117
1134
|
`seq: ${this._seq}`,
|
|
1118
|
-
`date: ${
|
|
1135
|
+
`date: ${dateStr}`
|
|
1119
1136
|
];
|
|
1120
1137
|
const info = this.info();
|
|
1121
|
-
if (info !== void 0)
|
|
1138
|
+
if (info !== void 0) {
|
|
1139
|
+
const textValue = info.asText();
|
|
1140
|
+
if (textValue !== void 0) components.push(`info: "${textValue}"`);
|
|
1141
|
+
else components.push(`info: ${info.toDiagnostic()}`);
|
|
1142
|
+
}
|
|
1122
1143
|
return `ProvenanceMark(${components.join(", ")})`;
|
|
1123
1144
|
}
|
|
1124
1145
|
/**
|
|
@@ -1159,6 +1180,33 @@ var ProvenanceMark = class ProvenanceMark {
|
|
|
1159
1180
|
if (typeof json["info_bytes"] === "string") infoBytes = fromBase64(json["info_bytes"]);
|
|
1160
1181
|
return new ProvenanceMark(res, key, hash, chainId, seqBytes, dateBytes, infoBytes, seq, date);
|
|
1161
1182
|
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Convert this provenance mark to a Gordian Envelope.
|
|
1185
|
+
*
|
|
1186
|
+
* The envelope contains the tagged CBOR representation of the mark.
|
|
1187
|
+
*
|
|
1188
|
+
* Note: Use provenanceMarkToEnvelope() for a standalone function alternative.
|
|
1189
|
+
*/
|
|
1190
|
+
intoEnvelope() {
|
|
1191
|
+
return Envelope.new(this.toCborData());
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Extract a ProvenanceMark from a Gordian Envelope.
|
|
1195
|
+
*
|
|
1196
|
+
* @param envelope - The envelope to extract from
|
|
1197
|
+
* @returns The extracted provenance mark
|
|
1198
|
+
* @throws ProvenanceMarkError if extraction fails
|
|
1199
|
+
*/
|
|
1200
|
+
static fromEnvelope(envelope) {
|
|
1201
|
+
const bytes = envelope.asByteString();
|
|
1202
|
+
if (bytes !== void 0) return ProvenanceMark.fromCborData(bytes);
|
|
1203
|
+
const envCase = envelope.case();
|
|
1204
|
+
if (envCase.type === "node") {
|
|
1205
|
+
const subjectBytes = envCase.subject.asByteString();
|
|
1206
|
+
if (subjectBytes !== void 0) return ProvenanceMark.fromCborData(subjectBytes);
|
|
1207
|
+
}
|
|
1208
|
+
throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Could not extract ProvenanceMark from envelope" });
|
|
1209
|
+
}
|
|
1162
1210
|
};
|
|
1163
1211
|
/**
|
|
1164
1212
|
* Helper function to compare two Uint8Arrays.
|
|
@@ -1290,6 +1338,63 @@ var ProvenanceMarkGenerator = class ProvenanceMarkGenerator {
|
|
|
1290
1338
|
const rngState = RngState.fromBytes(fromBase64(json["rngState"]));
|
|
1291
1339
|
return ProvenanceMarkGenerator.new(res, seed, chainId, nextSeq, rngState);
|
|
1292
1340
|
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Convert this generator to a Gordian Envelope.
|
|
1343
|
+
*
|
|
1344
|
+
* The envelope contains structured assertions for all generator fields:
|
|
1345
|
+
* - isA: "provenance-generator"
|
|
1346
|
+
* - res: The resolution
|
|
1347
|
+
* - seed: The seed
|
|
1348
|
+
* - next-seq: The next sequence number
|
|
1349
|
+
* - rng-state: The RNG state
|
|
1350
|
+
*
|
|
1351
|
+
* Note: Use provenanceMarkGeneratorToEnvelope() for a standalone function alternative.
|
|
1352
|
+
*/
|
|
1353
|
+
intoEnvelope() {
|
|
1354
|
+
let envelope = Envelope.new(this._chainId);
|
|
1355
|
+
envelope = envelope.addAssertion("isA", "provenance-generator");
|
|
1356
|
+
envelope = envelope.addAssertion("res", resolutionToNumber(this._res));
|
|
1357
|
+
envelope = envelope.addAssertion("seed", this._seed.toBytes());
|
|
1358
|
+
envelope = envelope.addAssertion("next-seq", this._nextSeq);
|
|
1359
|
+
envelope = envelope.addAssertion("rng-state", this._rngState.toBytes());
|
|
1360
|
+
return envelope;
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Extract a ProvenanceMarkGenerator from a Gordian Envelope.
|
|
1364
|
+
*
|
|
1365
|
+
* @param envelope - The envelope to extract from
|
|
1366
|
+
* @returns The extracted generator
|
|
1367
|
+
* @throws ProvenanceMarkError if extraction fails
|
|
1368
|
+
*/
|
|
1369
|
+
static fromEnvelope(envelope) {
|
|
1370
|
+
const env = envelope;
|
|
1371
|
+
if (!env.hasType("provenance-generator")) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Envelope is not a provenance-generator" });
|
|
1372
|
+
const chainId = env.subject().asByteString();
|
|
1373
|
+
if (chainId === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Could not extract chain ID" });
|
|
1374
|
+
const extractAssertion = (predicate) => {
|
|
1375
|
+
const assertions = env.assertionsWithPredicate(predicate);
|
|
1376
|
+
if (assertions.length === 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Missing ${predicate} assertion` });
|
|
1377
|
+
const assertionCase = assertions[0].case();
|
|
1378
|
+
if (assertionCase.type !== "assertion") throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Invalid ${predicate} assertion` });
|
|
1379
|
+
const obj = assertionCase.assertion.object();
|
|
1380
|
+
const objCase = obj.case();
|
|
1381
|
+
if (objCase.type === "leaf") return {
|
|
1382
|
+
cbor: objCase.cbor,
|
|
1383
|
+
bytes: obj.asByteString()
|
|
1384
|
+
};
|
|
1385
|
+
throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Invalid ${predicate} value` });
|
|
1386
|
+
};
|
|
1387
|
+
const res = resolutionFromCbor(extractAssertion("res").cbor);
|
|
1388
|
+
const seedValue = extractAssertion("seed");
|
|
1389
|
+
if (seedValue.bytes === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Invalid seed data" });
|
|
1390
|
+
const seed = ProvenanceSeed.fromBytes(seedValue.bytes);
|
|
1391
|
+
const seqValue = extractAssertion("next-seq");
|
|
1392
|
+
const nextSeq = Number(seqValue.cbor);
|
|
1393
|
+
const rngValue = extractAssertion("rng-state");
|
|
1394
|
+
if (rngValue.bytes === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Invalid rng-state data" });
|
|
1395
|
+
const rngState = RngState.fromBytes(rngValue.bytes);
|
|
1396
|
+
return ProvenanceMarkGenerator.new(res, seed, chainId, nextSeq, rngState);
|
|
1397
|
+
}
|
|
1293
1398
|
};
|
|
1294
1399
|
|
|
1295
1400
|
//#endregion
|
|
@@ -1653,5 +1758,123 @@ var ProvenanceMarkInfo = class ProvenanceMarkInfo {
|
|
|
1653
1758
|
};
|
|
1654
1759
|
|
|
1655
1760
|
//#endregion
|
|
1656
|
-
|
|
1761
|
+
//#region src/envelope.ts
|
|
1762
|
+
/**
|
|
1763
|
+
* Envelope support for Provenance Marks
|
|
1764
|
+
*
|
|
1765
|
+
* This module provides Gordian Envelope integration for ProvenanceMark and
|
|
1766
|
+
* ProvenanceMarkGenerator, enabling them to be used with the bc-envelope
|
|
1767
|
+
* ecosystem.
|
|
1768
|
+
*
|
|
1769
|
+
* Ported from provenance-mark-rust/src/mark.rs and generator.rs (envelope feature)
|
|
1770
|
+
*/
|
|
1771
|
+
/**
|
|
1772
|
+
* Registers provenance mark tags in the global format context.
|
|
1773
|
+
*
|
|
1774
|
+
* This function sets up a summarizer for the PROVENANCE_MARK tag that displays
|
|
1775
|
+
* provenance marks in a human-readable format.
|
|
1776
|
+
*/
|
|
1777
|
+
function registerTags() {
|
|
1778
|
+
registerTagsIn(globalTagsContext);
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Registers provenance mark tags in a specific format context.
|
|
1782
|
+
*
|
|
1783
|
+
* @param context - The format context to register tags in
|
|
1784
|
+
*/
|
|
1785
|
+
function registerTagsIn(context) {
|
|
1786
|
+
context.setSummarizer(Number(PROVENANCE_MARK.value), (cborValue) => {
|
|
1787
|
+
return ProvenanceMark.fromUntaggedCbor(cborValue).toString();
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1790
|
+
const globalTagsContext = { setSummarizer(_tag, _summarizer) {} };
|
|
1791
|
+
/**
|
|
1792
|
+
* Convert a ProvenanceMark to an Envelope.
|
|
1793
|
+
*
|
|
1794
|
+
* The envelope contains the tagged CBOR representation of the mark.
|
|
1795
|
+
*
|
|
1796
|
+
* @param mark - The provenance mark to convert
|
|
1797
|
+
* @returns An envelope containing the mark
|
|
1798
|
+
*/
|
|
1799
|
+
function provenanceMarkToEnvelope(mark) {
|
|
1800
|
+
return Envelope.new(mark.toCborData());
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Extract a ProvenanceMark from an Envelope.
|
|
1804
|
+
*
|
|
1805
|
+
* @param envelope - The envelope to extract from
|
|
1806
|
+
* @returns The extracted provenance mark
|
|
1807
|
+
* @throws ProvenanceMarkError if extraction fails
|
|
1808
|
+
*/
|
|
1809
|
+
function provenanceMarkFromEnvelope(envelope) {
|
|
1810
|
+
const bytes = envelope.asByteString();
|
|
1811
|
+
if (bytes !== void 0) return ProvenanceMark.fromCborData(bytes);
|
|
1812
|
+
const envCase = envelope.case();
|
|
1813
|
+
if (envCase.type === "node") {
|
|
1814
|
+
const subjectBytes = envCase.subject.asByteString();
|
|
1815
|
+
if (subjectBytes !== void 0) return ProvenanceMark.fromCborData(subjectBytes);
|
|
1816
|
+
}
|
|
1817
|
+
throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Could not extract ProvenanceMark from envelope" });
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* Convert a ProvenanceMarkGenerator to an Envelope.
|
|
1821
|
+
*
|
|
1822
|
+
* The envelope contains structured assertions for all generator fields:
|
|
1823
|
+
* - type: "provenance-generator"
|
|
1824
|
+
* - res: The resolution
|
|
1825
|
+
* - seed: The seed
|
|
1826
|
+
* - next-seq: The next sequence number
|
|
1827
|
+
* - rng-state: The RNG state
|
|
1828
|
+
*
|
|
1829
|
+
* @param generator - The generator to convert
|
|
1830
|
+
* @returns An envelope containing the generator
|
|
1831
|
+
*/
|
|
1832
|
+
function provenanceMarkGeneratorToEnvelope(generator) {
|
|
1833
|
+
let envelope = Envelope.new(generator.chainId());
|
|
1834
|
+
envelope = envelope.addAssertion("isA", "provenance-generator");
|
|
1835
|
+
envelope = envelope.addAssertion("res", resolutionToNumber(generator.res()));
|
|
1836
|
+
envelope = envelope.addAssertion("seed", generator.seed().toBytes());
|
|
1837
|
+
envelope = envelope.addAssertion("next-seq", generator.nextSeq());
|
|
1838
|
+
envelope = envelope.addAssertion("rng-state", generator.rngState().toBytes());
|
|
1839
|
+
return envelope;
|
|
1840
|
+
}
|
|
1841
|
+
/**
|
|
1842
|
+
* Extract a ProvenanceMarkGenerator from an Envelope.
|
|
1843
|
+
*
|
|
1844
|
+
* @param envelope - The envelope to extract from
|
|
1845
|
+
* @returns The extracted generator
|
|
1846
|
+
* @throws ProvenanceMarkError if extraction fails
|
|
1847
|
+
*/
|
|
1848
|
+
function provenanceMarkGeneratorFromEnvelope(envelope) {
|
|
1849
|
+
const env = envelope;
|
|
1850
|
+
if (!env.hasType("provenance-generator")) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Envelope is not a provenance-generator" });
|
|
1851
|
+
const chainId = env.subject().asByteString();
|
|
1852
|
+
if (chainId === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Could not extract chain ID" });
|
|
1853
|
+
const extractAssertion = (predicate) => {
|
|
1854
|
+
const assertions = env.assertionsWithPredicate(predicate);
|
|
1855
|
+
if (assertions.length === 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Missing ${predicate} assertion` });
|
|
1856
|
+
const assertionCase = assertions[0].case();
|
|
1857
|
+
if (assertionCase.type !== "assertion") throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Invalid ${predicate} assertion` });
|
|
1858
|
+
const obj = assertionCase.assertion.object();
|
|
1859
|
+
const objCase = obj.case();
|
|
1860
|
+
if (objCase.type === "leaf") return {
|
|
1861
|
+
cbor: objCase.cbor,
|
|
1862
|
+
bytes: obj.asByteString()
|
|
1863
|
+
};
|
|
1864
|
+
throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: `Invalid ${predicate} value` });
|
|
1865
|
+
};
|
|
1866
|
+
const res = resolutionFromCbor(extractAssertion("res").cbor);
|
|
1867
|
+
const seedValue = extractAssertion("seed");
|
|
1868
|
+
if (seedValue.bytes === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Invalid seed data" });
|
|
1869
|
+
const seed = ProvenanceSeed.fromBytes(seedValue.bytes);
|
|
1870
|
+
const seqValue = extractAssertion("next-seq");
|
|
1871
|
+
const nextSeq = Number(seqValue.cbor);
|
|
1872
|
+
const rngValue = extractAssertion("rng-state");
|
|
1873
|
+
if (rngValue.bytes === void 0) throw new ProvenanceMarkError(ProvenanceMarkErrorType.CborError, void 0, { message: "Invalid rng-state data" });
|
|
1874
|
+
const rngState = RngState.fromBytes(rngValue.bytes);
|
|
1875
|
+
return ProvenanceMarkGenerator.new(res, seed, chainId, nextSeq, rngState);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
//#endregion
|
|
1879
|
+
export { 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 };
|
|
1657
1880
|
//# sourceMappingURL=index.mjs.map
|