@enbox/agent 0.1.8 → 0.1.9
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/browser.mjs +11 -11
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/anonymous-dwn-api.js +1 -1
- package/dist/esm/anonymous-dwn-api.js.map +1 -1
- package/dist/esm/connect.js +2 -9
- package/dist/esm/connect.js.map +1 -1
- package/dist/esm/dwn-api.js +144 -195
- package/dist/esm/dwn-api.js.map +1 -1
- package/dist/esm/dwn-protocol-cache.js +149 -0
- package/dist/esm/dwn-protocol-cache.js.map +1 -0
- package/dist/esm/dwn-record-upgrade.js +3 -3
- package/dist/esm/dwn-record-upgrade.js.map +1 -1
- package/dist/esm/hd-identity-vault.js +0 -2
- package/dist/esm/hd-identity-vault.js.map +1 -1
- package/dist/esm/identity-api.js +0 -2
- package/dist/esm/identity-api.js.map +1 -1
- package/dist/esm/permissions-api.js +24 -6
- package/dist/esm/permissions-api.js.map +1 -1
- package/dist/esm/store-data-protocols.js +2 -2
- package/dist/esm/store-data-protocols.js.map +1 -1
- package/dist/esm/test-harness.js +3 -5
- package/dist/esm/test-harness.js.map +1 -1
- package/dist/esm/types/dwn.js.map +1 -1
- package/dist/types/anonymous-dwn-api.d.ts +3 -3
- package/dist/types/anonymous-dwn-api.d.ts.map +1 -1
- package/dist/types/connect.d.ts.map +1 -1
- package/dist/types/dwn-api.d.ts +11 -18
- package/dist/types/dwn-api.d.ts.map +1 -1
- package/dist/types/dwn-protocol-cache.d.ts +76 -0
- package/dist/types/dwn-protocol-cache.d.ts.map +1 -0
- package/dist/types/hd-identity-vault.d.ts.map +1 -1
- package/dist/types/identity-api.d.ts.map +1 -1
- package/dist/types/permissions-api.d.ts.map +1 -1
- package/dist/types/test-harness.d.ts.map +1 -1
- package/dist/types/types/dwn.d.ts +18 -19
- package/dist/types/types/dwn.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/anonymous-dwn-api.ts +4 -4
- package/src/connect.ts +2 -9
- package/src/dwn-api.ts +192 -250
- package/src/dwn-protocol-cache.ts +216 -0
- package/src/dwn-record-upgrade.ts +3 -3
- package/src/hd-identity-vault.ts +0 -2
- package/src/identity-api.ts +0 -2
- package/src/permissions-api.ts +28 -6
- package/src/store-data-protocols.ts +2 -2
- package/src/test-harness.ts +3 -5
- package/src/types/dwn.ts +19 -21
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol definition fetching and caching utilities for {@link AgentDwnApi}.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `dwn-api.ts` to keep protocol-resolution logic in its own
|
|
5
|
+
* module.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { DidUrlDereferencer } from '@enbox/dids';
|
|
11
|
+
import type { PublicKeyJwk } from '@enbox/crypto';
|
|
12
|
+
import type { TtlCache } from '@enbox/common';
|
|
13
|
+
import type {
|
|
14
|
+
ProtocolDefinition,
|
|
15
|
+
ProtocolsQueryReply,
|
|
16
|
+
RecordsQueryReply,
|
|
17
|
+
} from '@enbox/dwn-sdk-js';
|
|
18
|
+
|
|
19
|
+
import type {
|
|
20
|
+
DwnInterface,
|
|
21
|
+
DwnMessage,
|
|
22
|
+
DwnMessageReply,
|
|
23
|
+
DwnSigner,
|
|
24
|
+
MessageHandler,
|
|
25
|
+
} from './types/dwn.js';
|
|
26
|
+
|
|
27
|
+
import { KeyDerivationScheme } from '@enbox/dwn-sdk-js';
|
|
28
|
+
|
|
29
|
+
import { getDwnServiceEndpointUrls } from './utils.js';
|
|
30
|
+
import { DwnInterface as DwnInterfaceEnum, dwnMessageConstructors } from './types/dwn.js';
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Dependency signatures — keep the extracted code free of `this` references.
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/** Callback to obtain a DWN signer for a given DID. */
|
|
37
|
+
type GetSignerFn = (author: string) => Promise<DwnSigner>;
|
|
38
|
+
|
|
39
|
+
/** Callback to send a raw DWN request to a remote endpoint. */
|
|
40
|
+
type SendDwnRpcRequestFn = <T extends DwnInterface>(params: {
|
|
41
|
+
targetDid: string;
|
|
42
|
+
dwnEndpointUrls: string[];
|
|
43
|
+
message: DwnMessage[T];
|
|
44
|
+
data?: Blob;
|
|
45
|
+
subscriptionHandler?: MessageHandler[T];
|
|
46
|
+
}) => Promise<DwnMessageReply[T]>;
|
|
47
|
+
|
|
48
|
+
/** Minimal DWN interface needed for local `processMessage` calls. */
|
|
49
|
+
interface DwnNode {
|
|
50
|
+
processMessage(tenant: string, message: unknown, options?: unknown): Promise<any>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Exported functions
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fetches a protocol definition from the **local** DWN, backed by a TTL cache.
|
|
59
|
+
*
|
|
60
|
+
* @param tenantDid - The DID whose DWN to query
|
|
61
|
+
* @param protocolUri - The protocol URI to look up
|
|
62
|
+
* @param dwn - The local DWN instance
|
|
63
|
+
* @param getSigner - Callback to obtain the signer for `tenantDid`
|
|
64
|
+
* @param cache - The shared protocol definition cache
|
|
65
|
+
* @returns The protocol definition, or `undefined` if not installed
|
|
66
|
+
*/
|
|
67
|
+
export async function getProtocolDefinition(
|
|
68
|
+
tenantDid: string,
|
|
69
|
+
protocolUri: string,
|
|
70
|
+
dwn: DwnNode,
|
|
71
|
+
getSigner: GetSignerFn,
|
|
72
|
+
cache: TtlCache<string, ProtocolDefinition>,
|
|
73
|
+
): Promise<ProtocolDefinition | undefined> {
|
|
74
|
+
const cacheKey = `${tenantDid}~${protocolUri}`;
|
|
75
|
+
|
|
76
|
+
const cached = cache.get(cacheKey);
|
|
77
|
+
if (cached) {
|
|
78
|
+
return cached;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const signer = await getSigner(tenantDid);
|
|
82
|
+
const protocolsQuery = await dwnMessageConstructors[
|
|
83
|
+
DwnInterfaceEnum.ProtocolsQuery
|
|
84
|
+
].create({
|
|
85
|
+
filter: { protocol: protocolUri },
|
|
86
|
+
signer,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const reply = await dwn.processMessage(
|
|
90
|
+
tenantDid, protocolsQuery.message,
|
|
91
|
+
);
|
|
92
|
+
if (reply.status.code !== 200 || !reply.entries?.length) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const definition = reply.entries[0].descriptor.definition;
|
|
97
|
+
cache.set(cacheKey, definition);
|
|
98
|
+
return definition;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Fetches a protocol definition from a **remote** DWN.
|
|
103
|
+
*
|
|
104
|
+
* Uses an unsigned `ProtocolsQuery` since public protocols can be queried
|
|
105
|
+
* anonymously.
|
|
106
|
+
*
|
|
107
|
+
* @param targetDid - The remote DWN owner
|
|
108
|
+
* @param protocolUri - The protocol URI to look up
|
|
109
|
+
* @param didDereferencer - A DID URL dereferencer for resolving service endpoints
|
|
110
|
+
* @param sendDwnRpcRequest - Callback to send the RPC query
|
|
111
|
+
* @param cache - The shared protocol definition cache
|
|
112
|
+
* @returns The protocol definition
|
|
113
|
+
* @throws If the protocol cannot be fetched
|
|
114
|
+
*/
|
|
115
|
+
export async function fetchRemoteProtocolDefinition(
|
|
116
|
+
targetDid: string,
|
|
117
|
+
protocolUri: string,
|
|
118
|
+
didDereferencer: DidUrlDereferencer,
|
|
119
|
+
sendDwnRpcRequest: SendDwnRpcRequestFn,
|
|
120
|
+
cache: TtlCache<string, ProtocolDefinition>,
|
|
121
|
+
): Promise<ProtocolDefinition> {
|
|
122
|
+
const cacheKey = `remote~${targetDid}~${protocolUri}`;
|
|
123
|
+
const cached = cache.get(cacheKey);
|
|
124
|
+
if (cached) { return cached; }
|
|
125
|
+
|
|
126
|
+
const protocolsQuery = await dwnMessageConstructors[
|
|
127
|
+
DwnInterfaceEnum.ProtocolsQuery
|
|
128
|
+
].create({
|
|
129
|
+
filter: { protocol: protocolUri },
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const reply = await sendDwnRpcRequest({
|
|
133
|
+
targetDid,
|
|
134
|
+
dwnEndpointUrls : await getDwnServiceEndpointUrls(targetDid, didDereferencer),
|
|
135
|
+
message : protocolsQuery.message,
|
|
136
|
+
}) as ProtocolsQueryReply;
|
|
137
|
+
|
|
138
|
+
if (reply.status.code !== 200 || !reply.entries?.length) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`AgentDwnApi: Failed to fetch protocol '${protocolUri}' from ` +
|
|
141
|
+
`'${targetDid}'. The recipient may not have the protocol installed.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const definition = reply.entries[0].descriptor.definition;
|
|
146
|
+
cache.set(cacheKey, definition);
|
|
147
|
+
return definition;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Extracts the `derivedPublicKey` from an existing `ProtocolContext`-encrypted
|
|
152
|
+
* record in a context on a remote DWN.
|
|
153
|
+
*
|
|
154
|
+
* This key allows an external author to encrypt new records in the same
|
|
155
|
+
* context without knowing the context private key.
|
|
156
|
+
*
|
|
157
|
+
* @param targetDid - The DWN owner's DID
|
|
158
|
+
* @param protocolUri - The protocol URI to search
|
|
159
|
+
* @param rootContextId - The root context ID
|
|
160
|
+
* @param requesterDid - The DID of the requester (used for signing the query)
|
|
161
|
+
* @param didDereferencer - A DID URL dereferencer for resolving service endpoints
|
|
162
|
+
* @param getSigner - Callback to obtain the signer for `requesterDid`
|
|
163
|
+
* @param sendDwnRpcRequest - Callback to send the RPC query
|
|
164
|
+
* @returns The rootKeyId and derivedPublicKey, or `undefined` if no
|
|
165
|
+
* `ProtocolContext` record exists yet
|
|
166
|
+
*/
|
|
167
|
+
export async function extractDerivedPublicKey(
|
|
168
|
+
targetDid: string,
|
|
169
|
+
protocolUri: string,
|
|
170
|
+
rootContextId: string,
|
|
171
|
+
requesterDid: string,
|
|
172
|
+
didDereferencer: DidUrlDereferencer,
|
|
173
|
+
getSigner: GetSignerFn,
|
|
174
|
+
sendDwnRpcRequest: SendDwnRpcRequestFn,
|
|
175
|
+
): Promise<{ rootKeyId: string; derivedPublicKey: PublicKeyJwk } | undefined> {
|
|
176
|
+
const signer = await getSigner(requesterDid);
|
|
177
|
+
|
|
178
|
+
// Query the target's DWN for any record in this context
|
|
179
|
+
const recordsQuery = await dwnMessageConstructors[DwnInterfaceEnum.RecordsQuery].create({
|
|
180
|
+
signer,
|
|
181
|
+
filter: {
|
|
182
|
+
protocol : protocolUri,
|
|
183
|
+
contextId : rootContextId,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const dwnEndpointUrls = await getDwnServiceEndpointUrls(targetDid, didDereferencer);
|
|
188
|
+
const queryReply = await sendDwnRpcRequest<DwnInterfaceEnum.RecordsQuery>({
|
|
189
|
+
targetDid,
|
|
190
|
+
dwnEndpointUrls,
|
|
191
|
+
message: recordsQuery.message,
|
|
192
|
+
}) as RecordsQueryReply;
|
|
193
|
+
|
|
194
|
+
if (queryReply.status.code !== 200 || !queryReply.entries?.length) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Search entries for one with a ProtocolContext recipient entry
|
|
199
|
+
// that includes derivedPublicKey
|
|
200
|
+
for (const entry of queryReply.entries) {
|
|
201
|
+
if (entry.encryption?.recipients) {
|
|
202
|
+
const contextEntry = entry.encryption.recipients.find(
|
|
203
|
+
(r: { header: { derivationScheme: string; derivedPublicKey?: PublicKeyJwk } }) =>
|
|
204
|
+
r.header.derivationScheme === KeyDerivationScheme.ProtocolContext && r.header.derivedPublicKey
|
|
205
|
+
);
|
|
206
|
+
if (contextEntry?.header.derivedPublicKey) {
|
|
207
|
+
return {
|
|
208
|
+
rootKeyId : contextEntry.header.kid,
|
|
209
|
+
derivedPublicKey : contextEntry.header.derivedPublicKey,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
@@ -118,7 +118,7 @@ export async function upgradeExternalRootRecord(
|
|
|
118
118
|
// We must also update the state index and event stream to keep sync and
|
|
119
119
|
// real-time subscribers consistent — without this, the upgraded record
|
|
120
120
|
// would never propagate to remote DWNs or notify subscribers.
|
|
121
|
-
const { messageStore, stateIndex,
|
|
121
|
+
const { messageStore, stateIndex, eventLog } = dwn.storage;
|
|
122
122
|
|
|
123
123
|
// Validate the upgrade only changed encryption and authorization fields.
|
|
124
124
|
// The descriptor, recordId, contextId, and data must remain identical.
|
|
@@ -157,8 +157,8 @@ export async function upgradeExternalRootRecord(
|
|
|
157
157
|
await stateIndex.delete(tenantDid, [originalCid]);
|
|
158
158
|
|
|
159
159
|
// Notify real-time subscribers (mirrors handler behavior)
|
|
160
|
-
if (
|
|
161
|
-
|
|
160
|
+
if (eventLog !== undefined) {
|
|
161
|
+
await eventLog.emit(tenantDid, { message: upgradedMessage }, upgradedIndexes);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
// Cache context key info for subsequent writes in this context
|
package/src/hd-identity-vault.ts
CHANGED
package/src/identity-api.ts
CHANGED
|
@@ -254,8 +254,6 @@ export class AgentIdentityApi<TKeyManager extends AgentKeyManager = AgentKeyMana
|
|
|
254
254
|
id : 'dwn',
|
|
255
255
|
type : 'DecentralizedWebNode',
|
|
256
256
|
serviceEndpoint : endpoints,
|
|
257
|
-
enc : '#enc',
|
|
258
|
-
sig : '#sig'
|
|
259
257
|
};
|
|
260
258
|
|
|
261
259
|
// if no other services exist, create a new array with the DWN service
|
package/src/permissions-api.ts
CHANGED
|
@@ -114,7 +114,7 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
114
114
|
if (revokedGrantIds.has(entry.recordId)) {
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
|
-
const grant =
|
|
117
|
+
const grant = DwnPermissionGrant.parse(entry);
|
|
118
118
|
grants.push({ grant, message: entry });
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -193,7 +193,7 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
193
193
|
|
|
194
194
|
const requests: PermissionRequestEntry[] = [];
|
|
195
195
|
for (const entry of reply.entries! as DwnDataEncodedRecordsWriteMessage[]) {
|
|
196
|
-
const request =
|
|
196
|
+
const request = DwnPermissionRequest.parse(entry);
|
|
197
197
|
requests.push({ request, message: entry });
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -275,7 +275,7 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
275
275
|
encodedData: Convert.uint8Array(permissionsGrantBytes).toBase64Url()
|
|
276
276
|
};
|
|
277
277
|
|
|
278
|
-
const grant =
|
|
278
|
+
const grant = DwnPermissionGrant.parse(dataEncodedMessage);
|
|
279
279
|
|
|
280
280
|
return { grant, message: dataEncodedMessage };
|
|
281
281
|
}
|
|
@@ -321,7 +321,7 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
321
321
|
encodedData: Convert.uint8Array(permissionRequestBytes).toBase64Url()
|
|
322
322
|
};
|
|
323
323
|
|
|
324
|
-
const request =
|
|
324
|
+
const request = DwnPermissionRequest.parse(dataEncodedMessage);
|
|
325
325
|
|
|
326
326
|
return { request, message: dataEncodedMessage };
|
|
327
327
|
}
|
|
@@ -388,6 +388,11 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
388
388
|
grants: PermissionGrantEntry[],
|
|
389
389
|
delegated: boolean = false
|
|
390
390
|
): Promise<PermissionGrantEntry | undefined> {
|
|
391
|
+
// Two-pass matching: prefer exact scope matches over unified Messages.Read fallback.
|
|
392
|
+
// This ensures that if both a Messages.Sync grant and a Messages.Read grant exist,
|
|
393
|
+
// the specific Messages.Sync grant is returned for MessagesSync lookups.
|
|
394
|
+
let unifiedFallback: PermissionGrantEntry | undefined;
|
|
395
|
+
|
|
391
396
|
for (const entry of grants) {
|
|
392
397
|
const { grant, message } = entry;
|
|
393
398
|
if (delegated === true && grant.delegated !== true) {
|
|
@@ -396,9 +401,19 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
396
401
|
const { messageType, protocol, protocolPath, contextId } = messageParams;
|
|
397
402
|
|
|
398
403
|
if (this.matchScopeFromGrant(grantor, grantee, messageType, grant, protocol, protocolPath, contextId)) {
|
|
399
|
-
|
|
404
|
+
const scopeMessageType = grant.scope.interface + grant.scope.method;
|
|
405
|
+
// Exact match — return immediately
|
|
406
|
+
if (scopeMessageType === messageType) {
|
|
407
|
+
return { grant, message };
|
|
408
|
+
}
|
|
409
|
+
// Unified fallback match — hold for later in case an exact match is found
|
|
410
|
+
if (!unifiedFallback) {
|
|
411
|
+
unifiedFallback = { grant, message };
|
|
412
|
+
}
|
|
400
413
|
}
|
|
401
414
|
}
|
|
415
|
+
|
|
416
|
+
return unifiedFallback;
|
|
402
417
|
}
|
|
403
418
|
|
|
404
419
|
private static matchScopeFromGrant<T extends DwnInterface>(
|
|
@@ -417,7 +432,14 @@ export class AgentPermissionsApi implements PermissionsApi {
|
|
|
417
432
|
|
|
418
433
|
const scope = grant.scope;
|
|
419
434
|
const scopeMessageType = scope.interface + scope.method;
|
|
420
|
-
|
|
435
|
+
|
|
436
|
+
// Messages.Read is a unified scope that covers Messages.Read, Messages.Sync, and Messages.Subscribe.
|
|
437
|
+
// When looking for a MessagesSync or MessagesSubscribe grant, also accept a MessagesRead grant.
|
|
438
|
+
const isMessagesScopeMatch = scopeMessageType === messageType
|
|
439
|
+
|| (scopeMessageType === DwnInterface.MessagesRead
|
|
440
|
+
&& (messageType === DwnInterface.MessagesSync || messageType === DwnInterface.MessagesSubscribe));
|
|
441
|
+
|
|
442
|
+
if (isMessagesScopeMatch) {
|
|
421
443
|
if (isRecordsType(messageType)) {
|
|
422
444
|
const recordScope = scope as DwnRecordsPermissionScope;
|
|
423
445
|
if (recordScope.protocol !== protocol) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
|
|
2
2
|
|
|
3
3
|
export const IdentityProtocolDefinition: ProtocolDefinition = {
|
|
4
|
-
protocol : '
|
|
4
|
+
protocol : 'https://identity.foundation/protocols/web5/identity-store',
|
|
5
5
|
published : false,
|
|
6
6
|
types : {
|
|
7
7
|
portableDid: {
|
|
@@ -47,7 +47,7 @@ export const KeyDeliveryProtocolDefinition: ProtocolDefinition = {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
export const JwkProtocolDefinition: ProtocolDefinition = {
|
|
50
|
-
protocol : '
|
|
50
|
+
protocol : 'https://identity.foundation/protocols/web5/jwk-store',
|
|
51
51
|
published : false,
|
|
52
52
|
types : {
|
|
53
53
|
privateJwk: {
|
package/src/test-harness.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { KeyValueStore } from '@enbox/common';
|
|
|
6
6
|
import type { Web5PlatformAgent } from './types/agent.js';
|
|
7
7
|
|
|
8
8
|
import { Level } from 'level';
|
|
9
|
-
import { DataStoreLevel,
|
|
9
|
+
import { DataStoreLevel, EventEmitterEventLog, MessageStoreLevel, ResumableTaskStoreLevel, StateIndexLevel } from '@enbox/dwn-sdk-js';
|
|
10
10
|
import { DidDht, DidJwk, DidResolverCacheMemory } from '@enbox/dids';
|
|
11
11
|
import { LevelStore, MemoryStore } from '@enbox/common';
|
|
12
12
|
|
|
@@ -193,8 +193,6 @@ export class PlatformAgentTestHarness {
|
|
|
193
193
|
id : 'dwn',
|
|
194
194
|
type : 'DecentralizedWebNode',
|
|
195
195
|
serviceEndpoint : testDwnUrls,
|
|
196
|
-
enc : '#enc',
|
|
197
|
-
sig : '#sig',
|
|
198
196
|
}
|
|
199
197
|
],
|
|
200
198
|
verificationMethods: [
|
|
@@ -259,7 +257,7 @@ export class PlatformAgentTestHarness {
|
|
|
259
257
|
// Note: There is no in-memory store for DWN, so we always use LevelDB-based disk stores.
|
|
260
258
|
const dwnDataStore = new DataStoreLevel({ blockstoreLocation: testDataPath('DWN_DATASTORE') });
|
|
261
259
|
const dwnStateIndex = new StateIndexLevel({ location: testDataPath('DWN_STATEINDEX') });
|
|
262
|
-
const
|
|
260
|
+
const dwnEventLog = new EventEmitterEventLog();
|
|
263
261
|
const dwnResumableTaskStore = new ResumableTaskStoreLevel({ location: testDataPath('DWN_RESUMABLETASKSTORE') });
|
|
264
262
|
|
|
265
263
|
const dwnMessageStore = new MessageStoreLevel({
|
|
@@ -273,7 +271,7 @@ export class PlatformAgentTestHarness {
|
|
|
273
271
|
dataStore : dwnDataStore,
|
|
274
272
|
didResolver : didApi,
|
|
275
273
|
stateIndex : dwnStateIndex,
|
|
276
|
-
|
|
274
|
+
eventLog : dwnEventLog,
|
|
277
275
|
messageStore : dwnMessageStore,
|
|
278
276
|
resumableTaskStore : dwnResumableTaskStore
|
|
279
277
|
});
|
package/src/types/dwn.ts
CHANGED
|
@@ -11,7 +11,6 @@ import type {
|
|
|
11
11
|
MessagesSubscribeReply,
|
|
12
12
|
MessagesSyncMessage,
|
|
13
13
|
MessagesSyncReply,
|
|
14
|
-
MessageSubscriptionHandler,
|
|
15
14
|
ProtocolsConfigureMessage,
|
|
16
15
|
ProtocolsConfigureOptions,
|
|
17
16
|
ProtocolsQueryMessage,
|
|
@@ -28,9 +27,9 @@ import type {
|
|
|
28
27
|
RecordsSubscribeMessage,
|
|
29
28
|
RecordsSubscribeOptions,
|
|
30
29
|
RecordsSubscribeReply,
|
|
31
|
-
RecordSubscriptionHandler,
|
|
32
30
|
RecordsWriteMessage,
|
|
33
31
|
RecordsWriteOptions,
|
|
32
|
+
SubscriptionListener,
|
|
34
33
|
} from '@enbox/dwn-sdk-js';
|
|
35
34
|
|
|
36
35
|
import type { MessagesSyncOptions } from '@enbox/dwn-sdk-js';
|
|
@@ -54,38 +53,37 @@ import {
|
|
|
54
53
|
* Represents a Decentralized Web Node (DWN) service in a DID Document.
|
|
55
54
|
*
|
|
56
55
|
* A DWN DID service is a specialized type of DID service with the `type` set to
|
|
57
|
-
* `DecentralizedWebNode`.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
56
|
+
* `DecentralizedWebNode`. Encryption and signing keys are resolved from the DID document's
|
|
57
|
+
* verification methods, not from the service entry.
|
|
58
|
+
*
|
|
59
|
+
* The `enc` and `sig` properties are optional legacy fields that may be present on existing
|
|
60
|
+
* DID documents for backward compatibility. New implementations should resolve keys from the
|
|
61
|
+
* DID document's verification methods by purpose (`keyAgreement` for encryption,
|
|
62
|
+
* `authentication`/`assertionMethod` for signing).
|
|
63
63
|
*
|
|
64
64
|
* @example
|
|
65
65
|
* ```ts
|
|
66
66
|
* const service: DwnDidService = {
|
|
67
67
|
* id: 'did:example:123#dwn',
|
|
68
68
|
* type: 'DecentralizedWebNode',
|
|
69
|
-
* serviceEndpoint: 'https://enbox-dwn.fly.dev'
|
|
70
|
-
* enc: 'did:example:123#key-1',
|
|
71
|
-
* sig: 'did:example:123#key-2'
|
|
69
|
+
* serviceEndpoint: 'https://enbox-dwn.fly.dev'
|
|
72
70
|
* }
|
|
73
71
|
* ```
|
|
74
72
|
*
|
|
75
|
-
* @see {@link https://
|
|
73
|
+
* @see {@link https://github.com/enboxorg/dwn-spec | Enbox DWN Specification}
|
|
76
74
|
*/
|
|
77
75
|
export interface DwnDidService extends DidService {
|
|
78
76
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
77
|
+
* @deprecated Optional legacy field. Resolve encryption keys from the DID document's
|
|
78
|
+
* `keyAgreement` verification methods instead.
|
|
81
79
|
*/
|
|
82
80
|
enc?: string | string[];
|
|
83
81
|
|
|
84
82
|
/**
|
|
85
|
-
*
|
|
86
|
-
* or
|
|
83
|
+
* @deprecated Optional legacy field. Resolve signing keys from the DID document's
|
|
84
|
+
* `authentication` or `assertionMethod` verification methods instead.
|
|
87
85
|
*/
|
|
88
|
-
sig
|
|
86
|
+
sig?: string | string[];
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
export enum DwnInterface {
|
|
@@ -158,8 +156,8 @@ export interface DwnMessageReply {
|
|
|
158
156
|
}
|
|
159
157
|
|
|
160
158
|
export interface MessageHandler {
|
|
161
|
-
[DwnInterface.MessagesSubscribe] :
|
|
162
|
-
[DwnInterface.RecordsSubscribe] :
|
|
159
|
+
[DwnInterface.MessagesSubscribe] : SubscriptionListener;
|
|
160
|
+
[DwnInterface.RecordsSubscribe] : SubscriptionListener;
|
|
163
161
|
|
|
164
162
|
// define all of them individually as undefined
|
|
165
163
|
[DwnInterface.MessagesRead] : undefined;
|
|
@@ -273,7 +271,6 @@ export type {
|
|
|
273
271
|
DataEncodedRecordsWriteMessage as DwnDataEncodedRecordsWriteMessage,
|
|
274
272
|
MessageSigner as DwnSigner,
|
|
275
273
|
MessageSubscription as DwnMessageSubscription,
|
|
276
|
-
MessageSubscriptionHandler as DwnMessageSubscriptionHandler,
|
|
277
274
|
MessagesPermissionScope as DwnMessagesPermissionScope,
|
|
278
275
|
PaginationCursor as DwnPaginationCursor,
|
|
279
276
|
PermissionConditions as DwnPermissionConditions,
|
|
@@ -283,6 +280,7 @@ export type {
|
|
|
283
280
|
ProtocolDefinition as DwnProtocolDefinition,
|
|
284
281
|
ProtocolPermissionScope as DwnProtocolPermissionScope,
|
|
285
282
|
PublicKeyJwk as DwnPublicKeyJwk,
|
|
286
|
-
RecordSubscriptionHandler as DwnRecordSubscriptionHandler,
|
|
287
283
|
RecordsPermissionScope as DwnRecordsPermissionScope,
|
|
284
|
+
SubscriptionListener as DwnSubscriptionListener,
|
|
285
|
+
SubscriptionMessage as DwnSubscriptionMessage,
|
|
288
286
|
} from '@enbox/dwn-sdk-js';
|