@enbox/dids 0.0.3 → 0.0.5

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.
Files changed (77) hide show
  1. package/dist/browser.mjs +1 -1
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/index.js +2 -0
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/methods/did-dht-dns.js +455 -0
  6. package/dist/esm/methods/did-dht-dns.js.map +1 -0
  7. package/dist/esm/methods/did-dht-pkarr.js +168 -0
  8. package/dist/esm/methods/did-dht-pkarr.js.map +1 -0
  9. package/dist/esm/methods/did-dht-types.js +116 -0
  10. package/dist/esm/methods/did-dht-types.js.map +1 -0
  11. package/dist/esm/methods/did-dht-utils.js +143 -0
  12. package/dist/esm/methods/did-dht-utils.js.map +1 -0
  13. package/dist/esm/methods/did-dht.js +65 -842
  14. package/dist/esm/methods/did-dht.js.map +1 -1
  15. package/dist/esm/methods/did-ion-utils.js +161 -0
  16. package/dist/esm/methods/did-ion-utils.js.map +1 -0
  17. package/dist/esm/methods/did-ion.js +4 -151
  18. package/dist/esm/methods/did-ion.js.map +1 -1
  19. package/dist/esm/methods/did-jwk.js.map +1 -1
  20. package/dist/esm/methods/did-key-utils.js +235 -0
  21. package/dist/esm/methods/did-key-utils.js.map +1 -0
  22. package/dist/esm/methods/did-key.js +6 -222
  23. package/dist/esm/methods/did-key.js.map +1 -1
  24. package/dist/esm/resolver/resolver-cache-memory.js +77 -0
  25. package/dist/esm/resolver/resolver-cache-memory.js.map +1 -0
  26. package/dist/esm/utils.js +25 -0
  27. package/dist/esm/utils.js.map +1 -1
  28. package/dist/types/bearer-did.d.ts +4 -4
  29. package/dist/types/bearer-did.d.ts.map +1 -1
  30. package/dist/types/index.d.ts +2 -0
  31. package/dist/types/index.d.ts.map +1 -1
  32. package/dist/types/methods/did-dht-dns.d.ts +114 -0
  33. package/dist/types/methods/did-dht-dns.d.ts.map +1 -0
  34. package/dist/types/methods/did-dht-pkarr.d.ts +56 -0
  35. package/dist/types/methods/did-dht-pkarr.d.ts.map +1 -0
  36. package/dist/types/methods/did-dht-types.d.ts +286 -0
  37. package/dist/types/methods/did-dht-types.d.ts.map +1 -0
  38. package/dist/types/methods/did-dht-utils.d.ts +54 -0
  39. package/dist/types/methods/did-dht-utils.d.ts.map +1 -0
  40. package/dist/types/methods/did-dht.d.ts +45 -460
  41. package/dist/types/methods/did-dht.d.ts.map +1 -1
  42. package/dist/types/methods/did-ion-utils.d.ts +86 -0
  43. package/dist/types/methods/did-ion-utils.d.ts.map +1 -0
  44. package/dist/types/methods/did-ion.d.ts +4 -84
  45. package/dist/types/methods/did-ion.d.ts.map +1 -1
  46. package/dist/types/methods/did-jwk.d.ts +4 -4
  47. package/dist/types/methods/did-jwk.d.ts.map +1 -1
  48. package/dist/types/methods/did-key-utils.d.ts +138 -0
  49. package/dist/types/methods/did-key-utils.d.ts.map +1 -0
  50. package/dist/types/methods/did-key.d.ts +6 -127
  51. package/dist/types/methods/did-key.d.ts.map +1 -1
  52. package/dist/types/methods/did-method.d.ts +3 -3
  53. package/dist/types/methods/did-method.d.ts.map +1 -1
  54. package/dist/types/resolver/resolver-cache-memory.d.ts +58 -0
  55. package/dist/types/resolver/resolver-cache-memory.d.ts.map +1 -0
  56. package/dist/types/utils.d.ts +19 -0
  57. package/dist/types/utils.d.ts.map +1 -1
  58. package/dist/utils.js +1 -1
  59. package/dist/utils.js.map +4 -4
  60. package/package.json +11 -13
  61. package/src/bearer-did.ts +4 -4
  62. package/src/index.ts +2 -0
  63. package/src/methods/did-dht-dns.ts +516 -0
  64. package/src/methods/did-dht-pkarr.ts +192 -0
  65. package/src/methods/did-dht-types.ts +316 -0
  66. package/src/methods/did-dht-utils.ts +157 -0
  67. package/src/methods/did-dht.ts +125 -1131
  68. package/src/methods/did-ion-utils.ts +186 -0
  69. package/src/methods/did-ion.ts +16 -185
  70. package/src/methods/did-jwk.ts +4 -4
  71. package/src/methods/did-key-utils.ts +258 -0
  72. package/src/methods/did-key.ts +20 -272
  73. package/src/methods/did-method.ts +3 -3
  74. package/src/resolver/resolver-cache-memory.ts +84 -0
  75. package/src/utils.ts +27 -0
  76. package/dist/browser.js +0 -73
  77. package/dist/browser.js.map +0 -7
