@did-btcr2/method 0.47.0 → 0.49.0
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/.tsbuildinfo +1 -1
- package/dist/browser.js +33 -69
- package/dist/browser.mjs +33 -69
- package/dist/cjs/index.js +33 -70
- package/dist/esm/core/identifier.js +68 -130
- package/dist/esm/core/identifier.js.map +1 -1
- package/dist/esm/utils/did-document.js +0 -5
- package/dist/esm/utils/did-document.js.map +1 -1
- package/dist/types/core/identifier.d.ts.map +1 -1
- package/dist/types/utils/did-document.d.ts +0 -3
- package/dist/types/utils/did-document.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/core/identifier.ts +77 -149
- package/src/utils/did-document.ts +0 -7
package/dist/browser.mjs
CHANGED
|
@@ -38915,18 +38915,19 @@ var Identifier = class _Identifier {
|
|
|
38915
38915
|
* @returns {string} The new did:btcr2 identifier.
|
|
38916
38916
|
*/
|
|
38917
38917
|
static encode(genesisBytes, options) {
|
|
38918
|
-
const { idType, version = 1, network } = options;
|
|
38918
|
+
const { idType, version = 1, network = "bitcoin" } = options;
|
|
38919
38919
|
if (!(idType in IdentifierTypes)) {
|
|
38920
38920
|
throw new IdentifierError('Expected "idType" to be "KEY" or "EXTERNAL"', INVALID_DID, { idType });
|
|
38921
38921
|
}
|
|
38922
|
-
if (
|
|
38922
|
+
if (version !== 1) {
|
|
38923
38923
|
throw new IdentifierError('Expected "version" to be 1', INVALID_DID, { version });
|
|
38924
38924
|
}
|
|
38925
|
-
if (typeof network
|
|
38926
|
-
throw new IdentifierError('
|
|
38925
|
+
if (typeof network !== "string") {
|
|
38926
|
+
throw new IdentifierError('Expected "network" to be a known network name', INVALID_DID, { network });
|
|
38927
38927
|
}
|
|
38928
|
-
|
|
38929
|
-
|
|
38928
|
+
const networkValue = BitcoinNetworkNames[network];
|
|
38929
|
+
if (networkValue === void 0) {
|
|
38930
|
+
throw new IdentifierError('Invalid "network" name', INVALID_DID, { network });
|
|
38930
38931
|
}
|
|
38931
38932
|
if (idType === "KEY") {
|
|
38932
38933
|
try {
|
|
@@ -38938,28 +38939,16 @@ var Identifier = class _Identifier {
|
|
|
38938
38939
|
{ genesisBytes }
|
|
38939
38940
|
);
|
|
38940
38941
|
}
|
|
38942
|
+
} else if (genesisBytes.length !== 32) {
|
|
38943
|
+
throw new IdentifierError(
|
|
38944
|
+
'Expected "genesisBytes" to be a 32-byte hash for EXTERNAL identifiers',
|
|
38945
|
+
INVALID_DID,
|
|
38946
|
+
{ genesisBytes }
|
|
38947
|
+
);
|
|
38941
38948
|
}
|
|
38942
38949
|
const hrp = idType === "KEY" ? "k" : "x";
|
|
38943
|
-
const
|
|
38944
|
-
const
|
|
38945
|
-
for (let i = 0; i < fCount; i++) {
|
|
38946
|
-
nibbles.push(15);
|
|
38947
|
-
}
|
|
38948
|
-
nibbles.push((version - 1) % 15);
|
|
38949
|
-
if (typeof network === "string") {
|
|
38950
|
-
nibbles.push(BitcoinNetworkNames[network]);
|
|
38951
|
-
} else if (typeof network === "number") {
|
|
38952
|
-
nibbles.push(network + 11);
|
|
38953
|
-
}
|
|
38954
|
-
if (nibbles.length % 2 !== 0) {
|
|
38955
|
-
nibbles.push(0);
|
|
38956
|
-
}
|
|
38957
|
-
if (fCount !== 0) {
|
|
38958
|
-
for (const index in Array.from({ length: nibbles.length / 2 - 1 })) {
|
|
38959
|
-
throw new IdentifierError("Not implemented", "NOT_IMPLEMENTED", { index });
|
|
38960
|
-
}
|
|
38961
|
-
}
|
|
38962
|
-
const dataBytes = new Uint8Array([nibbles[2 * 0] << 4 | nibbles[2 * 0 + 1], ...genesisBytes]);
|
|
38950
|
+
const firstByte = version - 1 << 4 | networkValue;
|
|
38951
|
+
const dataBytes = new Uint8Array([firstByte, ...genesisBytes]);
|
|
38963
38952
|
return `did:btcr2:${bech32m.encodeFromBytes(hrp, dataBytes)}`;
|
|
38964
38953
|
}
|
|
38965
38954
|
/**
|
|
@@ -38989,53 +38978,34 @@ var Identifier = class _Identifier {
|
|
|
38989
38978
|
if (!["x", "k"].includes(hrp)) {
|
|
38990
38979
|
throw new IdentifierError(`Invalid hrp: ${hrp}`, INVALID_DID, { identifier });
|
|
38991
38980
|
}
|
|
38992
|
-
if (!dataBytes) {
|
|
38981
|
+
if (!dataBytes || dataBytes.length < 1) {
|
|
38993
38982
|
throw new IdentifierError(`Failed to decode id: ${encoded}`, INVALID_DID, { identifier });
|
|
38994
38983
|
}
|
|
38995
38984
|
const idType = hrp === "k" ? "KEY" : "EXTERNAL";
|
|
38996
|
-
|
|
38997
|
-
|
|
38998
|
-
|
|
38999
|
-
|
|
39000
|
-
|
|
39001
|
-
|
|
39002
|
-
|
|
39003
|
-
|
|
39004
|
-
|
|
39005
|
-
|
|
39006
|
-
|
|
39007
|
-
|
|
39008
|
-
|
|
39009
|
-
|
|
39010
|
-
if (version > 1) {
|
|
39011
|
-
throw new IdentifierError(`Invalid version: ${version}`, INVALID_DID, { identifier });
|
|
39012
|
-
}
|
|
39013
|
-
}
|
|
39014
|
-
version += versionNibble;
|
|
39015
|
-
nibblesConsumed += 1;
|
|
39016
|
-
let networkValue = nibblesConsumed % 2 === 0 ? dataBytes[++byteIndex] >>> 4 : currentByte & 15;
|
|
39017
|
-
nibblesConsumed += 1;
|
|
39018
|
-
let network = BitcoinNetworkNames[networkValue];
|
|
39019
|
-
if (!network) {
|
|
39020
|
-
if (networkValue >= 8 && networkValue <= 15) {
|
|
39021
|
-
network = networkValue - 11;
|
|
39022
|
-
} else {
|
|
39023
|
-
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
39024
|
-
}
|
|
39025
|
-
}
|
|
39026
|
-
if (nibblesConsumed % 2 === 1) {
|
|
39027
|
-
const fillerNibble = currentByte & 15;
|
|
39028
|
-
if (fillerNibble !== 0) {
|
|
39029
|
-
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
39030
|
-
}
|
|
38985
|
+
const btcr2Version = dataBytes[0] >>> 4;
|
|
38986
|
+
if (btcr2Version !== 0) {
|
|
38987
|
+
throw new IdentifierError(`Invalid btcr2_version (expected 0): ${btcr2Version}`, INVALID_DID, { identifier });
|
|
38988
|
+
}
|
|
38989
|
+
const version = 1;
|
|
38990
|
+
const networkValue = dataBytes[0] & 15;
|
|
38991
|
+
const networkName = BitcoinNetworkNames[networkValue];
|
|
38992
|
+
let network;
|
|
38993
|
+
if (typeof networkName === "string") {
|
|
38994
|
+
network = networkName;
|
|
38995
|
+
} else if (networkValue >= 12 && networkValue <= 14) {
|
|
38996
|
+
network = networkValue - 11;
|
|
38997
|
+
} else {
|
|
38998
|
+
throw new IdentifierError(`Invalid network: ${networkValue}`, INVALID_DID, { identifier });
|
|
39031
38999
|
}
|
|
39032
|
-
const genesisBytes = dataBytes.slice(
|
|
39000
|
+
const genesisBytes = dataBytes.slice(1);
|
|
39033
39001
|
if (idType === "KEY") {
|
|
39034
39002
|
try {
|
|
39035
39003
|
new CompressedSecp256k1PublicKey(genesisBytes);
|
|
39036
39004
|
} catch {
|
|
39037
39005
|
throw new IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, INVALID_DID, { identifier });
|
|
39038
39006
|
}
|
|
39007
|
+
} else if (genesisBytes.length !== 32) {
|
|
39008
|
+
throw new IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, INVALID_DID, { identifier });
|
|
39039
39009
|
}
|
|
39040
39010
|
return { idType, hrp, version, network, genesisBytes };
|
|
39041
39011
|
}
|
|
@@ -40436,11 +40406,6 @@ var DidDocument = class _DidDocument {
|
|
|
40436
40406
|
return new GenesisDocument(this);
|
|
40437
40407
|
}
|
|
40438
40408
|
};
|
|
40439
|
-
var Document = class {
|
|
40440
|
-
static isValid(didDocument) {
|
|
40441
|
-
return new DidDocument(didDocument).validateGenesis();
|
|
40442
|
-
}
|
|
40443
|
-
};
|
|
40444
40409
|
var GenesisDocument = class _GenesisDocument extends DidDocument {
|
|
40445
40410
|
constructor(document) {
|
|
40446
40411
|
super(document);
|
|
@@ -41538,7 +41503,6 @@ export {
|
|
|
41538
41503
|
DidDocument,
|
|
41539
41504
|
DidDocumentBuilder,
|
|
41540
41505
|
DidVerificationMethod,
|
|
41541
|
-
Document,
|
|
41542
41506
|
GenesisDocument,
|
|
41543
41507
|
ID_PLACEHOLDER_VALUE,
|
|
41544
41508
|
Identifier,
|
package/dist/cjs/index.js
CHANGED
|
@@ -38,7 +38,6 @@ __export(index_exports, {
|
|
|
38
38
|
DidDocument: () => DidDocument,
|
|
39
39
|
DidDocumentBuilder: () => DidDocumentBuilder,
|
|
40
40
|
DidVerificationMethod: () => DidVerificationMethod,
|
|
41
|
-
Document: () => Document,
|
|
42
41
|
GenesisDocument: () => GenesisDocument,
|
|
43
42
|
ID_PLACEHOLDER_VALUE: () => ID_PLACEHOLDER_VALUE,
|
|
44
43
|
Identifier: () => Identifier,
|
|
@@ -845,18 +844,19 @@ var Identifier = class _Identifier {
|
|
|
845
844
|
* @returns {string} The new did:btcr2 identifier.
|
|
846
845
|
*/
|
|
847
846
|
static encode(genesisBytes, options) {
|
|
848
|
-
const { idType, version = 1, network } = options;
|
|
847
|
+
const { idType, version = 1, network = "bitcoin" } = options;
|
|
849
848
|
if (!(idType in import_common6.IdentifierTypes)) {
|
|
850
849
|
throw new import_common6.IdentifierError('Expected "idType" to be "KEY" or "EXTERNAL"', import_common6.INVALID_DID, { idType });
|
|
851
850
|
}
|
|
852
|
-
if (
|
|
851
|
+
if (version !== 1) {
|
|
853
852
|
throw new import_common6.IdentifierError('Expected "version" to be 1', import_common6.INVALID_DID, { version });
|
|
854
853
|
}
|
|
855
|
-
if (typeof network
|
|
856
|
-
throw new import_common6.IdentifierError('
|
|
854
|
+
if (typeof network !== "string") {
|
|
855
|
+
throw new import_common6.IdentifierError('Expected "network" to be a known network name', import_common6.INVALID_DID, { network });
|
|
857
856
|
}
|
|
858
|
-
|
|
859
|
-
|
|
857
|
+
const networkValue = import_common6.BitcoinNetworkNames[network];
|
|
858
|
+
if (networkValue === void 0) {
|
|
859
|
+
throw new import_common6.IdentifierError('Invalid "network" name', import_common6.INVALID_DID, { network });
|
|
860
860
|
}
|
|
861
861
|
if (idType === "KEY") {
|
|
862
862
|
try {
|
|
@@ -868,28 +868,16 @@ var Identifier = class _Identifier {
|
|
|
868
868
|
{ genesisBytes }
|
|
869
869
|
);
|
|
870
870
|
}
|
|
871
|
+
} else if (genesisBytes.length !== 32) {
|
|
872
|
+
throw new import_common6.IdentifierError(
|
|
873
|
+
'Expected "genesisBytes" to be a 32-byte hash for EXTERNAL identifiers',
|
|
874
|
+
import_common6.INVALID_DID,
|
|
875
|
+
{ genesisBytes }
|
|
876
|
+
);
|
|
871
877
|
}
|
|
872
878
|
const hrp = idType === "KEY" ? "k" : "x";
|
|
873
|
-
const
|
|
874
|
-
const
|
|
875
|
-
for (let i = 0; i < fCount; i++) {
|
|
876
|
-
nibbles.push(15);
|
|
877
|
-
}
|
|
878
|
-
nibbles.push((version - 1) % 15);
|
|
879
|
-
if (typeof network === "string") {
|
|
880
|
-
nibbles.push(import_common6.BitcoinNetworkNames[network]);
|
|
881
|
-
} else if (typeof network === "number") {
|
|
882
|
-
nibbles.push(network + 11);
|
|
883
|
-
}
|
|
884
|
-
if (nibbles.length % 2 !== 0) {
|
|
885
|
-
nibbles.push(0);
|
|
886
|
-
}
|
|
887
|
-
if (fCount !== 0) {
|
|
888
|
-
for (const index in Array.from({ length: nibbles.length / 2 - 1 })) {
|
|
889
|
-
throw new import_common6.IdentifierError("Not implemented", "NOT_IMPLEMENTED", { index });
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
const dataBytes = new Uint8Array([nibbles[2 * 0] << 4 | nibbles[2 * 0 + 1], ...genesisBytes]);
|
|
879
|
+
const firstByte = version - 1 << 4 | networkValue;
|
|
880
|
+
const dataBytes = new Uint8Array([firstByte, ...genesisBytes]);
|
|
893
881
|
return `did:btcr2:${import_base.bech32m.encodeFromBytes(hrp, dataBytes)}`;
|
|
894
882
|
}
|
|
895
883
|
/**
|
|
@@ -919,53 +907,34 @@ var Identifier = class _Identifier {
|
|
|
919
907
|
if (!["x", "k"].includes(hrp)) {
|
|
920
908
|
throw new import_common6.IdentifierError(`Invalid hrp: ${hrp}`, import_common6.INVALID_DID, { identifier });
|
|
921
909
|
}
|
|
922
|
-
if (!dataBytes) {
|
|
910
|
+
if (!dataBytes || dataBytes.length < 1) {
|
|
923
911
|
throw new import_common6.IdentifierError(`Failed to decode id: ${encoded}`, import_common6.INVALID_DID, { identifier });
|
|
924
912
|
}
|
|
925
913
|
const idType = hrp === "k" ? "KEY" : "EXTERNAL";
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
if (version > 1) {
|
|
941
|
-
throw new import_common6.IdentifierError(`Invalid version: ${version}`, import_common6.INVALID_DID, { identifier });
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
version += versionNibble;
|
|
945
|
-
nibblesConsumed += 1;
|
|
946
|
-
let networkValue = nibblesConsumed % 2 === 0 ? dataBytes[++byteIndex] >>> 4 : currentByte & 15;
|
|
947
|
-
nibblesConsumed += 1;
|
|
948
|
-
let network = import_common6.BitcoinNetworkNames[networkValue];
|
|
949
|
-
if (!network) {
|
|
950
|
-
if (networkValue >= 8 && networkValue <= 15) {
|
|
951
|
-
network = networkValue - 11;
|
|
952
|
-
} else {
|
|
953
|
-
throw new import_common6.IdentifierError(`Invalid did: ${identifier}`, import_common6.INVALID_DID, { identifier });
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
if (nibblesConsumed % 2 === 1) {
|
|
957
|
-
const fillerNibble = currentByte & 15;
|
|
958
|
-
if (fillerNibble !== 0) {
|
|
959
|
-
throw new import_common6.IdentifierError(`Invalid did: ${identifier}`, import_common6.INVALID_DID, { identifier });
|
|
960
|
-
}
|
|
914
|
+
const btcr2Version = dataBytes[0] >>> 4;
|
|
915
|
+
if (btcr2Version !== 0) {
|
|
916
|
+
throw new import_common6.IdentifierError(`Invalid btcr2_version (expected 0): ${btcr2Version}`, import_common6.INVALID_DID, { identifier });
|
|
917
|
+
}
|
|
918
|
+
const version = 1;
|
|
919
|
+
const networkValue = dataBytes[0] & 15;
|
|
920
|
+
const networkName = import_common6.BitcoinNetworkNames[networkValue];
|
|
921
|
+
let network;
|
|
922
|
+
if (typeof networkName === "string") {
|
|
923
|
+
network = networkName;
|
|
924
|
+
} else if (networkValue >= 12 && networkValue <= 14) {
|
|
925
|
+
network = networkValue - 11;
|
|
926
|
+
} else {
|
|
927
|
+
throw new import_common6.IdentifierError(`Invalid network: ${networkValue}`, import_common6.INVALID_DID, { identifier });
|
|
961
928
|
}
|
|
962
|
-
const genesisBytes = dataBytes.slice(
|
|
929
|
+
const genesisBytes = dataBytes.slice(1);
|
|
963
930
|
if (idType === "KEY") {
|
|
964
931
|
try {
|
|
965
932
|
new import_keypair.CompressedSecp256k1PublicKey(genesisBytes);
|
|
966
933
|
} catch {
|
|
967
934
|
throw new import_common6.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common6.INVALID_DID, { identifier });
|
|
968
935
|
}
|
|
936
|
+
} else if (genesisBytes.length !== 32) {
|
|
937
|
+
throw new import_common6.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common6.INVALID_DID, { identifier });
|
|
969
938
|
}
|
|
970
939
|
return { idType, hrp, version, network, genesisBytes };
|
|
971
940
|
}
|
|
@@ -1628,11 +1597,6 @@ var DidDocument = class _DidDocument {
|
|
|
1628
1597
|
return new GenesisDocument(this);
|
|
1629
1598
|
}
|
|
1630
1599
|
};
|
|
1631
|
-
var Document = class {
|
|
1632
|
-
static isValid(didDocument) {
|
|
1633
|
-
return new DidDocument(didDocument).validateGenesis();
|
|
1634
|
-
}
|
|
1635
|
-
};
|
|
1636
1600
|
var GenesisDocument = class _GenesisDocument extends DidDocument {
|
|
1637
1601
|
constructor(document) {
|
|
1638
1602
|
super(document);
|
|
@@ -2729,7 +2693,6 @@ var DidDocumentBuilder = class {
|
|
|
2729
2693
|
DidDocument,
|
|
2730
2694
|
DidDocumentBuilder,
|
|
2731
2695
|
DidVerificationMethod,
|
|
2732
|
-
Document,
|
|
2733
2696
|
GenesisDocument,
|
|
2734
2697
|
ID_PLACEHOLDER_VALUE,
|
|
2735
2698
|
Identifier,
|
|
@@ -29,25 +29,30 @@ export class Identifier {
|
|
|
29
29
|
* @returns {string} The new did:btcr2 identifier.
|
|
30
30
|
*/
|
|
31
31
|
static encode(genesisBytes, options) {
|
|
32
|
-
// Deconstruct the options
|
|
33
|
-
const { idType, version = 1, network } = options;
|
|
34
|
-
//
|
|
32
|
+
// Deconstruct the options, defaulting version to 1 and network to "bitcoin" (matching DidBtcr2.create).
|
|
33
|
+
const { idType, version = 1, network = 'bitcoin' } = options;
|
|
34
|
+
// idType MUST be "KEY" or "EXTERNAL".
|
|
35
35
|
if (!(idType in IdentifierTypes)) {
|
|
36
36
|
throw new IdentifierError('Expected "idType" to be "KEY" or "EXTERNAL"', INVALID_DID, { idType });
|
|
37
37
|
}
|
|
38
|
-
//
|
|
39
|
-
|
|
38
|
+
// The only valid version_number is 1 (which encodes a btcr2_version of 0). Any other value would
|
|
39
|
+
// overflow or corrupt the version nibble, so reject everything except exactly 1. This also rejects
|
|
40
|
+
// NaN and non-number inputs, which are never strictly equal to 1.
|
|
41
|
+
if (version !== 1) {
|
|
40
42
|
throw new IdentifierError('Expected "version" to be 1', INVALID_DID, { version });
|
|
41
43
|
}
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
// network MUST be a known network name. This encoder does not mint custom/numeric networks: the
|
|
45
|
+
// public surface (DidCreateOptions.network) is a string, and a numeric nibble >= 5 would overflow
|
|
46
|
+
// the 4-bit network field and corrupt the version nibble. Custom networks remain decode-only.
|
|
47
|
+
if (typeof network !== 'string') {
|
|
48
|
+
throw new IdentifierError('Expected "network" to be a known network name', INVALID_DID, { network });
|
|
45
49
|
}
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
throw new IdentifierError('Invalid "network"
|
|
50
|
+
const networkValue = BitcoinNetworkNames[network];
|
|
51
|
+
if (networkValue === undefined) {
|
|
52
|
+
throw new IdentifierError('Invalid "network" name', INVALID_DID, { network });
|
|
49
53
|
}
|
|
50
|
-
//
|
|
54
|
+
// genesisBytes MUST match the identifier type: a valid compressed secp256k1 public key for KEY,
|
|
55
|
+
// or a 32-byte hash for EXTERNAL. An EXTERNAL DID minted with any other length is unresolvable.
|
|
51
56
|
if (idType === 'KEY') {
|
|
52
57
|
try {
|
|
53
58
|
new CompressedSecp256k1PublicKey(genesisBytes);
|
|
@@ -56,47 +61,15 @@ export class Identifier {
|
|
|
56
61
|
throw new IdentifierError('Expected "genesisBytes" to be a valid compressed secp256k1 public key', INVALID_DID, { genesisBytes });
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// 6.2 “external” - “x”
|
|
62
|
-
const hrp = idType === 'KEY' ? 'k' : 'x';
|
|
63
|
-
// 7. Create an empty nibbles numeric array.
|
|
64
|
-
const nibbles = [];
|
|
65
|
-
// 8. Set fCount equal to (version - 1) / 15, rounded down.
|
|
66
|
-
const fCount = Math.floor((version - 1) / 15);
|
|
67
|
-
// 9. Append hexadecimal F (decimal 15) to nibbles fCount times.
|
|
68
|
-
for (let i = 0; i < fCount; i++) {
|
|
69
|
-
nibbles.push(15);
|
|
70
|
-
}
|
|
71
|
-
// 10. Append (version - 1) mod 15 to nibbles.
|
|
72
|
-
nibbles.push((version - 1) % 15);
|
|
73
|
-
// 11. If network is a string, append the numeric value from the following map to nibbles:
|
|
74
|
-
// "bitcoin" - 0
|
|
75
|
-
// "signet" - 1
|
|
76
|
-
// "regtest" - 2
|
|
77
|
-
// "testnet3" - 3
|
|
78
|
-
// "testnet4" - 4
|
|
79
|
-
// "mutinynet" - 5
|
|
80
|
-
if (typeof network === 'string') {
|
|
81
|
-
nibbles.push(BitcoinNetworkNames[network]);
|
|
82
|
-
}
|
|
83
|
-
else if (typeof network === 'number') {
|
|
84
|
-
// 12. If network is a number, append network + 11 to nibbles.
|
|
85
|
-
nibbles.push(network + 11);
|
|
64
|
+
else if (genesisBytes.length !== 32) {
|
|
65
|
+
throw new IdentifierError('Expected "genesisBytes" to be a 32-byte hash for EXTERNAL identifiers', INVALID_DID, { genesisBytes });
|
|
86
66
|
}
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (fCount !== 0) {
|
|
94
|
-
for (const index in Array.from({ length: (nibbles.length / 2) - 1 })) {
|
|
95
|
-
throw new IdentifierError('Not implemented', 'NOT_IMPLEMENTED', { index });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
const dataBytes = new Uint8Array([(nibbles[2 * 0] << 4) | nibbles[2 * 0 + 1], ...genesisBytes]);
|
|
99
|
-
// 18. Return identifier.
|
|
67
|
+
// Map idType to its human-readable part: KEY -> "k", EXTERNAL -> "x".
|
|
68
|
+
const hrp = idType === 'KEY' ? 'k' : 'x';
|
|
69
|
+
// Pack btcr2_version (high nibble, = version - 1 = 0) and network_value (low nibble) into the first
|
|
70
|
+
// byte, then append genesisBytes. Bech32m-encode the result.
|
|
71
|
+
const firstByte = ((version - 1) << 4) | networkValue;
|
|
72
|
+
const dataBytes = new Uint8Array([firstByte, ...genesisBytes]);
|
|
100
73
|
return `did:btcr2:${bech32m.encodeFromBytes(hrp, dataBytes)}`;
|
|
101
74
|
}
|
|
102
75
|
/**
|
|
@@ -108,104 +81,66 @@ export class Identifier {
|
|
|
108
81
|
* @throws {DidErrorCode.MethodNotSupported} if the method is not supported
|
|
109
82
|
*/
|
|
110
83
|
static decode(identifier) {
|
|
111
|
-
// 1. Split identifier into
|
|
84
|
+
// 1. Split the identifier into scheme, method, and encoded id at the colon character.
|
|
112
85
|
const components = identifier.split(':');
|
|
113
|
-
// 2.
|
|
86
|
+
// 2. There MUST be exactly three colon-separated components.
|
|
114
87
|
if (components.length !== 3) {
|
|
115
88
|
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
116
89
|
}
|
|
117
|
-
// Deconstruct the components of the identifier: scheme, method, encoded
|
|
118
90
|
const [scheme, method, encoded] = components;
|
|
119
|
-
// 3.
|
|
91
|
+
// 3. The scheme MUST be "did".
|
|
120
92
|
if (scheme !== 'did') {
|
|
121
93
|
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
122
94
|
}
|
|
123
|
-
// 4.
|
|
95
|
+
// 4. The method MUST be "btcr2".
|
|
124
96
|
if (method !== 'btcr2') {
|
|
125
97
|
throw new IdentifierError(`Invalid did method: ${method}`, METHOD_NOT_SUPPORTED, { identifier });
|
|
126
98
|
}
|
|
127
|
-
// 5.
|
|
99
|
+
// 5. The method-specific id MUST be present.
|
|
128
100
|
if (!encoded) {
|
|
129
101
|
throw new IdentifierError(`Invalid method-specific id: ${identifier}`, INVALID_DID, { identifier });
|
|
130
102
|
}
|
|
131
|
-
// 6.
|
|
103
|
+
// 6. Bech32m-decode the id into its hrp and dataBytes.
|
|
132
104
|
const { prefix: hrp, bytes: dataBytes } = bech32m.decodeToBytes(encoded);
|
|
133
|
-
// 7.
|
|
105
|
+
// 7. The hrp MUST be "k" (KEY) or "x" (EXTERNAL).
|
|
134
106
|
if (!['x', 'k'].includes(hrp)) {
|
|
135
107
|
throw new IdentifierError(`Invalid hrp: ${hrp}`, INVALID_DID, { identifier });
|
|
136
108
|
}
|
|
137
|
-
|
|
109
|
+
// 8. There MUST be at least one byte to read btcr2_version and network_value from.
|
|
110
|
+
if (!dataBytes || dataBytes.length < 1) {
|
|
138
111
|
throw new IdentifierError(`Failed to decode id: ${encoded}`, INVALID_DID, { identifier });
|
|
139
112
|
}
|
|
140
|
-
//
|
|
141
|
-
// “k” - “key”
|
|
142
|
-
// “x” - “external”
|
|
143
|
-
// other - raise invalidDid error
|
|
113
|
+
// 9. Map hrp to idType.
|
|
144
114
|
const idType = hrp === 'k' ? 'KEY' : 'EXTERNAL';
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
// 15. Advance to the next nibble and set networkValue to its value.
|
|
175
|
-
let networkValue = nibblesConsumed % 2 === 0
|
|
176
|
-
? dataBytes[++byteIndex] >>> 4
|
|
177
|
-
: currentByte & 0x0F;
|
|
178
|
-
nibblesConsumed += 1;
|
|
179
|
-
// 16. Map networkValue to network from the following:
|
|
180
|
-
// 0 - "bitcoin"
|
|
181
|
-
// 1 - "signet"
|
|
182
|
-
// 2 - "regtest"
|
|
183
|
-
// 3 - "testnet3"
|
|
184
|
-
// 4 - "testnet4"
|
|
185
|
-
// 5 - "mutinynet"
|
|
186
|
-
// 6-7 - raise invalidDid error
|
|
187
|
-
// 8-F - networkValue - 11
|
|
188
|
-
let network = BitcoinNetworkNames[networkValue];
|
|
189
|
-
if (!network) {
|
|
190
|
-
if (networkValue >= 0x8 && networkValue <= 0xF) {
|
|
191
|
-
network = networkValue - 11;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// 17. If the number of nibbles consumed is odd:
|
|
198
|
-
if (nibblesConsumed % 2 === 1) {
|
|
199
|
-
// 17.1 Advance to the next nibble and set fillerNibble to its value.
|
|
200
|
-
const fillerNibble = currentByte & 0x0F;
|
|
201
|
-
// 17.2 If fillerNibble is not 0, raise invalidDid error.
|
|
202
|
-
if (fillerNibble !== 0) {
|
|
203
|
-
throw new IdentifierError(`Invalid did: ${identifier}`, INVALID_DID, { identifier });
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
// 18. Set genesisBytes to the remaining dataBytes.
|
|
207
|
-
const genesisBytes = dataBytes.slice(byteIndex + 1);
|
|
208
|
-
// 19. If idType is “key” and genesisBytes is not a valid compressed secp256k1 public key, raise invalidDid error.
|
|
115
|
+
// 10. btcr2_version is the high nibble of the first byte and MUST be 0, which is version_number 1.
|
|
116
|
+
// The version-extension scheme (a leading nibble of 0xF chaining into further bytes) is reserved
|
|
117
|
+
// and not valid under v1, so any non-zero high nibble (0x1 through 0xF) is a malformed or forged
|
|
118
|
+
// identifier and is rejected here. Reading a single flat nibble (rather than looping on 0xF) is
|
|
119
|
+
// what makes this guard actually fire: the previous loop body never ran for a leading nibble of
|
|
120
|
+
// 0x1 through 0xE, silently accepting forged versions.
|
|
121
|
+
const btcr2Version = dataBytes[0] >>> 4;
|
|
122
|
+
if (btcr2Version !== 0) {
|
|
123
|
+
throw new IdentifierError(`Invalid btcr2_version (expected 0): ${btcr2Version}`, INVALID_DID, { identifier });
|
|
124
|
+
}
|
|
125
|
+
const version = 1;
|
|
126
|
+
// 11. network_value is the low nibble of the first byte. 0-5 map to named networks; 12-14 are custom
|
|
127
|
+
// networks (returned as the numeric values 1-3); 6-11 and 15 are reserved/out-of-range and rejected.
|
|
128
|
+
const networkValue = dataBytes[0] & 0x0F;
|
|
129
|
+
const networkName = BitcoinNetworkNames[networkValue];
|
|
130
|
+
let network;
|
|
131
|
+
if (typeof networkName === 'string') {
|
|
132
|
+
network = networkName;
|
|
133
|
+
}
|
|
134
|
+
else if (networkValue >= 12 && networkValue <= 14) {
|
|
135
|
+
network = networkValue - 11;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
throw new IdentifierError(`Invalid network: ${networkValue}`, INVALID_DID, { identifier });
|
|
139
|
+
}
|
|
140
|
+
// 12. genesisBytes is everything after the first byte.
|
|
141
|
+
const genesisBytes = dataBytes.slice(1);
|
|
142
|
+
// 13. genesisBytes MUST match the identifier type: a valid compressed secp256k1 public key for KEY,
|
|
143
|
+
// or a 32-byte hash for EXTERNAL.
|
|
209
144
|
if (idType === 'KEY') {
|
|
210
145
|
try {
|
|
211
146
|
new CompressedSecp256k1PublicKey(genesisBytes);
|
|
@@ -214,7 +149,10 @@ export class Identifier {
|
|
|
214
149
|
throw new IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, INVALID_DID, { identifier });
|
|
215
150
|
}
|
|
216
151
|
}
|
|
217
|
-
|
|
152
|
+
else if (genesisBytes.length !== 32) {
|
|
153
|
+
throw new IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, INVALID_DID, { identifier });
|
|
154
|
+
}
|
|
155
|
+
// 14. Return idType, hrp, version, network, and genesisBytes.
|
|
218
156
|
return { idType, hrp, version, network, genesisBytes };
|
|
219
157
|
}
|
|
220
158
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../src/core/identifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC7H,OAAO,EAAE,4BAA4B,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAWrC,CAAC;AAgBF;;;;;;;;;;GAUG;AACH,MAAM,OAAO,UAAU;IACrB;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,MAAM,CAAC,YAAsC,EAAE,OAAyB;QAC7E,
|
|
1
|
+
{"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../src/core/identifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -371,11 +371,6 @@ export class DidDocument {
|
|
|
371
371
|
return new GenesisDocument(this);
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
|
-
export class Document {
|
|
375
|
-
static isValid(didDocument) {
|
|
376
|
-
return new DidDocument(didDocument).validateGenesis();
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
374
|
/**
|
|
380
375
|
* GenesisDocument extends the DidDocument class for creating and managing intermediate DID documents.
|
|
381
376
|
* This class is used to create a minimal DID document with a placeholder ID.
|