@bcts/xid 1.0.0-alpha.17 → 1.0.0-alpha.18
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 +324 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +145 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +145 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +326 -40
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +316 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +3 -0
- package/src/key.ts +81 -15
- package/src/provenance.ts +75 -19
- package/src/service.ts +17 -1
- package/src/xid-document.ts +334 -29
package/README.md
CHANGED
|
@@ -12,4 +12,4 @@ XIDs and XID documents are discussed in [this paper](https://hackmd.io/@bc-commu
|
|
|
12
12
|
|
|
13
13
|
## Rust Reference Implementation
|
|
14
14
|
|
|
15
|
-
This TypeScript implementation is based on [bc-xid-rust](https://github.com/BlockchainCommons/bc-xid-rust) **v0.
|
|
15
|
+
This TypeScript implementation is based on [bc-xid-rust](https://github.com/BlockchainCommons/bc-xid-rust) **v0.21.0** ([commit](https://github.com/BlockchainCommons/bc-xid-rust/tree/f0dc62187fc728d92063ee0ff456a9552a4698cf)).
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,6 @@ let _bcts_components = require("@bcts/components");
|
|
|
2
2
|
let _bcts_known_values = require("@bcts/known-values");
|
|
3
3
|
let _bcts_envelope = require("@bcts/envelope");
|
|
4
4
|
let _bcts_provenance_mark = require("@bcts/provenance-mark");
|
|
5
|
-
let _bcts_dcbor = require("@bcts/dcbor");
|
|
6
5
|
|
|
7
6
|
//#region src/error.ts
|
|
8
7
|
/**
|
|
@@ -618,8 +617,8 @@ var Key = class Key {
|
|
|
618
617
|
* Create a new Key with private key base (derives keys from it).
|
|
619
618
|
*/
|
|
620
619
|
static newWithPrivateKeyBase(privateKeyBase) {
|
|
621
|
-
const privateKeys = privateKeyBase.
|
|
622
|
-
const publicKeys = privateKeyBase.
|
|
620
|
+
const privateKeys = privateKeyBase.schnorrPrivateKeys();
|
|
621
|
+
const publicKeys = privateKeyBase.schnorrPublicKeys();
|
|
623
622
|
return Key.newWithPrivateKeys(privateKeys, publicKeys);
|
|
624
623
|
}
|
|
625
624
|
/**
|
|
@@ -660,6 +659,18 @@ var Key = class Key {
|
|
|
660
659
|
return this._publicKeys.reference();
|
|
661
660
|
}
|
|
662
661
|
/**
|
|
662
|
+
* Get the signing public key.
|
|
663
|
+
*/
|
|
664
|
+
signingPublicKey() {
|
|
665
|
+
return this._publicKeys.signingPublicKey();
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Get the encapsulation public key.
|
|
669
|
+
*/
|
|
670
|
+
encapsulationPublicKey() {
|
|
671
|
+
return this._publicKeys.encapsulationPublicKey();
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
663
674
|
* Verify a signature against a message.
|
|
664
675
|
*/
|
|
665
676
|
verify(signature, message) {
|
|
@@ -724,7 +735,9 @@ var Key = class Key {
|
|
|
724
735
|
}
|
|
725
736
|
case XIDPrivateKeyOptions.Encrypt:
|
|
726
737
|
if (typeof privateKeyOptions === "object") {
|
|
727
|
-
const
|
|
738
|
+
const privateKeysEnvelope = _bcts_envelope.Envelope.new(data.privateKeys.taggedCborData());
|
|
739
|
+
const method = privateKeyOptions.method ?? (0, _bcts_components.defaultKeyDerivationMethod)();
|
|
740
|
+
const encrypted = privateKeysEnvelope.lockSubject(method, privateKeyOptions.password);
|
|
728
741
|
envelope = envelope.addAssertion(kv$3(_bcts_known_values.PRIVATE_KEY), encrypted);
|
|
729
742
|
envelope = envelope.addAssertion(kv$3(_bcts_known_values.SALT), salt.toData());
|
|
730
743
|
}
|
|
@@ -746,9 +759,15 @@ var Key = class Key {
|
|
|
746
759
|
*/
|
|
747
760
|
static tryFromEnvelope(envelope, password) {
|
|
748
761
|
const env = envelope;
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
const
|
|
762
|
+
const subject = env.case().type === "node" ? env.subject() : env;
|
|
763
|
+
let publicKeys;
|
|
764
|
+
const publicKeysData = subject.asByteString();
|
|
765
|
+
if (publicKeysData !== void 0) publicKeys = _bcts_components.PublicKeys.fromTaggedCborData(publicKeysData);
|
|
766
|
+
else {
|
|
767
|
+
const leaf = subject.asLeaf?.();
|
|
768
|
+
if (leaf === void 0) throw XIDError.component(/* @__PURE__ */ new Error("Could not extract public keys from envelope"));
|
|
769
|
+
publicKeys = _bcts_components.PublicKeys.fromTaggedCbor(leaf);
|
|
770
|
+
}
|
|
752
771
|
let privateKeyData;
|
|
753
772
|
let salt = _bcts_components.Salt.random(32);
|
|
754
773
|
const saltAssertions = env.assertionsWithPredicate(_bcts_known_values.SALT);
|
|
@@ -764,8 +783,8 @@ var Key = class Key {
|
|
|
764
783
|
const assertionCase = privateKeyAssertions[0].case();
|
|
765
784
|
if (assertionCase.type === "assertion") {
|
|
766
785
|
const privateKeyObject = assertionCase.assertion.object();
|
|
767
|
-
if (privateKeyObject.
|
|
768
|
-
const decryptedData = privateKeyObject.
|
|
786
|
+
if (privateKeyObject.isLockedWithPassword()) if (password !== void 0) try {
|
|
787
|
+
const decryptedData = privateKeyObject.unlockSubject(password).subject().asByteString();
|
|
769
788
|
if (decryptedData !== void 0) privateKeyData = {
|
|
770
789
|
data: {
|
|
771
790
|
type: "decrypted",
|
|
@@ -816,6 +835,27 @@ var Key = class Key {
|
|
|
816
835
|
return new Key(publicKeys, privateKeyData, nickname, endpoints, permissions);
|
|
817
836
|
}
|
|
818
837
|
/**
|
|
838
|
+
* Get the private key envelope, optionally decrypting it.
|
|
839
|
+
*
|
|
840
|
+
* Returns:
|
|
841
|
+
* - undefined if no private keys
|
|
842
|
+
* - The decrypted private key envelope if unencrypted
|
|
843
|
+
* - The decrypted envelope if encrypted + correct password
|
|
844
|
+
* - The encrypted envelope as-is if encrypted + no password
|
|
845
|
+
* - Throws on wrong password
|
|
846
|
+
*/
|
|
847
|
+
privateKeyEnvelope(password) {
|
|
848
|
+
if (this._privateKeyData === void 0) return;
|
|
849
|
+
const { data } = this._privateKeyData;
|
|
850
|
+
if (data.type === "decrypted") return _bcts_envelope.Envelope.new(data.privateKeys.taggedCborData());
|
|
851
|
+
if (password !== void 0) try {
|
|
852
|
+
return data.envelope.unlockSubject(new TextEncoder().encode(password));
|
|
853
|
+
} catch {
|
|
854
|
+
throw XIDError.invalidPassword();
|
|
855
|
+
}
|
|
856
|
+
return data.envelope;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
819
859
|
* Check equality with another Key.
|
|
820
860
|
*/
|
|
821
861
|
equals(other) {
|
|
@@ -955,6 +995,20 @@ var Service = class Service {
|
|
|
955
995
|
this.addDelegateReferenceHex(delegateReference.toHex());
|
|
956
996
|
}
|
|
957
997
|
/**
|
|
998
|
+
* Add a key by its public keys provider (convenience method).
|
|
999
|
+
* Matches Rust's `add_key(&mut self, key: &dyn PublicKeysProvider)`.
|
|
1000
|
+
*/
|
|
1001
|
+
addKey(keyProvider) {
|
|
1002
|
+
this.addKeyReference(keyProvider.publicKeys().reference());
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Add a delegate by its XID provider (convenience method).
|
|
1006
|
+
* Matches Rust's `add_delegate(&mut self, delegate: &dyn XIDProvider)`.
|
|
1007
|
+
*/
|
|
1008
|
+
addDelegate(xidProvider) {
|
|
1009
|
+
this.addDelegateReference(_bcts_components.Reference.hash(xidProvider.xid().toData()));
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
958
1012
|
* Get the name.
|
|
959
1013
|
*/
|
|
960
1014
|
name() {
|
|
@@ -1171,6 +1225,8 @@ var Delegate = class Delegate {
|
|
|
1171
1225
|
* Ported from bc-xid-rust/src/provenance.rs
|
|
1172
1226
|
*/
|
|
1173
1227
|
const kv$1 = (v) => v;
|
|
1228
|
+
const encodeGeneratorJSON = (json) => new TextEncoder().encode(JSON.stringify(json));
|
|
1229
|
+
const decodeGeneratorJSON = (data) => JSON.parse(new TextDecoder().decode(data));
|
|
1174
1230
|
/**
|
|
1175
1231
|
* Options for handling generators in envelopes.
|
|
1176
1232
|
*/
|
|
@@ -1281,9 +1337,9 @@ var Provenance = class Provenance {
|
|
|
1281
1337
|
if (password !== void 0) {
|
|
1282
1338
|
const encryptedEnvelope = this._generator.data.envelope;
|
|
1283
1339
|
try {
|
|
1284
|
-
const generatorData = encryptedEnvelope.
|
|
1340
|
+
const generatorData = encryptedEnvelope.unlockSubject(password).subject().tryUnwrap().asByteString();
|
|
1285
1341
|
if (generatorData !== void 0) {
|
|
1286
|
-
const json = (
|
|
1342
|
+
const json = decodeGeneratorJSON(generatorData);
|
|
1287
1343
|
const generator = _bcts_provenance_mark.ProvenanceMarkGenerator.fromJSON(json);
|
|
1288
1344
|
this._generator = {
|
|
1289
1345
|
data: {
|
|
@@ -1301,6 +1357,30 @@ var Provenance = class Provenance {
|
|
|
1301
1357
|
throw XIDError.invalidPassword();
|
|
1302
1358
|
}
|
|
1303
1359
|
/**
|
|
1360
|
+
* Get the generator envelope, optionally decrypting it.
|
|
1361
|
+
*
|
|
1362
|
+
* Returns:
|
|
1363
|
+
* - undefined if no generator
|
|
1364
|
+
* - An envelope containing the generator if unencrypted
|
|
1365
|
+
* - The decrypted envelope if encrypted + correct password
|
|
1366
|
+
* - The encrypted envelope as-is if encrypted + no password
|
|
1367
|
+
* - Throws on wrong password
|
|
1368
|
+
*/
|
|
1369
|
+
generatorEnvelope(password) {
|
|
1370
|
+
if (this._generator === void 0) return;
|
|
1371
|
+
const { data } = this._generator;
|
|
1372
|
+
if (data.type === "decrypted") {
|
|
1373
|
+
const generatorBytes = encodeGeneratorJSON(data.generator.toJSON());
|
|
1374
|
+
return _bcts_envelope.Envelope.new(generatorBytes);
|
|
1375
|
+
}
|
|
1376
|
+
if (password !== void 0) try {
|
|
1377
|
+
return data.envelope.unlockSubject(new TextEncoder().encode(password)).subject().tryUnwrap();
|
|
1378
|
+
} catch {
|
|
1379
|
+
throw XIDError.invalidPassword();
|
|
1380
|
+
}
|
|
1381
|
+
return data.envelope;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1304
1384
|
* Convert to envelope with specified options.
|
|
1305
1385
|
*/
|
|
1306
1386
|
intoEnvelopeOpt(generatorOptions = XIDGeneratorOptions.Omit) {
|
|
@@ -1312,13 +1392,13 @@ var Provenance = class Provenance {
|
|
|
1312
1392
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.SALT), salt.toData());
|
|
1313
1393
|
} else if (data.type === "decrypted") switch (typeof generatorOptions === "object" ? generatorOptions.type : generatorOptions) {
|
|
1314
1394
|
case XIDGeneratorOptions.Include: {
|
|
1315
|
-
const generatorBytes = (
|
|
1395
|
+
const generatorBytes = encodeGeneratorJSON(data.generator.toJSON());
|
|
1316
1396
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.PROVENANCE_GENERATOR), generatorBytes);
|
|
1317
1397
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.SALT), salt.toData());
|
|
1318
1398
|
break;
|
|
1319
1399
|
}
|
|
1320
1400
|
case XIDGeneratorOptions.Elide: {
|
|
1321
|
-
const generatorBytes2 = (
|
|
1401
|
+
const generatorBytes2 = encodeGeneratorJSON(data.generator.toJSON());
|
|
1322
1402
|
const elidedAssertion = _bcts_envelope.Envelope.newAssertion(kv$1(_bcts_known_values.PROVENANCE_GENERATOR), generatorBytes2).elide();
|
|
1323
1403
|
envelope = envelope.addAssertionEnvelope(elidedAssertion);
|
|
1324
1404
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.SALT), salt.toData());
|
|
@@ -1326,8 +1406,10 @@ var Provenance = class Provenance {
|
|
|
1326
1406
|
}
|
|
1327
1407
|
case XIDGeneratorOptions.Encrypt:
|
|
1328
1408
|
if (typeof generatorOptions === "object") {
|
|
1329
|
-
const generatorBytes3 = (
|
|
1330
|
-
const
|
|
1409
|
+
const generatorBytes3 = encodeGeneratorJSON(data.generator.toJSON());
|
|
1410
|
+
const wrapped = _bcts_envelope.Envelope.new(generatorBytes3).wrap();
|
|
1411
|
+
const method = generatorOptions.method ?? (0, _bcts_components.defaultKeyDerivationMethod)();
|
|
1412
|
+
const encrypted = wrapped.lockSubject(method, generatorOptions.password);
|
|
1331
1413
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.PROVENANCE_GENERATOR), encrypted);
|
|
1332
1414
|
envelope = envelope.addAssertion(kv$1(_bcts_known_values.SALT), salt.toData());
|
|
1333
1415
|
}
|
|
@@ -1364,10 +1446,10 @@ var Provenance = class Provenance {
|
|
|
1364
1446
|
const assertionCase = generatorAssertions[0].case();
|
|
1365
1447
|
if (assertionCase.type === "assertion") {
|
|
1366
1448
|
const generatorObject = assertionCase.assertion.object();
|
|
1367
|
-
if (generatorObject.
|
|
1368
|
-
const generatorData = generatorObject.
|
|
1449
|
+
if (generatorObject.isLockedWithPassword()) if (password !== void 0) try {
|
|
1450
|
+
const generatorData = generatorObject.unlockSubject(password).subject().tryUnwrap().asByteString();
|
|
1369
1451
|
if (generatorData !== void 0) {
|
|
1370
|
-
const json = (
|
|
1452
|
+
const json = decodeGeneratorJSON(generatorData);
|
|
1371
1453
|
generator = {
|
|
1372
1454
|
data: {
|
|
1373
1455
|
type: "decrypted",
|
|
@@ -1395,7 +1477,7 @@ var Provenance = class Provenance {
|
|
|
1395
1477
|
else {
|
|
1396
1478
|
const generatorData = generatorObject.asByteString();
|
|
1397
1479
|
if (generatorData !== void 0) {
|
|
1398
|
-
const json2 = (
|
|
1480
|
+
const json2 = decodeGeneratorJSON(generatorData);
|
|
1399
1481
|
generator = {
|
|
1400
1482
|
data: {
|
|
1401
1483
|
type: "decrypted",
|
|
@@ -1442,6 +1524,8 @@ const DELEGATE_RAW = _bcts_known_values.DELEGATE.value();
|
|
|
1442
1524
|
const SERVICE_RAW = _bcts_known_values.SERVICE.value();
|
|
1443
1525
|
const PROVENANCE_RAW = _bcts_known_values.PROVENANCE.value();
|
|
1444
1526
|
const DEREFERENCE_VIA_RAW = _bcts_known_values.DEREFERENCE_VIA.value();
|
|
1527
|
+
const ATTACHMENT_RAW_VALUE = Number(_bcts_known_values.ATTACHMENT_RAW);
|
|
1528
|
+
const EDGE_RAW_VALUE = Number(_bcts_known_values.EDGE_RAW);
|
|
1445
1529
|
/**
|
|
1446
1530
|
* Options for verifying the signature on an envelope when loading.
|
|
1447
1531
|
*/
|
|
@@ -1462,13 +1546,17 @@ var XIDDocument = class XIDDocument {
|
|
|
1462
1546
|
_delegates;
|
|
1463
1547
|
_services;
|
|
1464
1548
|
_provenance;
|
|
1465
|
-
|
|
1549
|
+
_attachments;
|
|
1550
|
+
_edges;
|
|
1551
|
+
constructor(xid, resolutionMethods = /* @__PURE__ */ new Set(), keys = /* @__PURE__ */ new Map(), delegates = /* @__PURE__ */ new Map(), services = /* @__PURE__ */ new Map(), provenance, attachments, edges) {
|
|
1466
1552
|
this._xid = xid;
|
|
1467
1553
|
this._resolutionMethods = resolutionMethods;
|
|
1468
1554
|
this._keys = keys;
|
|
1469
1555
|
this._delegates = delegates;
|
|
1470
1556
|
this._services = services;
|
|
1471
1557
|
this._provenance = provenance;
|
|
1558
|
+
this._attachments = attachments ?? new _bcts_envelope.Attachments();
|
|
1559
|
+
this._edges = edges ?? new _bcts_envelope.Edges();
|
|
1472
1560
|
}
|
|
1473
1561
|
/**
|
|
1474
1562
|
* Create a new XIDDocument with the given options.
|
|
@@ -1476,7 +1564,7 @@ var XIDDocument = class XIDDocument {
|
|
|
1476
1564
|
static new(keyOptions = { type: "default" }, markOptions = { type: "none" }) {
|
|
1477
1565
|
const inceptionKey = XIDDocument.inceptionKeyForOptions(keyOptions);
|
|
1478
1566
|
const provenance = XIDDocument.genesisMarkWithOptions(markOptions);
|
|
1479
|
-
const doc = new XIDDocument(_bcts_components.XID.
|
|
1567
|
+
const doc = new XIDDocument(_bcts_components.XID.newFromSigningKey(inceptionKey.publicKeys().signingPublicKey()), /* @__PURE__ */ new Set(), /* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), provenance);
|
|
1480
1568
|
doc.addKey(inceptionKey);
|
|
1481
1569
|
return doc;
|
|
1482
1570
|
}
|
|
@@ -1585,16 +1673,17 @@ var XIDDocument = class XIDDocument {
|
|
|
1585
1673
|
if (!this._keys.delete(hashKey)) throw XIDError.notFound("key");
|
|
1586
1674
|
}
|
|
1587
1675
|
/**
|
|
1588
|
-
* Check if the given public
|
|
1676
|
+
* Check if the given signing public key is the inception signing key.
|
|
1677
|
+
* Matches Rust: `is_inception_signing_key(&self, signing_public_key: &SigningPublicKey) -> bool`
|
|
1589
1678
|
*/
|
|
1590
|
-
|
|
1591
|
-
return
|
|
1679
|
+
isInceptionSigningKey(signingPublicKey) {
|
|
1680
|
+
return this._xid.validate(signingPublicKey);
|
|
1592
1681
|
}
|
|
1593
1682
|
/**
|
|
1594
1683
|
* Get the inception key, if it exists in the document.
|
|
1595
1684
|
*/
|
|
1596
1685
|
inceptionKey() {
|
|
1597
|
-
for (const key of this._keys.values()) if (this.
|
|
1686
|
+
for (const key of this._keys.values()) if (this.isInceptionSigningKey(key.publicKeys().signingPublicKey())) return key;
|
|
1598
1687
|
}
|
|
1599
1688
|
/**
|
|
1600
1689
|
* Get the inception private keys, if available.
|
|
@@ -1623,6 +1712,136 @@ var XIDDocument = class XIDDocument {
|
|
|
1623
1712
|
return inceptionKey;
|
|
1624
1713
|
}
|
|
1625
1714
|
/**
|
|
1715
|
+
* Set the name (nickname) for a key identified by its public keys.
|
|
1716
|
+
*/
|
|
1717
|
+
setNameForKey(publicKeys, name) {
|
|
1718
|
+
const key = this.takeKey(publicKeys);
|
|
1719
|
+
if (key === void 0) throw XIDError.notFound("key");
|
|
1720
|
+
key.setNickname(name);
|
|
1721
|
+
this.addKey(key);
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Get the inception signing public key, if it exists.
|
|
1725
|
+
*/
|
|
1726
|
+
inceptionSigningKey() {
|
|
1727
|
+
return this.inceptionKey()?.publicKeys().signingPublicKey();
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Get the verification (signing) key for this document.
|
|
1731
|
+
* Prefers the inception key. Falls back to the first key.
|
|
1732
|
+
*/
|
|
1733
|
+
verificationKey() {
|
|
1734
|
+
const inceptionKey = this.inceptionKey();
|
|
1735
|
+
if (inceptionKey !== void 0) return inceptionKey.publicKeys().signingPublicKey();
|
|
1736
|
+
return this._keys.values().next().value?.publicKeys().signingPublicKey();
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Extract inception private keys from an envelope (convenience static method).
|
|
1740
|
+
*/
|
|
1741
|
+
static extractInceptionPrivateKeysFromEnvelope(envelope, password) {
|
|
1742
|
+
return XIDDocument.fromEnvelope(envelope, password, XIDVerifySignature.None).inceptionPrivateKeys();
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Get the private key envelope for a specific key, optionally decrypting it.
|
|
1746
|
+
*/
|
|
1747
|
+
privateKeyEnvelopeForKey(publicKeys, password) {
|
|
1748
|
+
const key = this.findKeyByPublicKeys(publicKeys);
|
|
1749
|
+
if (key === void 0) return;
|
|
1750
|
+
return key.privateKeyEnvelope(password);
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Check that the document contains a key with the given public keys.
|
|
1754
|
+
* Throws if not found.
|
|
1755
|
+
*/
|
|
1756
|
+
checkContainsKey(publicKeys) {
|
|
1757
|
+
if (this.findKeyByPublicKeys(publicKeys) === void 0) throw XIDError.keyNotFoundInDocument(publicKeys.toString());
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Check that the document contains a delegate with the given XID.
|
|
1761
|
+
* Throws if not found.
|
|
1762
|
+
*/
|
|
1763
|
+
checkContainsDelegate(xid) {
|
|
1764
|
+
if (this.findDelegateByXid(xid) === void 0) throw XIDError.delegateNotFoundInDocument(xid.toString());
|
|
1765
|
+
}
|
|
1766
|
+
/**
|
|
1767
|
+
* Get the attachments container.
|
|
1768
|
+
*/
|
|
1769
|
+
getAttachments() {
|
|
1770
|
+
return this._attachments;
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Add an attachment with the specified payload and metadata.
|
|
1774
|
+
*/
|
|
1775
|
+
addAttachment(payload, vendor, conformsTo) {
|
|
1776
|
+
this._attachments.add(payload, vendor, conformsTo);
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Check if the document has any attachments.
|
|
1780
|
+
*/
|
|
1781
|
+
hasAttachments() {
|
|
1782
|
+
return !this._attachments.isEmpty();
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Remove all attachments.
|
|
1786
|
+
*/
|
|
1787
|
+
clearAttachments() {
|
|
1788
|
+
this._attachments.clear();
|
|
1789
|
+
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Get an attachment by its digest.
|
|
1792
|
+
*/
|
|
1793
|
+
getAttachment(digest) {
|
|
1794
|
+
return this._attachments.get(digest);
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Remove an attachment by its digest.
|
|
1798
|
+
*/
|
|
1799
|
+
removeAttachment(digest) {
|
|
1800
|
+
return this._attachments.remove(digest);
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Get the edges container (read-only).
|
|
1804
|
+
*/
|
|
1805
|
+
edges() {
|
|
1806
|
+
return this._edges;
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Get the edges container (mutable).
|
|
1810
|
+
*/
|
|
1811
|
+
edgesMut() {
|
|
1812
|
+
return this._edges;
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Add an edge envelope.
|
|
1816
|
+
*/
|
|
1817
|
+
addEdge(edgeEnvelope) {
|
|
1818
|
+
this._edges.add(edgeEnvelope);
|
|
1819
|
+
}
|
|
1820
|
+
/**
|
|
1821
|
+
* Get an edge by its digest.
|
|
1822
|
+
*/
|
|
1823
|
+
getEdge(digest) {
|
|
1824
|
+
return this._edges.get(digest);
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* Remove an edge by its digest.
|
|
1828
|
+
*/
|
|
1829
|
+
removeEdge(digest) {
|
|
1830
|
+
return this._edges.remove(digest);
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Remove all edges.
|
|
1834
|
+
*/
|
|
1835
|
+
clearEdges() {
|
|
1836
|
+
this._edges.clear();
|
|
1837
|
+
}
|
|
1838
|
+
/**
|
|
1839
|
+
* Check if the document has any edges.
|
|
1840
|
+
*/
|
|
1841
|
+
hasEdges() {
|
|
1842
|
+
return !this._edges.isEmpty();
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1626
1845
|
* Check if the document is empty (no keys, delegates, services, or provenance).
|
|
1627
1846
|
*/
|
|
1628
1847
|
isEmpty() {
|
|
@@ -1799,12 +2018,14 @@ var XIDDocument = class XIDDocument {
|
|
|
1799
2018
|
* Convert to envelope with options.
|
|
1800
2019
|
*/
|
|
1801
2020
|
toEnvelope(privateKeyOptions = XIDPrivateKeyOptions.Omit, generatorOptions = XIDGeneratorOptions.Omit, signingOptions = { type: "none" }) {
|
|
1802
|
-
let envelope = _bcts_envelope.Envelope.
|
|
2021
|
+
let envelope = _bcts_envelope.Envelope.newLeaf(this._xid.taggedCbor());
|
|
1803
2022
|
for (const method of this._resolutionMethods) envelope = envelope.addAssertion(kv(_bcts_known_values.DEREFERENCE_VIA), method);
|
|
1804
2023
|
for (const key of this._keys.values()) envelope = envelope.addAssertion(kv(_bcts_known_values.KEY), key.intoEnvelopeOpt(privateKeyOptions));
|
|
1805
2024
|
for (const delegate of this._delegates.values()) envelope = envelope.addAssertion(kv(_bcts_known_values.DELEGATE), delegate.intoEnvelope());
|
|
1806
2025
|
for (const service of this._services.values()) envelope = envelope.addAssertion(kv(_bcts_known_values.SERVICE), service.intoEnvelope());
|
|
1807
2026
|
if (this._provenance !== void 0) envelope = envelope.addAssertion(kv(_bcts_known_values.PROVENANCE), this._provenance.intoEnvelopeOpt(generatorOptions));
|
|
2027
|
+
envelope = this._attachments.addToEnvelope(envelope);
|
|
2028
|
+
envelope = this._edges.addToEnvelope(envelope);
|
|
1808
2029
|
switch (signingOptions.type) {
|
|
1809
2030
|
case "inception": {
|
|
1810
2031
|
const inceptionKey = this.inceptionKey();
|
|
@@ -1814,19 +2035,18 @@ var XIDDocument = class XIDDocument {
|
|
|
1814
2035
|
envelope = envelope.sign(privateKeys);
|
|
1815
2036
|
break;
|
|
1816
2037
|
}
|
|
1817
|
-
case "privateKeyBase": {
|
|
1818
|
-
const privateKeys = signingOptions.privateKeyBase.ed25519PrivateKeys();
|
|
1819
|
-
envelope = envelope.sign(privateKeys);
|
|
1820
|
-
break;
|
|
1821
|
-
}
|
|
1822
2038
|
case "privateKeys":
|
|
1823
2039
|
envelope = envelope.sign(signingOptions.privateKeys);
|
|
1824
2040
|
break;
|
|
2041
|
+
case "signingPrivateKey":
|
|
2042
|
+
envelope = envelope.sign(signingOptions.signingPrivateKey);
|
|
2043
|
+
break;
|
|
1825
2044
|
default: break;
|
|
1826
2045
|
}
|
|
1827
2046
|
return envelope;
|
|
1828
2047
|
}
|
|
1829
2048
|
intoEnvelope() {
|
|
2049
|
+
if (this.isEmpty()) return _bcts_envelope.Envelope.new(this._xid.toData());
|
|
1830
2050
|
return this.toEnvelope();
|
|
1831
2051
|
}
|
|
1832
2052
|
/**
|
|
@@ -1838,25 +2058,42 @@ var XIDDocument = class XIDDocument {
|
|
|
1838
2058
|
case XIDVerifySignature.None: {
|
|
1839
2059
|
const subject = envelopeExt.subject();
|
|
1840
2060
|
const envelopeToParse = subject.isWrapped() ? subject.tryUnwrap() : envelope;
|
|
1841
|
-
|
|
2061
|
+
const attachments = _bcts_envelope.Attachments.fromEnvelope(envelopeToParse);
|
|
2062
|
+
const edges = _bcts_envelope.Edges.fromEnvelope(envelopeToParse);
|
|
2063
|
+
const doc = XIDDocument.fromEnvelopeInner(envelopeToParse, password);
|
|
2064
|
+
doc._attachments = attachments;
|
|
2065
|
+
doc._edges = edges;
|
|
2066
|
+
return doc;
|
|
1842
2067
|
}
|
|
1843
2068
|
case XIDVerifySignature.Inception: {
|
|
1844
2069
|
if (!envelopeExt.subject().isWrapped()) throw XIDError.envelopeNotSigned();
|
|
1845
2070
|
const unwrapped = envelopeExt.tryUnwrap();
|
|
2071
|
+
const attachments = _bcts_envelope.Attachments.fromEnvelope(unwrapped);
|
|
2072
|
+
const edges = _bcts_envelope.Edges.fromEnvelope(unwrapped);
|
|
1846
2073
|
const doc = XIDDocument.fromEnvelopeInner(unwrapped, password);
|
|
1847
2074
|
const inceptionKey = doc.inceptionKey();
|
|
1848
2075
|
if (inceptionKey === void 0) throw XIDError.missingInceptionKey();
|
|
1849
2076
|
if (!envelopeExt.hasSignatureFrom(inceptionKey.publicKeys())) throw XIDError.signatureVerificationFailed();
|
|
1850
|
-
if (!doc.
|
|
2077
|
+
if (!doc.isInceptionSigningKey(inceptionKey.publicKeys().signingPublicKey())) throw XIDError.invalidXid();
|
|
2078
|
+
doc._attachments = attachments;
|
|
2079
|
+
doc._edges = edges;
|
|
1851
2080
|
return doc;
|
|
1852
2081
|
}
|
|
1853
2082
|
}
|
|
1854
2083
|
}
|
|
1855
2084
|
static fromEnvelopeInner(envelope, password) {
|
|
1856
2085
|
const envelopeExt = envelope;
|
|
1857
|
-
const
|
|
1858
|
-
|
|
1859
|
-
|
|
2086
|
+
const subject = envelope.case().type === "node" ? envelopeExt.subject() : envelope;
|
|
2087
|
+
const leaf = subject.asLeaf?.();
|
|
2088
|
+
if (leaf === void 0) throw XIDError.invalidXid();
|
|
2089
|
+
let xid;
|
|
2090
|
+
try {
|
|
2091
|
+
xid = _bcts_components.XID.fromTaggedCbor(leaf);
|
|
2092
|
+
} catch {
|
|
2093
|
+
const xidData = subject.asByteString();
|
|
2094
|
+
if (xidData === void 0) throw XIDError.invalidXid();
|
|
2095
|
+
xid = _bcts_components.XID.from(xidData);
|
|
2096
|
+
}
|
|
1860
2097
|
const doc = XIDDocument.fromXid(xid);
|
|
1861
2098
|
for (const assertion of envelopeExt.assertions()) {
|
|
1862
2099
|
const assertionCase = assertion.case();
|
|
@@ -1891,6 +2128,8 @@ var XIDDocument = class XIDDocument {
|
|
|
1891
2128
|
if (doc._provenance !== void 0) throw XIDError.multipleProvenanceMarks();
|
|
1892
2129
|
doc._provenance = Provenance.tryFromEnvelope(object, password);
|
|
1893
2130
|
break;
|
|
2131
|
+
case ATTACHMENT_RAW_VALUE: break;
|
|
2132
|
+
case EDGE_RAW_VALUE: break;
|
|
1894
2133
|
default: throw XIDError.unexpectedPredicate(String(predicate));
|
|
1895
2134
|
}
|
|
1896
2135
|
}
|
|
@@ -1901,7 +2140,13 @@ var XIDDocument = class XIDDocument {
|
|
|
1901
2140
|
* Create a signed envelope.
|
|
1902
2141
|
*/
|
|
1903
2142
|
toSignedEnvelope(signingKey) {
|
|
1904
|
-
return this.
|
|
2143
|
+
return this.toSignedEnvelopeOpt(signingKey, XIDPrivateKeyOptions.Omit);
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Create a signed envelope with private key options.
|
|
2147
|
+
*/
|
|
2148
|
+
toSignedEnvelopeOpt(signingKey, privateKeyOptions = XIDPrivateKeyOptions.Omit) {
|
|
2149
|
+
return this.toEnvelope(privateKeyOptions, XIDGeneratorOptions.Omit, { type: "none" }).sign(signingKey);
|
|
1905
2150
|
}
|
|
1906
2151
|
/**
|
|
1907
2152
|
* Get the reference for this document.
|
|
@@ -1913,13 +2158,41 @@ var XIDDocument = class XIDDocument {
|
|
|
1913
2158
|
* Check equality with another XIDDocument.
|
|
1914
2159
|
*/
|
|
1915
2160
|
equals(other) {
|
|
1916
|
-
|
|
2161
|
+
if (!this._xid.equals(other._xid)) return false;
|
|
2162
|
+
if (this._resolutionMethods.size !== other._resolutionMethods.size) return false;
|
|
2163
|
+
for (const m of this._resolutionMethods) if (!other._resolutionMethods.has(m)) return false;
|
|
2164
|
+
if (this._keys.size !== other._keys.size) return false;
|
|
2165
|
+
for (const [hash, key] of this._keys) {
|
|
2166
|
+
const otherKey = other._keys.get(hash);
|
|
2167
|
+
if (otherKey === void 0 || !key.equals(otherKey)) return false;
|
|
2168
|
+
}
|
|
2169
|
+
if (this._delegates.size !== other._delegates.size) return false;
|
|
2170
|
+
for (const [hash, delegate] of this._delegates) {
|
|
2171
|
+
const otherDelegate = other._delegates.get(hash);
|
|
2172
|
+
if (otherDelegate === void 0 || !delegate.equals(otherDelegate)) return false;
|
|
2173
|
+
}
|
|
2174
|
+
if (this._services.size !== other._services.size) return false;
|
|
2175
|
+
for (const [uri, service] of this._services) {
|
|
2176
|
+
const otherService = other._services.get(uri);
|
|
2177
|
+
if (otherService === void 0 || !service.equals(otherService)) return false;
|
|
2178
|
+
}
|
|
2179
|
+
if (this._provenance === void 0 && other._provenance !== void 0) return false;
|
|
2180
|
+
if (this._provenance !== void 0 && other._provenance === void 0) return false;
|
|
2181
|
+
if (this._provenance !== void 0 && other._provenance !== void 0) {
|
|
2182
|
+
if (!this._provenance.equals(other._provenance)) return false;
|
|
2183
|
+
}
|
|
2184
|
+
if (!this._attachments.equals(other._attachments)) return false;
|
|
2185
|
+
if (!this._edges.equals(other._edges)) return false;
|
|
2186
|
+
return true;
|
|
1917
2187
|
}
|
|
1918
2188
|
/**
|
|
1919
2189
|
* Clone this XIDDocument.
|
|
1920
2190
|
*/
|
|
1921
2191
|
clone() {
|
|
1922
|
-
|
|
2192
|
+
const doc = new XIDDocument(this._xid, new Set(this._resolutionMethods), new Map(Array.from(this._keys.entries()).map(([k, v]) => [k, v.clone()])), new Map(Array.from(this._delegates.entries()).map(([k, v]) => [k, v.clone()])), new Map(Array.from(this._services.entries()).map(([k, v]) => [k, v.clone()])), this._provenance?.clone());
|
|
2193
|
+
for (const [, env] of this._attachments.iter()) doc._attachments.addEnvelope(env);
|
|
2194
|
+
for (const [, env] of this._edges.iter()) doc._edges.add(env);
|
|
2195
|
+
return doc;
|
|
1923
2196
|
}
|
|
1924
2197
|
/**
|
|
1925
2198
|
* Try to extract from envelope (alias for fromEnvelope with default options).
|
|
@@ -1940,7 +2213,19 @@ function bytesEqual(a, b) {
|
|
|
1940
2213
|
const VERSION = "1.0.0-alpha.3";
|
|
1941
2214
|
|
|
1942
2215
|
//#endregion
|
|
2216
|
+
Object.defineProperty(exports, 'Attachments', {
|
|
2217
|
+
enumerable: true,
|
|
2218
|
+
get: function () {
|
|
2219
|
+
return _bcts_envelope.Attachments;
|
|
2220
|
+
}
|
|
2221
|
+
});
|
|
1943
2222
|
exports.Delegate = Delegate;
|
|
2223
|
+
Object.defineProperty(exports, 'Edges', {
|
|
2224
|
+
enumerable: true,
|
|
2225
|
+
get: function () {
|
|
2226
|
+
return _bcts_envelope.Edges;
|
|
2227
|
+
}
|
|
2228
|
+
});
|
|
1944
2229
|
exports.HasNicknameMixin = HasNicknameMixin;
|
|
1945
2230
|
exports.HasPermissionsMixin = HasPermissionsMixin;
|
|
1946
2231
|
exports.Key = Key;
|