@@ -0,0 +1,168 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import bencode from 'bencode';
11
+ import { Convert } from '@enbox/common';
12
+ import { Ed25519 } from '@enbox/crypto';
13
+ import { DidError, DidErrorCode } from '../did-error.js';
14
+ import { decode as dnsPacketDecode, encode as dnsPacketEncode } from '@dnsquery/dns-packet';
15
+ /**
16
+ * Constructs a Pkarr URL from public key bytes and a gateway URI.
17
+ *
18
+ * @param publicKeyBytes - The public key bytes to z-base-32 encode.
19
+ * @param gatewayUri - The gateway URI to use as the base URL.
20
+ * @returns The full Pkarr URL.
21
+ */
22
+ function pkarrUrl(publicKeyBytes, gatewayUri) {
23
+ const identifier = Convert.uint8Array(publicKeyBytes).toBase32Z();
24
+ return new URL(identifier, gatewayUri).href;
25
+ }
26
+ /**
27
+ * Retrieves a signed BEP44 message from a DID DHT Gateway or Pkarr Relay server.
28
+ *
29
+ * @see {@link https://github.com/Nuhvi/pkarr/blob/main/design/relays.md | Pkarr Relay design}
30
+ *
31
+ * @param params - The parameters for the get operation.
32
+ * @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
33
+ * @param params.publicKeyBytes - The public key bytes of the Identity Key, z-base-32 encoded.
34
+ * @returns A promise resolving to a BEP44 message containing the signed DNS packet.
35
+ */
36
+ export function pkarrGet(_a) {
37
+ return __awaiter(this, arguments, void 0, function* ({ gatewayUri, publicKeyBytes }) {
38
+ // The identifier (key in the DHT) is the z-base-32 encoding of the Identity Key.
39
+ const identifier = Convert.uint8Array(publicKeyBytes).toBase32Z();
40
+ // Concatenate the gateway URI with the identifier to form the full URL.
41
+ const url = pkarrUrl(publicKeyBytes, gatewayUri);
42
+ // Transmit the Get request to the DID DHT Gateway or Pkarr Relay and get the response.
43
+ let response;
44
+ try {
45
+ response = yield fetch(url, { method: 'GET' });
46
+ if (!response.ok) {
47
+ throw new DidError(DidErrorCode.NotFound, `Pkarr record not found for: ${identifier}`);
48
+ }
49
+ }
50
+ catch (error) {
51
+ if (error instanceof DidError) {
52
+ throw error;
53
+ }
54
+ throw new DidError(DidErrorCode.InternalError, `Failed to fetch Pkarr record: ${error.message}`);
55
+ }
56
+ // Read the Fetch Response stream into a byte array.
57
+ const messageBytes = yield response.arrayBuffer();
58
+ if (!messageBytes) {
59
+ throw new DidError(DidErrorCode.NotFound, `Pkarr record not found for: ${identifier}`);
60
+ }
61
+ if (messageBytes.byteLength < 72) {
62
+ throw new DidError(DidErrorCode.InvalidDidDocumentLength, `Pkarr response must be at least 72 bytes but got: ${messageBytes.byteLength}`);
63
+ }
64
+ if (messageBytes.byteLength > 1072) {
65
+ throw new DidError(DidErrorCode.InvalidDidDocumentLength, `Pkarr response exceeds 1000 byte limit: ${messageBytes.byteLength}`);
66
+ }
67
+ // Decode the BEP44 message from the byte array.
68
+ const bep44Message = {
69
+ k: publicKeyBytes,
70
+ seq: Number(new DataView(messageBytes).getBigUint64(64)),
71
+ sig: new Uint8Array(messageBytes, 0, 64),
72
+ v: new Uint8Array(messageBytes, 72)
73
+ };
74
+ return bep44Message;
75
+ });
76
+ }
77
+ /**
78
+ * Publishes a signed BEP44 message to a DID DHT Gateway or Pkarr Relay server.
79
+ *
80
+ * @see {@link https://github.com/Nuhvi/pkarr/blob/main/design/relays.md | Pkarr Relay design}
81
+ *
82
+ * @param params - The parameters to use when publishing a signed BEP44 message to a Pkarr relay server.
83
+ * @param params.gatewayUri - The DID DHT Gateway or Pkarr Relay URI.
84
+ * @param params.bep44Message - The BEP44 message to be published, containing the signed DNS packet.
85
+ * @returns A promise resolving to `true` if the message was successfully published, otherwise `false`.
86
+ */
87
+ export function pkarrPut(_a) {
88
+ return __awaiter(this, arguments, void 0, function* ({ gatewayUri, bep44Message }) {
89
+ // The identifier (key in the DHT) is the z-base-32 encoding of the Identity Key.
90
+ const identifier = Convert.uint8Array(bep44Message.k).toBase32Z();
91
+ // Concatenate the gateway URI with the identifier to form the full URL.
92
+ const url = pkarrUrl(bep44Message.k, gatewayUri);
93
+ // Construct the body of the request according to the Pkarr relay specification.
94
+ const body = new Uint8Array(bep44Message.v.length + 72);
95
+ body.set(bep44Message.sig, 0);
96
+ new DataView(body.buffer).setBigUint64(bep44Message.sig.length, BigInt(bep44Message.seq));
97
+ body.set(bep44Message.v, bep44Message.sig.length + 8);
98
+ // Transmit the Put request to the Pkarr relay and get the response.
99
+ let response;
100
+ try {
101
+ response = yield fetch(url, {
102
+ method: 'PUT',
103
+ headers: { 'Content-Type': 'application/octet-stream' },
104
+ body
105
+ });
106
+ }
107
+ catch (error) {
108
+ throw new DidError(DidErrorCode.InternalError, `Failed to put Pkarr record for identifier ${identifier}: ${error.message}`);
109
+ }
110
+ // Return `true` if the DHT request was successful, otherwise return `false`.
111
+ return response.ok;
112
+ });
113
+ }
114
+ /**
115
+ * Creates a BEP44 put message, which is used to publish a DID document to the DHT network.
116
+ *
117
+ * @param params - The parameters to use when creating the BEP44 put message.
118
+ * @param params.dnsPacket - The DNS packet to encode in the BEP44 message.
119
+ * @param params.publicKeyBytes - The public key bytes of the Identity Key.
120
+ * @param params.signer - Signer that can sign and verify data using the Identity Key.
121
+ * @returns A promise that resolves to a BEP44 put message.
122
+ */
123
+ export function createBep44PutMessage(_a) {
124
+ return __awaiter(this, arguments, void 0, function* ({ dnsPacket, publicKeyBytes, signer }) {
125
+ // BEP44 requires that the sequence number be a monotoically increasing integer, so we use the
126
+ // current time in seconds since Unix epoch as a simple solution. Higher precision is not
127
+ // recommended since DID DHT documents are not expected to change frequently and there are
128
+ // small differences in system clocks that can cause issues if multiple clients are publishing
129
+ // updates to the same DID document.
130
+ const sequenceNumber = Math.ceil(Date.now() / 1000);
131
+ // Encode the DNS packet into a byte array containing a UDP payload.
132
+ const encodedDnsPacket = dnsPacketEncode(dnsPacket);
133
+ // Encode the sequence and DNS byte array to bencode format.
134
+ const bencodedData = bencode.encode({ seq: sequenceNumber, v: encodedDnsPacket }).subarray(1, -1);
135
+ if (bencodedData.length > 1000) {
136
+ throw new DidError(DidErrorCode.InvalidDidDocumentLength, `DNS packet exceeds the 1000 byte maximum size: ${bencodedData.length} bytes`);
137
+ }
138
+ // Sign the BEP44 message.
139
+ const signature = yield signer.sign({ data: bencodedData });
140
+ return { k: publicKeyBytes, seq: sequenceNumber, sig: signature, v: encodedDnsPacket };
141
+ });
142
+ }
143
+ /**
144
+ * Parses and verifies a BEP44 Get message, converting it to a DNS packet.
145
+ *
146
+ * @param params - The parameters to use when verifying and parsing the BEP44 Get response message.
147
+ * @param params.bep44Message - The BEP44 message to verify and parse.
148
+ * @returns A promise that resolves to a DNS packet.
149
+ */
150
+ export function parseBep44GetMessage(_a) {
151
+ return __awaiter(this, arguments, void 0, function* ({ bep44Message }) {
152
+ // Convert the public key byte array to JWK format.
153
+ const publicKey = yield Ed25519.bytesToPublicKey({ publicKeyBytes: bep44Message.k });
154
+ // Encode the sequence and DNS byte array to bencode format.
155
+ const bencodedData = bencode.encode({ seq: bep44Message.seq, v: bep44Message.v }).subarray(1, -1);
156
+ // Verify the signature of the BEP44 message.
157
+ const isValid = yield Ed25519.verify({
158
+ key: publicKey,
159
+ signature: bep44Message.sig,
160
+ data: bencodedData
161
+ });
162
+ if (!isValid) {
163
+ throw new DidError(DidErrorCode.InvalidSignature, `Invalid signature for DHT BEP44 message`);
164
+ }
165
+ return dnsPacketDecode(bep44Message.v);
166
+ });
167
+ }
168
+ //# sourceMappingURL=did-dht-pkarr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did-dht-pkarr.js","sourceRoot":"","sources":["../../../src/methods/did-dht-pkarr.ts"],"names":[],"mappings":";;;;;;;;;AAKA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5F;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,cAA0B,EAAE,UAAkB;IAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,CAAC;IAClE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAgB,QAAQ;yDAAC,EAAE,UAAU,EAAE,cAAc,EAG1D;QACC,iFAAiF;QACjF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,CAAC;QAElE,wEAAwE;QACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAEjD,uFAAuF;QACvF,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAE/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAE,+BAA+B,UAAU,EAAE,CAAC,CAAC;YACzF,CAAC;QAEH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAAA,MAAM,KAAK,CAAC;YAAA,CAAC;YAC7C,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,iCAAiC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACnG,CAAC;QAED,oDAAoD;QACpD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QAElD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAE,+BAA+B,UAAU,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,IAAI,YAAY,CAAC,UAAU,GAAG,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,wBAAwB,EAAE,qDAAqD,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC;QAC5I,CAAC;QAED,IAAI,YAAY,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,wBAAwB,EAAE,2CAA2C,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC;QAClI,CAAC;QAED,gDAAgD;QAChD,MAAM,YAAY,GAAiB;YACjC,CAAC,EAAK,cAAc;YACpB,GAAG,EAAG,MAAM,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACzD,GAAG,EAAG,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,CAAC,EAAK,IAAI,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC;SACvC,CAAC;QAEF,OAAO,YAAY,CAAC;IACtB,CAAC;CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,UAAgB,QAAQ;yDAAC,EAAE,UAAU,EAAE,YAAY,EAGxD;QACC,iFAAiF;QACjF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QAElE,wEAAwE;QACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAEjD,gFAAgF;QAChF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEtD,oEAAoE;QACpE,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC1B,MAAM,EAAI,KAAK;gBACf,OAAO,EAAG,EAAE,cAAc,EAAE,0BAA0B,EAAE;gBACxD,IAAI;aACL,CAAC,CAAC;QAEL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,6CAA6C,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9H,CAAC;QAED,6EAA6E;QAC7E,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,UAAgB,qBAAqB;yDAAC,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAI9E;QACC,8FAA8F;QAC9F,yFAAyF;QACzF,0FAA0F;QAC1F,8FAA8F;QAC9F,oCAAoC;QACpC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAEpD,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAEpD,4DAA4D;QAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAElG,IAAI,YAAY,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YAC/B,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,wBAAwB,EAAE,kDAAkD,YAAY,CAAC,MAAM,QAAQ,CAAC,CAAC;QAC3I,CAAC;QAED,0BAA0B;QAC1B,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QAE5D,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACzF,CAAC;CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAgB,oBAAoB;yDAAC,EAAE,YAAY,EAExD;QACC,mDAAmD;QACnD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;QAErF,4DAA4D;QAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAElG,6CAA6C;QAC7C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC;YACnC,GAAG,EAAS,SAAS;YACrB,SAAS,EAAG,YAAY,CAAC,GAAG;YAC5B,IAAI,EAAQ,YAAY;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,gBAAgB,EAAE,yCAAyC,CAAC,CAAC;QAC/F,CAAC;QAED,OAAO,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;CAAA"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Represents an optional extension to a DID Document's DNS packet representation exposed as a
3
+ * type index.
4
+ *
5
+ * Type indexing is an OPTIONAL feature that enables DIDs to become discoverable. DIDs that wish to
6
+ * be discoverable and resolveable by type can include one or more types when publishing their DID
7
+ * document to a DID DHT Gateway.
8
+ *
9
+ * The registered DID types are published in the {@link https://did-dht.com/registry/index.html#indexed-types | DID DHT Registry}.
10
+ */
11
+ export var DidDhtRegisteredDidType;
12
+ (function (DidDhtRegisteredDidType) {
13
+ /**
14
+ * Type 0 is reserved for DIDs that do not wish to associate themselves with a specific type but
15
+ * wish to make themselves discoverable.
16
+ */
17
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["Discoverable"] = 0] = "Discoverable";
18
+ /**
19
+ * Organization
20
+ * @see {@link https://schema.org/Organization | schema definition}
21
+ */
22
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["Organization"] = 1] = "Organization";
23
+ /**
24
+ * Government Organization
25
+ * @see {@link https://schema.org/GovernmentOrganization | schema definition}
26
+ */
27
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["Government"] = 2] = "Government";
28
+ /**
29
+ * Corporation
30
+ * @see {@link https://schema.org/Corporation | schema definition}
31
+ */
32
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["Corporation"] = 3] = "Corporation";
33
+ /**
34
+ * Corporation
35
+ * @see {@link https://schema.org/Corporation | schema definition}
36
+ */
37
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["LocalBusiness"] = 4] = "LocalBusiness";
38
+ /**
39
+ * Software Package
40
+ * @see {@link https://schema.org/SoftwareSourceCode | schema definition}
41
+ */
42
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["SoftwarePackage"] = 5] = "SoftwarePackage";
43
+ /**
44
+ * Web App
45
+ * @see {@link https://schema.org/WebApplication | schema definition}
46
+ */
47
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["WebApp"] = 6] = "WebApp";
48
+ /**
49
+ * Financial Institution
50
+ * @see {@link https://schema.org/FinancialService | schema definition}
51
+ */
52
+ DidDhtRegisteredDidType[DidDhtRegisteredDidType["FinancialInstitution"] = 7] = "FinancialInstitution";
53
+ })(DidDhtRegisteredDidType || (DidDhtRegisteredDidType = {}));
54
+ /**
55
+ * Enumerates the types of keys that can be used in a DID DHT document.
56
+ *
57
+ * The DID DHT method supports various cryptographic key types. These key types are essential for
58
+ * the creation and management of DIDs and their associated cryptographic operations like signing
59
+ * and encryption. The registered key types are published in the DID DHT Registry and each is
60
+ * assigned a unique numerical value for use by client and gateway implementations.
61
+ *
62
+ * The registered key types are published in the {@link https://did-dht.com/registry/index.html#key-type-index | DID DHT Registry}.
63
+ */
64
+ export var DidDhtRegisteredKeyType;
65
+ (function (DidDhtRegisteredKeyType) {
66
+ /**
67
+ * Ed25519: A public-key signature system using the EdDSA (Edwards-curve Digital Signature
68
+ * Algorithm) and Curve25519.
69
+ */
70
+ DidDhtRegisteredKeyType[DidDhtRegisteredKeyType["Ed25519"] = 0] = "Ed25519";
71
+ /**
72
+ * secp256k1: A cryptographic curve used for digital signatures in a range of decentralized
73
+ * systems.
74
+ */
75
+ DidDhtRegisteredKeyType[DidDhtRegisteredKeyType["secp256k1"] = 1] = "secp256k1";
76
+ /**
77
+ * secp256r1: Also known as P-256 or prime256v1, this curve is used for cryptographic operations
78
+ * and is widely supported in various cryptographic libraries and standards.
79
+ */
80
+ DidDhtRegisteredKeyType[DidDhtRegisteredKeyType["secp256r1"] = 2] = "secp256r1";
81
+ /**
82
+ * X25519: A public key used for Diffie-Hellman key exchange using Curve25519.
83
+ */
84
+ DidDhtRegisteredKeyType[DidDhtRegisteredKeyType["X25519"] = 3] = "X25519";
85
+ })(DidDhtRegisteredKeyType || (DidDhtRegisteredKeyType = {}));
86
+ /**
87
+ * Maps {@link https://www.w3.org/TR/did-core/#verification-relationships | DID Core Verification Relationship}
88
+ * values to the corresponding record name in the DNS packet representation of a DHT DID document.
89
+ */
90
+ export var DidDhtVerificationRelationship;
91
+ (function (DidDhtVerificationRelationship) {
92
+ /**
93
+ * Specifies how the DID subject is expected to be authenticated.
94
+ */
95
+ DidDhtVerificationRelationship["authentication"] = "auth";
96
+ /**
97
+ * Specifies how the DID subject is expected to express claims, such as for issuing Verifiable
98
+ * Credentials.
99
+ */
100
+ DidDhtVerificationRelationship["assertionMethod"] = "asm";
101
+ /**
102
+ * Specifies a mechanism used by the DID subject to delegate a cryptographic capability to another
103
+ * party
104
+ */
105
+ DidDhtVerificationRelationship["capabilityDelegation"] = "del";
106
+ /**
107
+ * Specifies a verification method used by the DID subject to invoke a cryptographic capability.
108
+ */
109
+ DidDhtVerificationRelationship["capabilityInvocation"] = "inv";
110
+ /**
111
+ * Specifies how an entity can generate encryption material to communicate confidentially with the
112
+ * DID subject.
113
+ */
114
+ DidDhtVerificationRelationship["keyAgreement"] = "agm";
115
+ })(DidDhtVerificationRelationship || (DidDhtVerificationRelationship = {}));
116
+ //# sourceMappingURL=did-dht-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did-dht-types.js","sourceRoot":"","sources":["../../../src/methods/did-dht-types.ts"],"names":[],"mappings":"AA4LA;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,uBAgDX;AAhDD,WAAY,uBAAuB;IACjC;;;OAGG;IACH,qFAAgB,CAAA;IAEhB;;;OAGG;IACH,qFAAgB,CAAA;IAEhB;;;OAGG;IACH,iFAAc,CAAA;IAEd;;;OAGG;IACH,mFAAe,CAAA;IAEf;;;OAGG;IACH,uFAAiB,CAAA;IAEjB;;;OAGG;IACH,2FAAmB,CAAA;IAEnB;;;OAGG;IACH,yEAAU,CAAA;IAEV;;;OAGG;IACH,qGAAwB,CAAA;AAC1B,CAAC,EAhDW,uBAAuB,KAAvB,uBAAuB,QAgDlC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,uBAuBX;AAvBD,WAAY,uBAAuB;IACjC;;;OAGG;IACH,2EAAW,CAAA;IAEX;;;OAGG;IACH,+EAAa,CAAA;IAEb;;;OAGG;IACH,+EAAa,CAAA;IAEb;;OAEG;IACH,yEAAU,CAAA;AACZ,CAAC,EAvBW,uBAAuB,KAAvB,uBAAuB,QAuBlC;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,8BA4BX;AA5BD,WAAY,8BAA8B;IACxC;;OAEG;IACH,yDAAuB,CAAA;IAEvB;;;OAGG;IACH,yDAAuB,CAAA;IAEvB;;;OAGG;IACH,8DAA4B,CAAA;IAE5B;;OAEG;IACH,8DAA4B,CAAA;IAE5B;;;OAGG;IACH,sDAAoB,CAAA;AACtB,CAAC,EA5BW,8BAA8B,KAA9B,8BAA8B,QA4BzC"}
@@ -0,0 +1,143 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Convert } from '@enbox/common';
11
+ import { Ed25519, Secp256k1, Secp256r1, X25519 } from '@enbox/crypto';
12
+ import { Did } from '../did.js';
13
+ import { DidError, DidErrorCode } from '../did-error.js';
14
+ /**
15
+ * The DID DHT method name.
16
+ */
17
+ const DID_DHT_METHOD_NAME = 'dht';
18
+ /**
19
+ * Converts a DID URI to a JSON Web Key (JWK) representing the Identity Key.
20
+ *
21
+ * @param params - The parameters to use for the conversion.
22
+ * @param params.didUri - The DID URI containing the Identity Key.
23
+ * @returns A promise that resolves to a JWK representing the Identity Key.
24
+ */
25
+ export function identifierToIdentityKey(_a) {
26
+ return __awaiter(this, arguments, void 0, function* ({ didUri }) {
27
+ // Decode the method-specific identifier from z-base-32 to a byte array.
28
+ const identityKeyBytes = identifierToIdentityKeyBytes({ didUri });
29
+ // Convert the byte array to a JWK.
30
+ const identityKey = yield Ed25519.bytesToPublicKey({ publicKeyBytes: identityKeyBytes });
31
+ return identityKey;
32
+ });
33
+ }
34
+ /**
35
+ * Converts a DID URI to the byte array representation of the Identity Key.
36
+ *
37
+ * @param params - The parameters to use for the conversion.
38
+ * @param params.didUri - The DID URI containing the Identity Key.
39
+ * @returns A byte array representation of the Identity Key.
40
+ */
41
+ export function identifierToIdentityKeyBytes({ didUri }) {
42
+ // Parse the DID URI.
43
+ const parsedDid = Did.parse(didUri);
44
+ // Verify that the DID URI is valid.
45
+ if (!parsedDid) {
46
+ throw new DidError(DidErrorCode.InvalidDid, `Invalid DID URI: ${didUri}`);
47
+ }
48
+ // Verify the DID method is supported.
49
+ if (parsedDid.method !== DID_DHT_METHOD_NAME) {
50
+ throw new DidError(DidErrorCode.MethodNotSupported, `Method not supported: ${parsedDid.method}`);
51
+ }
52
+ // Decode the method-specific identifier from z-base-32 to a byte array.
53
+ let identityKeyBytes;
54
+ try {
55
+ identityKeyBytes = Convert.base32Z(parsedDid.id).toUint8Array();
56
+ }
57
+ catch (_a) {
58
+ throw new DidError(DidErrorCode.InvalidPublicKey, `Failed to decode method-specific identifier`);
59
+ }
60
+ if (identityKeyBytes.length !== 32) {
61
+ throw new DidError(DidErrorCode.InvalidPublicKeyLength, `Invalid public key length: ${identityKeyBytes.length}`);
62
+ }
63
+ return identityKeyBytes;
64
+ }
65
+ /**
66
+ * Encodes a DID DHT Identity Key into a DID identifier.
67
+ *
68
+ * This method first z-base-32 encodes the Identity Key. The resulting string is prefixed with
69
+ * `did:dht:` to form the DID identifier.
70
+ *
71
+ * @param params - The parameters to use for the conversion.
72
+ * @param params.identityKey The Identity Key from which the DID identifier is computed.
73
+ * @returns A promise that resolves to a string containing the DID identifier.
74
+ */
75
+ export function identityKeyToIdentifier(_a) {
76
+ return __awaiter(this, arguments, void 0, function* ({ identityKey }) {
77
+ // Convert the key from JWK format to a byte array.
78
+ const publicKeyBytes = yield Ed25519.publicKeyToBytes({ publicKey: identityKey });
79
+ // Encode the byte array as a z-base-32 string.
80
+ const identifier = Convert.uint8Array(publicKeyBytes).toBase32Z();
81
+ return `did:${DID_DHT_METHOD_NAME}:${identifier}`;
82
+ });
83
+ }
84
+ /**
85
+ * Returns the appropriate key converter for the specified cryptographic curve.
86
+ *
87
+ * @param curve - The cryptographic curve to use for the key conversion.
88
+ * @returns An `AsymmetricKeyConverter` for the specified curve.
89
+ */
90
+ export function keyConverter(curve) {
91
+ const converters = {
92
+ 'Ed25519': Ed25519,
93
+ 'P-256': {
94
+ // Wrap the key converter which produces uncompressed public key bytes to produce compressed key bytes as required by the DID DHT spec.
95
+ // See https://did-dht.com/#representing-keys for more info.
96
+ publicKeyToBytes: (_a) => __awaiter(this, [_a], void 0, function* ({ publicKey }) {
97
+ const publicKeyBytes = yield Secp256r1.publicKeyToBytes({ publicKey });
98
+ const compressedPublicKey = yield Secp256r1.compressPublicKey({ publicKeyBytes });
99
+ return compressedPublicKey;
100
+ }),
101
+ bytesToPublicKey: Secp256r1.bytesToPublicKey,
102
+ privateKeyToBytes: Secp256r1.privateKeyToBytes,
103
+ bytesToPrivateKey: Secp256r1.bytesToPrivateKey,
104
+ },
105
+ 'secp256k1': {
106
+ // Wrap the key converter which produces uncompressed public key bytes to produce compressed key bytes as required by the DID DHT spec.
107
+ // See https://did-dht.com/#representing-keys for more info.
108
+ publicKeyToBytes: (_a) => __awaiter(this, [_a], void 0, function* ({ publicKey }) {
109
+ const publicKeyBytes = yield Secp256k1.publicKeyToBytes({ publicKey });
110
+ const compressedPublicKey = yield Secp256k1.compressPublicKey({ publicKeyBytes });
111
+ return compressedPublicKey;
112
+ }),
113
+ bytesToPublicKey: Secp256k1.bytesToPublicKey,
114
+ privateKeyToBytes: Secp256k1.privateKeyToBytes,
115
+ bytesToPrivateKey: Secp256k1.bytesToPrivateKey,
116
+ },
117
+ X25519: X25519,
118
+ };
119
+ const converter = converters[curve];
120
+ if (!converter) {
121
+ throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);
122
+ }
123
+ return converter;
124
+ }
125
+ /**
126
+ * Validates the proof of previous DID given.
127
+ *
128
+ * @param params - The parameters to validate the previous DID proof.
129
+ * @param params.newDid - The new DID that the previous DID is linking to.
130
+ * @param params.previousDidProof - The proof of the previous DID, containing the previous DID and signature signed by the previous DID.
131
+ */
132
+ export function validatePreviousDidProof(_a) {
133
+ return __awaiter(this, arguments, void 0, function* ({ newDid, previousDidProof }) {
134
+ const key = yield identifierToIdentityKey({ didUri: previousDidProof.previousDid });
135
+ const data = identifierToIdentityKeyBytes({ didUri: newDid });
136
+ const signature = Convert.base64Url(previousDidProof.signature).toUint8Array();
137
+ const isValid = yield Ed25519.verify({ key, data, signature });
138
+ if (!isValid) {
139
+ throw new DidError(DidErrorCode.InvalidPreviousDidProof, 'The previous DID proof is invalid.');
140
+ }
141
+ });
142
+ }
143
+ //# sourceMappingURL=did-dht-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did-dht-utils.js","sourceRoot":"","sources":["../../../src/methods/did-dht-utils.ts"],"names":[],"mappings":"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"}