@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/agent/rpc-client.ts
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import type { JsonRpcResponse } from './json-rpc.js';
|
|
2
|
-
import type { SerializableDwnMessage } from './types/agent.js';
|
|
3
|
-
|
|
4
|
-
import * as cryptoUtils from '../crypto/utils.js';
|
|
5
|
-
import { RecordsReadReply, UnionMessageReply } from '@dwn-protocol/id';
|
|
6
|
-
import { createJsonRpcRequest, parseJson } from './json-rpc.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Interface that can be implemented to communicate with {@link IDAgent | ID Agent}
|
|
10
|
-
* implementations via JSON-RPC.
|
|
11
|
-
*/
|
|
12
|
-
export interface DidRpc {
|
|
13
|
-
get transportProtocols(): string[]
|
|
14
|
-
sendDidRequest(request: DidRpcRequest): Promise<DidRpcResponse>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export enum DidRpcMethod {
|
|
18
|
-
Create = 'did.create',
|
|
19
|
-
Resolve = 'did.resolve'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type DidRpcRequest = {
|
|
23
|
-
data: string;
|
|
24
|
-
method: DidRpcMethod;
|
|
25
|
-
url: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type DidRpcResponse = {
|
|
29
|
-
data?: string;
|
|
30
|
-
ok: boolean;
|
|
31
|
-
status: RpcStatus;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* interface that can be implemented to communicate with Dwn Relayers
|
|
36
|
-
*/
|
|
37
|
-
export interface DwnRpc {
|
|
38
|
-
/**
|
|
39
|
-
* TODO: add jsdoc
|
|
40
|
-
*/
|
|
41
|
-
get transportProtocols(): string[]
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* TODO: add jsdoc
|
|
45
|
-
* @param request
|
|
46
|
-
*/
|
|
47
|
-
sendDwnRequest(request: DwnRpcRequest): Promise<DwnRpcResponse>
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* TODO: add jsdoc
|
|
52
|
-
*/
|
|
53
|
-
export type DwnRpcRequest = {
|
|
54
|
-
data?: any;
|
|
55
|
-
dwnUrl: string;
|
|
56
|
-
message: SerializableDwnMessage | any;
|
|
57
|
-
targetDid: string;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* TODO: add jsdoc
|
|
62
|
-
*/
|
|
63
|
-
export type DwnRpcResponse = UnionMessageReply & RecordsReadReply;
|
|
64
|
-
|
|
65
|
-
export type RpcStatus = {
|
|
66
|
-
code: number;
|
|
67
|
-
message: string;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export interface IDRpc extends DwnRpc, DidRpc {}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Client used to communicate with Dwn Servers
|
|
74
|
-
*/
|
|
75
|
-
export class IDRpcClient implements IDRpc {
|
|
76
|
-
private transportClients: Map<string, IDRpc>;
|
|
77
|
-
|
|
78
|
-
constructor(clients: IDRpc[] = []) {
|
|
79
|
-
this.transportClients = new Map();
|
|
80
|
-
|
|
81
|
-
// include http client as default. can be overwritten for 'http:' or 'https:' if instantiator provides
|
|
82
|
-
// their own.
|
|
83
|
-
clients = [new HttpIDRpcClient(), ...clients];
|
|
84
|
-
|
|
85
|
-
for (let client of clients) {
|
|
86
|
-
for (let transportScheme of client.transportProtocols) {
|
|
87
|
-
this.transportClients.set(transportScheme, client);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
get transportProtocols(): string[] {
|
|
93
|
-
return Array.from(this.transportClients.keys());
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async sendDidRequest(request: DidRpcRequest): Promise<DidRpcResponse> {
|
|
97
|
-
// URL() will throw if provided `url` is invalid.
|
|
98
|
-
const url = new URL(request.url);
|
|
99
|
-
|
|
100
|
-
const transportClient = this.transportClients.get(url.protocol);
|
|
101
|
-
if (!transportClient) {
|
|
102
|
-
const error = new Error(`no ${url.protocol} transport client available`);
|
|
103
|
-
error.name = 'NO_TRANSPORT_CLIENT';
|
|
104
|
-
|
|
105
|
-
throw error;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return transportClient.sendDidRequest(request);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
sendDwnRequest(request: DwnRpcRequest): Promise<DwnRpcResponse> {
|
|
112
|
-
// will throw if url is invalid
|
|
113
|
-
const url = new URL(request.dwnUrl);
|
|
114
|
-
|
|
115
|
-
const transportClient = this.transportClients.get(url.protocol);
|
|
116
|
-
if (!transportClient) {
|
|
117
|
-
const error = new Error(`no ${url.protocol} transport client available`);
|
|
118
|
-
error.name = 'NO_TRANSPORT_CLIENT';
|
|
119
|
-
|
|
120
|
-
throw error;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return transportClient.sendDwnRequest(request);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Http client that can be used to communicate with Dwn Servers
|
|
129
|
-
*/
|
|
130
|
-
class HttpDwnRpcClient implements DwnRpc {
|
|
131
|
-
get transportProtocols() { return ['http:', 'https:']; }
|
|
132
|
-
|
|
133
|
-
async sendDwnRequest(request: DwnRpcRequest): Promise<DwnRpcResponse> {
|
|
134
|
-
const requestId = cryptoUtils.randomUuid();
|
|
135
|
-
const jsonRpcRequest = createJsonRpcRequest(requestId, 'dwn.processMessage', {
|
|
136
|
-
target : request.targetDid,
|
|
137
|
-
message : request.message
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const fetchOpts = {
|
|
141
|
-
method : 'POST',
|
|
142
|
-
headers : {
|
|
143
|
-
'dwn-request': JSON.stringify(jsonRpcRequest)
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
if (request.data) {
|
|
148
|
-
fetchOpts.headers['content-type'] = 'application/octet-stream';
|
|
149
|
-
fetchOpts['body'] = request.data;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const resp = await fetch(request.dwnUrl, fetchOpts);
|
|
153
|
-
let dwnRpcResponse: JsonRpcResponse;
|
|
154
|
-
|
|
155
|
-
// check to see if response is in header first. if it is, that means the response is a ReadableStream
|
|
156
|
-
let dataStream;
|
|
157
|
-
const { headers } = resp;
|
|
158
|
-
if (headers.has('dwn-response')) {
|
|
159
|
-
const jsonRpcResponse = parseJson(headers.get('dwn-response')) as JsonRpcResponse;
|
|
160
|
-
|
|
161
|
-
if (jsonRpcResponse == null) {
|
|
162
|
-
throw new Error(`failed to parse json rpc response. dwn url: ${request.dwnUrl}`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
dataStream = resp.body;
|
|
166
|
-
dwnRpcResponse = jsonRpcResponse;
|
|
167
|
-
} else {
|
|
168
|
-
const responseBody = await resp.text();
|
|
169
|
-
dwnRpcResponse = JSON.parse(responseBody);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (dwnRpcResponse.error) {
|
|
173
|
-
const { code, message } = dwnRpcResponse.error;
|
|
174
|
-
throw new Error(`(${code}) - ${message}`);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const { reply } = dwnRpcResponse.result;
|
|
178
|
-
if (dataStream) {
|
|
179
|
-
reply['record']['data'] = dataStream;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return reply as DwnRpcResponse;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
class HttpIDRpcClient extends HttpDwnRpcClient implements IDRpc {
|
|
187
|
-
async sendDidRequest(request: DidRpcRequest): Promise<DidRpcResponse> {
|
|
188
|
-
const requestId = cryptoUtils.randomUuid();
|
|
189
|
-
const jsonRpcRequest = createJsonRpcRequest(requestId, request.method, {
|
|
190
|
-
data: request.data
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
const httpRequest = new Request(request.url, {
|
|
194
|
-
method : 'POST',
|
|
195
|
-
headers : {
|
|
196
|
-
'Content-Type': 'application/json',
|
|
197
|
-
},
|
|
198
|
-
body: JSON.stringify(jsonRpcRequest),
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
let jsonRpcResponse: JsonRpcResponse;
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const response = await fetch(httpRequest);
|
|
205
|
-
|
|
206
|
-
if (response.ok) {
|
|
207
|
-
jsonRpcResponse = await response.json();
|
|
208
|
-
|
|
209
|
-
// If the response is an error, throw an error.
|
|
210
|
-
if (jsonRpcResponse.error) {
|
|
211
|
-
const { code, message } = jsonRpcResponse.error;
|
|
212
|
-
throw new Error(`JSON RPC (${code}) - ${message}`);
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
throw new Error(`HTTP (${response.status}) - ${response.statusText}`);
|
|
216
|
-
}
|
|
217
|
-
} catch (error: any) {
|
|
218
|
-
throw new Error(`Error encountered while processing response from ${request.url}: ${error.message}`);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return jsonRpcResponse.result as DidRpcResponse;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
//@ts-nocheck
|
|
2
|
-
import type { RecordsWriteMessage } from '@dwn-protocol/id';
|
|
3
|
-
|
|
4
|
-
import { Convert } from '../common/index.js';
|
|
5
|
-
|
|
6
|
-
import type { IDManagedAgent } from './types/agent.js';
|
|
7
|
-
import type { ManagedDid } from './did-manager.js';
|
|
8
|
-
|
|
9
|
-
export interface ManagedDidStore {
|
|
10
|
-
deleteDid(options: { did: string, agent?: IDManagedAgent, context?: string }): Promise<boolean>
|
|
11
|
-
getDid(options: { did: string, agent?: IDManagedAgent, context?: string }): Promise<ManagedDid | undefined>
|
|
12
|
-
findDid(options: { did: string, agent?: IDManagedAgent, context?: string }): Promise<ManagedDid | undefined>
|
|
13
|
-
findDid(options: { alias: string, agent?: IDManagedAgent, context?: string }): Promise<ManagedDid | undefined>
|
|
14
|
-
importDid(options: { did: ManagedDid, agent?: IDManagedAgent, context?: string }): Promise<void>
|
|
15
|
-
listDids(options?: { agent?: IDManagedAgent, context?: string }): Promise<ManagedDid[]>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
export class DidStoreDwn implements ManagedDidStore {
|
|
22
|
-
private _didRecordProperties = {
|
|
23
|
-
dataFormat : 'application/json',
|
|
24
|
-
schema : 'https://abaxx.tech/schemas/dwn/managed-did'
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
async deleteDid(options: {
|
|
28
|
-
agent: IDManagedAgent,
|
|
29
|
-
context?: string,
|
|
30
|
-
did: string
|
|
31
|
-
}): Promise<boolean> {
|
|
32
|
-
const { agent, context, did } = options;
|
|
33
|
-
|
|
34
|
-
// Determine which DID to use to author DWN messages.
|
|
35
|
-
const authorDid = await this.getAuthor({ agent, context, did });
|
|
36
|
-
|
|
37
|
-
// Query the DWN for all stored DID objects.
|
|
38
|
-
const { reply: queryReply} = await agent.dwnManager.processRequest({
|
|
39
|
-
author : authorDid,
|
|
40
|
-
target : authorDid,
|
|
41
|
-
messageType : 'RecordsQuery',
|
|
42
|
-
messageOptions : {
|
|
43
|
-
filter: { ...this._didRecordProperties }
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Loop through all of the entries and try to find a match.
|
|
48
|
-
let matchingRecordId: string | undefined;
|
|
49
|
-
for (const record of queryReply.entries ?? []) {
|
|
50
|
-
if (record.encodedData) {
|
|
51
|
-
const storedDid = Convert.base64Url(record.encodedData).toObject() as ManagedDid;
|
|
52
|
-
if (storedDid && storedDid.did === did) {
|
|
53
|
-
matchingRecordId = (record as RecordsWriteMessage).recordId ;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Return undefined if the specified DID was not found in the store.
|
|
60
|
-
if (!matchingRecordId) return false;
|
|
61
|
-
|
|
62
|
-
// If a record for the specified DID was found, attempt to delete it.
|
|
63
|
-
const { reply: { status } } = await agent.dwnManager.processRequest({
|
|
64
|
-
author : authorDid,
|
|
65
|
-
target : authorDid,
|
|
66
|
-
messageType : 'RecordsDelete',
|
|
67
|
-
messageOptions : {
|
|
68
|
-
recordId: matchingRecordId
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// If the DID was successfully deleted, return true;
|
|
73
|
-
if (status.code === 202) return true;
|
|
74
|
-
|
|
75
|
-
// If the DID could not be deleted, return false;
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async findDid(options: { agent: IDManagedAgent, context?: string, did: string }): Promise<ManagedDid | undefined>;
|
|
80
|
-
async findDid(options: { agent: IDManagedAgent, context?: string, alias: string }): Promise<ManagedDid | undefined>;
|
|
81
|
-
async findDid(options: { agent: IDManagedAgent, alias: string, context?: string, did: string }): Promise<ManagedDid | undefined> {
|
|
82
|
-
const { agent, alias, context, did } = options;
|
|
83
|
-
|
|
84
|
-
// Determine which DID to use to author DWN messages.
|
|
85
|
-
const authorDid = await this.getAuthor({ agent, context, did });
|
|
86
|
-
|
|
87
|
-
// Query the DWN for all stored DID objects.
|
|
88
|
-
const { reply: queryReply} = await agent.dwnManager.processRequest({
|
|
89
|
-
author : authorDid,
|
|
90
|
-
target : authorDid,
|
|
91
|
-
messageType : 'RecordsQuery',
|
|
92
|
-
messageOptions : {
|
|
93
|
-
filter: { ...this._didRecordProperties }
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Loop through all of the entries and return a match, if found.
|
|
98
|
-
for (const record of queryReply.entries ?? []) {
|
|
99
|
-
if (record.encodedData) {
|
|
100
|
-
const storedDid = Convert.base64Url(record.encodedData).toObject() as ManagedDid;
|
|
101
|
-
if (storedDid && storedDid.did === did) return storedDid;
|
|
102
|
-
if (storedDid && storedDid.alias === alias) return storedDid;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Return undefined if no matches were found.
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async getDid(options: {
|
|
111
|
-
agent: IDManagedAgent,
|
|
112
|
-
context?: string,
|
|
113
|
-
did: string
|
|
114
|
-
}): Promise<ManagedDid | undefined> {
|
|
115
|
-
const { agent, context, did } = options;
|
|
116
|
-
|
|
117
|
-
// Determine which DID to use to author DWN messages.
|
|
118
|
-
const authorDid = await this.getAuthor({ agent, context, did });
|
|
119
|
-
|
|
120
|
-
// Query the DWN for all stored DID objects.
|
|
121
|
-
const { reply: queryReply} = await agent.dwnManager.processRequest({
|
|
122
|
-
author : authorDid,
|
|
123
|
-
target : authorDid,
|
|
124
|
-
messageType : 'RecordsQuery',
|
|
125
|
-
messageOptions : { filter: { ...this._didRecordProperties } }
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// Loop through all of the entries and return a match, if found.
|
|
129
|
-
for (const record of queryReply.entries ?? []) {
|
|
130
|
-
if (record.encodedData) {
|
|
131
|
-
const storedDid = Convert.base64Url(record.encodedData).toObject() as ManagedDid;
|
|
132
|
-
if (storedDid && storedDid.did === did) return storedDid;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Return undefined if no matches were found.
|
|
137
|
-
return undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async importDid(options: {
|
|
141
|
-
agent: IDManagedAgent,
|
|
142
|
-
context?: string,
|
|
143
|
-
did: ManagedDid
|
|
144
|
-
}) {
|
|
145
|
-
const { agent, context, did: importDid } = options;
|
|
146
|
-
|
|
147
|
-
// Determine which DID to use to author DWN messages.
|
|
148
|
-
const authorDid = await this.getAuthor({ agent, context, did: importDid.did });
|
|
149
|
-
|
|
150
|
-
// Check if the DID being imported is already present in the store.
|
|
151
|
-
const duplicateFound = await this.getDid({ agent, context, did: importDid.did });
|
|
152
|
-
if (duplicateFound) {
|
|
153
|
-
throw new Error(`DidStoreDwn: DID with ID already exists: '${importDid.did}'`);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Encode the ManagedDid as bytes.
|
|
157
|
-
const importDidU8A = Convert.object(importDid).toUint8Array();
|
|
158
|
-
|
|
159
|
-
const { reply: { status } } = await agent.dwnManager.processRequest({
|
|
160
|
-
author : authorDid,
|
|
161
|
-
target : authorDid,
|
|
162
|
-
messageType : 'RecordsWrite',
|
|
163
|
-
messageOptions : { ...this._didRecordProperties },
|
|
164
|
-
dataStream : new Blob([importDidU8A])
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// If the write fails, throw an error.
|
|
168
|
-
if (status.code !== 202) {
|
|
169
|
-
throw new Error('DidStoreDwn: Failed to write imported DID to store.');
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async listDids(options: {
|
|
174
|
-
agent: IDManagedAgent,
|
|
175
|
-
context?: string
|
|
176
|
-
}): Promise<ManagedDid[]> {
|
|
177
|
-
const { agent, context } = options;
|
|
178
|
-
|
|
179
|
-
// Determine which DID to use to author DWN messages.
|
|
180
|
-
const authorDid = await this.getAuthor({ agent, context });
|
|
181
|
-
|
|
182
|
-
// Query the DWN for all stored DID objects.
|
|
183
|
-
const { reply: queryReply} = await agent.dwnManager.processRequest({
|
|
184
|
-
author : authorDid,
|
|
185
|
-
target : authorDid,
|
|
186
|
-
messageType : 'RecordsQuery',
|
|
187
|
-
messageOptions : {
|
|
188
|
-
filter: { ...this._didRecordProperties }
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// Loop through all of the entries and accumulate the DID objects.
|
|
193
|
-
let storedDids: ManagedDid[] = [];
|
|
194
|
-
for (const record of queryReply.entries ?? []) {
|
|
195
|
-
if (record.encodedData) {
|
|
196
|
-
const storedDid = Convert.base64Url(record.encodedData).toObject() as ManagedDid;
|
|
197
|
-
storedDids.push(storedDid);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return storedDids;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private async getAuthor(options: {
|
|
205
|
-
context?: string,
|
|
206
|
-
did?: string,
|
|
207
|
-
agent: IDManagedAgent
|
|
208
|
-
}): Promise<string> {
|
|
209
|
-
const { context, did, agent } = options;
|
|
210
|
-
|
|
211
|
-
// If `context` is specified, DWN messages will be signed by this DID.
|
|
212
|
-
if (context) return context;
|
|
213
|
-
|
|
214
|
-
// If Agent has an agentDid, use it to sign DWN messages.
|
|
215
|
-
if (agent.agentDid) return agent.agentDid;
|
|
216
|
-
|
|
217
|
-
// If `context`, `agent.agentDid`, and `did` are undefined, throw error.
|
|
218
|
-
if (!did) {
|
|
219
|
-
throw new Error(`DidStoreDwn: Agent property 'agentDid' is undefined.`);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/** Lacking a context and agentDid DID, check whether KeyManager has
|
|
223
|
-
* a key pair for the given `did` value.*/
|
|
224
|
-
const signingKeyId = await agent.didManager.getDefaultSigningKey({ did });
|
|
225
|
-
const keyPair = (signingKeyId)
|
|
226
|
-
? await agent.keyManager.getKey({ keyRef: signingKeyId })
|
|
227
|
-
: undefined;
|
|
228
|
-
|
|
229
|
-
// If a key pair is found, use the `did` to sign messages.
|
|
230
|
-
if (keyPair) return did;
|
|
231
|
-
|
|
232
|
-
// If all else fails, throw an error.
|
|
233
|
-
throw new Error(`DidStoreDwn: Agent property 'agentDid' is undefined and no keys were found for: '${did}'`);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
*
|
|
239
|
-
*/
|
|
240
|
-
export class DidStoreMemory implements ManagedDidStore {
|
|
241
|
-
/**
|
|
242
|
-
* A private field that contains the Map used as the in-memory key-value store.
|
|
243
|
-
*/
|
|
244
|
-
private store: Map<string, ManagedDid> = new Map();
|
|
245
|
-
|
|
246
|
-
async deleteDid({ did }: { did: string; }): Promise<boolean> {
|
|
247
|
-
if (this.store.has(did)) {
|
|
248
|
-
// DID with given identifier exists so proceed with delete.
|
|
249
|
-
this.store.delete(did);
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// DID with given identifier not present so delete operation not possible.
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async getDid({ did }: { did: string; }): Promise<ManagedDid | undefined> {
|
|
258
|
-
return this.store.get(did);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
async findDid(options: { did: string }): Promise<ManagedDid | undefined>;
|
|
262
|
-
async findDid(options: { alias: string }): Promise<ManagedDid | undefined>;
|
|
263
|
-
async findDid(options: { alias?: string, did?: string}): Promise<ManagedDid | undefined> {
|
|
264
|
-
let { alias, did } = options;
|
|
265
|
-
|
|
266
|
-
// Get DID by identifier.
|
|
267
|
-
if (did) return this.store.get(did);
|
|
268
|
-
|
|
269
|
-
if (alias) {
|
|
270
|
-
// Search through the store to find a matching entry
|
|
271
|
-
for (const did of this.store.values()) {
|
|
272
|
-
if (did.alias === alias) return did;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return undefined;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async importDid(options: { did: ManagedDid }) {
|
|
280
|
-
const { did: importDid } = options;
|
|
281
|
-
|
|
282
|
-
if (this.store.has(importDid.did)) {
|
|
283
|
-
// DID with given identifier already exists so import operation cannot proceed.
|
|
284
|
-
throw new Error(`DidStoreMemory: DID with ID already exists: '${importDid.did}'`);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Make a deep copy of the DID so that the object stored does not share the same references as the input.
|
|
288
|
-
const clonedDid = structuredClone(importDid);
|
|
289
|
-
this.store.set(importDid.did, clonedDid);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async listDids(): Promise<ManagedDid[]> {
|
|
293
|
-
return Array.from(this.store.values());
|
|
294
|
-
}
|
|
295
|
-
}
|