@dwn-protocol/id-sdk 0.2.5 → 0.2.6
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/package.json +2 -3
- package/src/agent/app-data-store.ts +0 -365
- package/src/agent/did-manager.ts +0 -393
- package/src/agent/dwn-manager.ts +0 -548
- package/src/agent/identity-manager.ts +0 -165
- package/src/agent/index.ts +0 -19
- package/src/agent/json-rpc.ts +0 -107
- package/src/agent/key-manager.ts +0 -302
- package/src/agent/kms-local.ts +0 -412
- package/src/agent/outbox.ts +0 -128
- package/src/agent/rpc-client.ts +0 -223
- package/src/agent/store-managed-did.ts +0 -295
- package/src/agent/store-managed-identity.ts +0 -243
- package/src/agent/store-managed-key.ts +0 -754
- package/src/agent/sync-manager.ts +0 -631
- package/src/agent/test-managed-agent.ts +0 -299
- package/src/agent/types/agent.ts +0 -145
- package/src/agent/types/managed-key.ts +0 -442
- package/src/agent/utils.ts +0 -190
- package/src/common/convert.ts +0 -424
- package/src/common/index.ts +0 -9
- package/src/common/multicodec.ts +0 -176
- package/src/common/object.ts +0 -43
- package/src/common/stores.ts +0 -125
- package/src/common/stream-node.ts +0 -381
- package/src/common/stream.ts +0 -406
- package/src/common/type-utils.ts +0 -117
- package/src/common/types.ts +0 -48
- package/src/credentials/credential-bbs.ts +0 -419
- package/src/credentials/credential.ts +0 -324
- package/src/credentials/index.ts +0 -5
- package/src/credentials/presentation.ts +0 -182
- package/src/credentials/status-list.ts +0 -365
- package/src/credentials/utils.ts +0 -58
- package/src/credentials/validators.ts +0 -52
- package/src/crypto/algorithms-api/aes/base.ts +0 -49
- package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
- package/src/crypto/algorithms-api/aes/index.ts +0 -2
- package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
- package/src/crypto/algorithms-api/crypto-key.ts +0 -56
- package/src/crypto/algorithms-api/ec/base.ts +0 -39
- package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
- package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
- package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
- package/src/crypto/algorithms-api/ec/index.ts +0 -4
- package/src/crypto/algorithms-api/errors.ts +0 -29
- package/src/crypto/algorithms-api/index.ts +0 -6
- package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
- package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
- package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
- package/src/crypto/crypto-algorithms/bbs.ts +0 -110
- package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
- package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
- package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
- package/src/crypto/crypto-algorithms/index.ts +0 -6
- package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
- package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
- package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
- package/src/crypto/crypto-primitives/bbs.ts +0 -183
- package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
- package/src/crypto/crypto-primitives/ed25519.ts +0 -201
- package/src/crypto/crypto-primitives/index.ts +0 -10
- package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
- package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
- package/src/crypto/crypto-primitives/x25519.ts +0 -101
- package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
- package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
- package/src/crypto/index.ts +0 -8
- package/src/crypto/jose.ts +0 -948
- package/src/crypto/types/crypto-key.ts +0 -4
- package/src/crypto/types/iddwn-crypto.ts +0 -119
- package/src/crypto/utils.ts +0 -200
- package/src/did-api.ts +0 -72
- package/src/dids/dht.ts +0 -412
- package/src/dids/did-dht.ts +0 -436
- package/src/dids/did-ion.ts +0 -613
- package/src/dids/did-key.ts +0 -791
- package/src/dids/did-resolver.ts +0 -107
- package/src/dids/index.ts +0 -9
- package/src/dids/resolver-cache-level.ts +0 -82
- package/src/dids/resolver-cache-noop.ts +0 -25
- package/src/dids/types.ts +0 -278
- package/src/dids/utils.ts +0 -129
- package/src/dwn-api.ts +0 -584
- package/src/iddwn.ts +0 -241
- package/src/identity-agent/index.ts +0 -270
- package/src/index.ts +0 -26
- package/src/interfaces/metadata.ts +0 -163
- package/src/interfaces/queue.ts +0 -108
- package/src/interfaces/services.ts +0 -122
- package/src/interfaces/transactions.ts +0 -220
- package/src/protocol.ts +0 -68
- package/src/proxy-agent/index.ts +0 -255
- package/src/record.ts +0 -521
- package/src/service-options.ts +0 -62
- package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
- package/src/user-agent/index.ts +0 -295
- package/src/utils.ts +0 -29
- package/src/vc-api.ts +0 -505
package/src/dids/dht.ts
DELETED
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
import type { Packet, TxtAnswer } from 'dns-packet';
|
|
2
|
-
import type { PublicKeyJwk, IDCrypto} from '../crypto/index.js';
|
|
3
|
-
|
|
4
|
-
import { Jose } from '../crypto/index.js';
|
|
5
|
-
import { Convert } from '../common/index.js';
|
|
6
|
-
import { Pkarr, SignedPacket, z32 } from 'pkarr';
|
|
7
|
-
import dns, { AUTHORITATIVE_ANSWER } from 'dns-packet';
|
|
8
|
-
import { Buffer } from 'buffer';
|
|
9
|
-
|
|
10
|
-
import type { DidDocument } from './types.js';
|
|
11
|
-
|
|
12
|
-
const DEFAULT_PKARR_RELAY = 'https://relay.dwn.id/dht';
|
|
13
|
-
// const DEFAULT_PKARR_RELAY = 'http://localhost:8305';
|
|
14
|
-
const TTL = 7200;
|
|
15
|
-
|
|
16
|
-
function ensureBufferBigIntMethods(): void {
|
|
17
|
-
const proto = Buffer?.prototype as any;
|
|
18
|
-
if (!proto) return;
|
|
19
|
-
|
|
20
|
-
if (typeof proto.writeBigUInt64BE !== 'function') {
|
|
21
|
-
proto.writeBigUInt64BE = function writeBigUInt64BE(value: bigint | number, offset = 0): number {
|
|
22
|
-
const bigintValue = typeof value === 'bigint' ? value : BigInt(value);
|
|
23
|
-
const view = new DataView(this.buffer, this.byteOffset, this.byteLength);
|
|
24
|
-
view.setBigUint64(offset, bigintValue, false);
|
|
25
|
-
return offset + 8;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (typeof proto.readBigUInt64BE !== 'function') {
|
|
30
|
-
proto.readBigUInt64BE = function readBigUInt64BE(offset = 0): bigint {
|
|
31
|
-
const view = new DataView(this.buffer, this.byteOffset, this.byteLength);
|
|
32
|
-
return view.getBigUint64(offset, false);
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A class to handle operations related to DHT-based Decentralized Identifiers (DIDs).
|
|
39
|
-
* It provides methods to:
|
|
40
|
-
* - Parse a DNS packet into a DID Document.
|
|
41
|
-
* - Retrieve a DID Document from the DHT.
|
|
42
|
-
* - Publish a DID Document to the DHT.
|
|
43
|
-
* - Convert a DID Document to a DNS packet.
|
|
44
|
-
*
|
|
45
|
-
* The class assumes that DIDs and DID Documents are compliant with the did:dht specification.
|
|
46
|
-
*/
|
|
47
|
-
export class DidDht {
|
|
48
|
-
private static relayUrl = DEFAULT_PKARR_RELAY;
|
|
49
|
-
|
|
50
|
-
public static setRelayUrl(relayUrl: string): void {
|
|
51
|
-
this.relayUrl = relayUrl;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public static getRelayUrl(): string {
|
|
55
|
-
return this.relayUrl;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Parses a DNS packet into a DID Document.
|
|
60
|
-
* @param did The DID of the document.
|
|
61
|
-
* @param packet A DNS packet to parse into a DID Document.
|
|
62
|
-
* @returns A Promise that resolves to the parsed DidDocument.
|
|
63
|
-
*/
|
|
64
|
-
public static async fromDnsPacket({ did, packet }: {
|
|
65
|
-
did: string,
|
|
66
|
-
packet: Packet
|
|
67
|
-
}): Promise<DidDocument> {
|
|
68
|
-
const document: Partial<DidDocument> = {
|
|
69
|
-
id: did,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const keyLookup = new Map<string, string>();
|
|
73
|
-
|
|
74
|
-
for (const answer of packet.answers) {
|
|
75
|
-
if (answer.type !== 'TXT') continue;
|
|
76
|
-
|
|
77
|
-
const dataStr = answer.data?.toString();
|
|
78
|
-
// Extracts 'k' or 's' from "_k0._did" or "_s0._did"
|
|
79
|
-
const recordType = answer.name?.split('.')[0].substring(1, 2);
|
|
80
|
-
|
|
81
|
-
/*eslint-disable no-case-declarations*/
|
|
82
|
-
switch (recordType) {
|
|
83
|
-
case 'k': {
|
|
84
|
-
const { id, t, k } = DidDht.parseTxtData({ data: dataStr });
|
|
85
|
-
const keyConfigurations: { [keyType: string]: Partial<PublicKeyJwk> } = {
|
|
86
|
-
'0': {
|
|
87
|
-
crv : 'Ed25519',
|
|
88
|
-
kty : 'OKP',
|
|
89
|
-
alg : 'EdDSA'
|
|
90
|
-
},
|
|
91
|
-
'1': {
|
|
92
|
-
crv : 'secp256k1',
|
|
93
|
-
kty : 'EC',
|
|
94
|
-
alg : 'ES256K'
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
const keyConfig = keyConfigurations[t];
|
|
98
|
-
if (!keyConfig) {
|
|
99
|
-
throw new Error('Unsupported key type');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const publicKeyJwk = await Jose.keyToJwk({
|
|
103
|
-
...keyConfig,
|
|
104
|
-
kid : id,
|
|
105
|
-
keyMaterial : Convert.base64Url(k).toUint8Array(),
|
|
106
|
-
keyType : 'public'
|
|
107
|
-
}) as PublicKeyJwk;
|
|
108
|
-
|
|
109
|
-
if (!document.verificationMethod) {
|
|
110
|
-
document.verificationMethod = [];
|
|
111
|
-
}
|
|
112
|
-
document.verificationMethod.push({
|
|
113
|
-
id : `${did}#${id}`,
|
|
114
|
-
type : 'JsonWebKey2020',
|
|
115
|
-
controller : did,
|
|
116
|
-
publicKeyJwk : publicKeyJwk,
|
|
117
|
-
});
|
|
118
|
-
keyLookup.set(answer.name, id);
|
|
119
|
-
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
case 's': {
|
|
124
|
-
const {id: sId, t: sType, uri} = DidDht.parseTxtData({ data: dataStr });
|
|
125
|
-
|
|
126
|
-
if (!document.service) {
|
|
127
|
-
document.service = [];
|
|
128
|
-
}
|
|
129
|
-
document.service.push({
|
|
130
|
-
id : `${did}#${sId}`,
|
|
131
|
-
type : sType,
|
|
132
|
-
serviceEndpoint : DidDht.decodeServiceEndpoint({ encoded: uri })
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Extract relationships from root record
|
|
141
|
-
const didSuffix = did.split('did:dht:')[1];
|
|
142
|
-
const potentialRootNames = ['_did', `_did.${didSuffix}`];
|
|
143
|
-
|
|
144
|
-
let actualRootName = null;
|
|
145
|
-
const root = packet.answers
|
|
146
|
-
.filter(answer => {
|
|
147
|
-
if (potentialRootNames.includes(answer.name)) {
|
|
148
|
-
actualRootName = answer.name;
|
|
149
|
-
return true;
|
|
150
|
-
}
|
|
151
|
-
return false;
|
|
152
|
-
}) as dns.TxtAnswer[];
|
|
153
|
-
|
|
154
|
-
if (root.length === 0) {
|
|
155
|
-
throw new Error('No root record found');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (root.length > 1) {
|
|
159
|
-
throw new Error('Multiple root records found');
|
|
160
|
-
}
|
|
161
|
-
const singleRoot = root[0] as dns.TxtAnswer;
|
|
162
|
-
const rootRecord = singleRoot.data?.toString().split(';');
|
|
163
|
-
rootRecord?.forEach(record => {
|
|
164
|
-
const [type, ids] = record.split('=');
|
|
165
|
-
let idList = ids?.split(',').map(id => `#${keyLookup.get(`_${id}.${actualRootName}`)}`);
|
|
166
|
-
switch (type) {
|
|
167
|
-
case 'auth':
|
|
168
|
-
document.authentication = idList;
|
|
169
|
-
break;
|
|
170
|
-
case 'asm':
|
|
171
|
-
document.assertionMethod = idList;
|
|
172
|
-
break;
|
|
173
|
-
case 'agm':
|
|
174
|
-
document.keyAgreement = idList;
|
|
175
|
-
break;
|
|
176
|
-
case 'inv':
|
|
177
|
-
document.capabilityInvocation = idList;
|
|
178
|
-
break;
|
|
179
|
-
case 'del':
|
|
180
|
-
document.capabilityDelegation = idList;
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return document as DidDocument;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Retrieves a DID Document from the DHT.
|
|
190
|
-
*
|
|
191
|
-
* @param did The DID of the document to retrieve.
|
|
192
|
-
* @param relay The relay to use to retrieve the document; defaults to `PKARR_RELAY`.
|
|
193
|
-
* @returns A Promise that resolves to the retrieved DidDocument.
|
|
194
|
-
*/
|
|
195
|
-
public static async getDidDocument({ did, relay }: {
|
|
196
|
-
did: string,
|
|
197
|
-
relay?: string
|
|
198
|
-
}): Promise<DidDocument> {
|
|
199
|
-
ensureBufferBigIntMethods();
|
|
200
|
-
const relayUrl = relay ?? DidDht.getRelayUrl();
|
|
201
|
-
const didFragment = did.replace('did:dht:', '');
|
|
202
|
-
const publicKeyBytes = new Uint8Array(z32.decode(didFragment));
|
|
203
|
-
const resolved = await Pkarr.relayGet(relayUrl, publicKeyBytes);
|
|
204
|
-
if (resolved) {
|
|
205
|
-
return await DidDht.fromDnsPacket({ did, packet: resolved.packet() });
|
|
206
|
-
}
|
|
207
|
-
throw new Error('No packet found');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Publishes a DID Document to the DHT.
|
|
212
|
-
*
|
|
213
|
-
* @param keyPair The key pair to sign the document with.
|
|
214
|
-
* @param didDocument The DID Document to publish.
|
|
215
|
-
* @param relay The relay to use to retrieve the document; defaults to `PKARR_RELAY`.
|
|
216
|
-
* @returns A boolean indicating the success of the publishing operation.
|
|
217
|
-
*/
|
|
218
|
-
public static async publishDidDocument({ keyPair, didDocument, relay }: {
|
|
219
|
-
didDocument: DidDocument,
|
|
220
|
-
keyPair: IDCrypto.CryptoKeyPair,
|
|
221
|
-
relay?: string
|
|
222
|
-
}): Promise<boolean> {
|
|
223
|
-
ensureBufferBigIntMethods();
|
|
224
|
-
const relayUrl = relay ?? DidDht.getRelayUrl();
|
|
225
|
-
const packet = await DidDht.toDnsPacket({ didDocument });
|
|
226
|
-
const pkarrKeypair = {
|
|
227
|
-
publicKey : keyPair.publicKey.material,
|
|
228
|
-
secretKey : new Uint8Array([...keyPair.privateKey.material, ...keyPair.publicKey.material])
|
|
229
|
-
};
|
|
230
|
-
const signedPacket = SignedPacket.fromPacket(pkarrKeypair, packet);
|
|
231
|
-
const results = await Pkarr.relayPut(relayUrl, signedPacket);
|
|
232
|
-
|
|
233
|
-
return results.ok;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Converts a DID Document to a DNS packet according to the did:dht spec.
|
|
238
|
-
*
|
|
239
|
-
* @param didDocument The DID Document to convert.
|
|
240
|
-
* @returns A DNS packet converted from the DID Document.
|
|
241
|
-
*/
|
|
242
|
-
public static async toDnsPacket({ didDocument }: { didDocument: DidDocument }): Promise<Packet> {
|
|
243
|
-
const packet: Partial<Packet> = {
|
|
244
|
-
id : 0,
|
|
245
|
-
type : 'response',
|
|
246
|
-
flags : AUTHORITATIVE_ANSWER,
|
|
247
|
-
answers : []
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const vmIds: string[] = [];
|
|
251
|
-
const svcIds: string[] = [];
|
|
252
|
-
const rootRecord: string[] = [];
|
|
253
|
-
const keyLookup = new Map<string, string>();
|
|
254
|
-
|
|
255
|
-
// Add key records for each verification method
|
|
256
|
-
for (const vm of didDocument.verificationMethod) {
|
|
257
|
-
const index = didDocument.verificationMethod.indexOf(vm);
|
|
258
|
-
const recordIdentifier = `k${index}`;
|
|
259
|
-
let vmId = DidDht.identifierFragment({ identifier: vm.id });
|
|
260
|
-
keyLookup.set(vmId, recordIdentifier);
|
|
261
|
-
|
|
262
|
-
let keyType: number;
|
|
263
|
-
switch (vm.publicKeyJwk.alg) {
|
|
264
|
-
case 'EdDSA':
|
|
265
|
-
keyType = 0;
|
|
266
|
-
break;
|
|
267
|
-
case 'ES256K':
|
|
268
|
-
keyType = 1;
|
|
269
|
-
break;
|
|
270
|
-
default:
|
|
271
|
-
keyType = 0; // Default value or throw an error if needed
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// DID document JWKs intentionally omit WebCrypto-only fields such as
|
|
275
|
-
// `ext` and `key_ops`, so decode key bytes directly from JWK.
|
|
276
|
-
const { keyMaterial } = await Jose.jwkToKey({ key: vm.publicKeyJwk });
|
|
277
|
-
const keyBase64Url = Convert.uint8Array(keyMaterial).toBase64Url();
|
|
278
|
-
|
|
279
|
-
const keyRecord: TxtAnswer = {
|
|
280
|
-
type : 'TXT',
|
|
281
|
-
name : `_${recordIdentifier}._did`,
|
|
282
|
-
ttl : TTL,
|
|
283
|
-
data : `id=${vmId},t=${keyType},k=${keyBase64Url}`
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
packet.answers.push(keyRecord);
|
|
287
|
-
vmIds.push(recordIdentifier);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Add service records
|
|
291
|
-
didDocument.service?.forEach((service, index) => {
|
|
292
|
-
const recordIdentifier = `s${index}`;
|
|
293
|
-
let sId = DidDht.identifierFragment({ identifier: service.id });
|
|
294
|
-
const encodedServiceEndpoint = DidDht.encodeServiceEndpoint({ serviceEndpoint: service.serviceEndpoint });
|
|
295
|
-
const serviceRecord: TxtAnswer = {
|
|
296
|
-
type : 'TXT',
|
|
297
|
-
name : `_${recordIdentifier}._did`,
|
|
298
|
-
ttl : TTL,
|
|
299
|
-
data : `id=${sId},t=${service.type},uri=${encodedServiceEndpoint}`
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
packet.answers.push(serviceRecord);
|
|
303
|
-
svcIds.push(recordIdentifier);
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
// add root record for vms and svcs
|
|
307
|
-
if (vmIds.length) {
|
|
308
|
-
rootRecord.push(`vm=${vmIds.join(',')}`);
|
|
309
|
-
}
|
|
310
|
-
if (svcIds.length) {
|
|
311
|
-
rootRecord.push(`svc=${svcIds.join(',')}`);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// add verification relationships
|
|
315
|
-
if (didDocument.authentication) {
|
|
316
|
-
const authIds: string[] = didDocument.authentication
|
|
317
|
-
.map(id => DidDht.identifierFragment({ identifier: id }))
|
|
318
|
-
.filter(id => keyLookup.has(id))
|
|
319
|
-
.map(id => keyLookup.get(id) as string);
|
|
320
|
-
if (authIds.length) {
|
|
321
|
-
rootRecord.push(`auth=${authIds.join(',')}`);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (didDocument.assertionMethod) {
|
|
325
|
-
const authIds: string[] = didDocument.assertionMethod
|
|
326
|
-
.map(id => DidDht.identifierFragment({ identifier: id }))
|
|
327
|
-
.filter(id => keyLookup.has(id))
|
|
328
|
-
.map(id => keyLookup.get(id) as string);
|
|
329
|
-
if (authIds.length) {
|
|
330
|
-
rootRecord.push(`asm=${authIds.join(',')}`);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
if (didDocument.keyAgreement) {
|
|
334
|
-
const authIds: string[] = didDocument.keyAgreement
|
|
335
|
-
.map(id => DidDht.identifierFragment({ identifier: id }))
|
|
336
|
-
.filter(id => keyLookup.has(id))
|
|
337
|
-
.map(id => keyLookup.get(id) as string);
|
|
338
|
-
if (authIds.length) {
|
|
339
|
-
rootRecord.push(`agm=${authIds.join(',')}`);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
if (didDocument.capabilityInvocation) {
|
|
343
|
-
const authIds: string[] = didDocument.capabilityInvocation
|
|
344
|
-
.map(id => DidDht.identifierFragment({ identifier: id }))
|
|
345
|
-
.filter(id => keyLookup.has(id))
|
|
346
|
-
.map(id => keyLookup.get(id) as string);
|
|
347
|
-
if (authIds.length) {
|
|
348
|
-
rootRecord.push(`inv=${authIds.join(',')}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
if (didDocument.capabilityDelegation) {
|
|
352
|
-
const authIds: string[] = didDocument.capabilityDelegation
|
|
353
|
-
.map(id => DidDht.identifierFragment({ identifier: id }))
|
|
354
|
-
.filter(id => keyLookup.has(id))
|
|
355
|
-
.map(id => keyLookup.get(id) as string);
|
|
356
|
-
if (authIds.length) {
|
|
357
|
-
rootRecord.push(`del=${authIds.join(',')}`);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// Add root record
|
|
362
|
-
packet.answers.push({
|
|
363
|
-
type : 'TXT',
|
|
364
|
-
name : '_did',
|
|
365
|
-
ttl : TTL,
|
|
366
|
-
data : rootRecord.join(';')
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
return packet as Packet;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Extracts the fragment from a DID.
|
|
374
|
-
*
|
|
375
|
-
* @param identifier The DID to extract the fragment from.
|
|
376
|
-
* @returns The fragment from the DID or the complete DID if no fragment exists.
|
|
377
|
-
*/
|
|
378
|
-
private static identifierFragment({ identifier }: { identifier: string }): string {
|
|
379
|
-
return identifier.includes('#') ? identifier.substring(identifier.indexOf('#') + 1) : identifier;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Parses TXT data from a DNS answer to extract key or service information.
|
|
384
|
-
*
|
|
385
|
-
* @param data The TXT record string data containing key-value pairs separated by commas.
|
|
386
|
-
* @returns An object containing parsed attributes such as 'id', 't', 'k', and 'uri'.
|
|
387
|
-
*/
|
|
388
|
-
private static parseTxtData({ data }: { data: string }): { [key: string]: string } {
|
|
389
|
-
return data.split(',').reduce((acc, pair) => {
|
|
390
|
-
const [key, value] = pair.split('=');
|
|
391
|
-
acc[key] = value;
|
|
392
|
-
return acc;
|
|
393
|
-
}, {} as { [key: string]: string });
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
private static encodeServiceEndpoint({ serviceEndpoint }: { serviceEndpoint: unknown }): string {
|
|
397
|
-
return Convert.object({ serviceEndpoint }).toBase64Url();
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
private static decodeServiceEndpoint({ encoded }: { encoded: string }): unknown {
|
|
401
|
-
try {
|
|
402
|
-
const decoded = Convert.base64Url(encoded).toObject() as { serviceEndpoint?: unknown };
|
|
403
|
-
if (decoded && 'serviceEndpoint' in decoded) {
|
|
404
|
-
return decoded.serviceEndpoint;
|
|
405
|
-
}
|
|
406
|
-
} catch {
|
|
407
|
-
// Backward compatibility for pre-encoded records.
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
return encoded;
|
|
411
|
-
}
|
|
412
|
-
}
|