@enbox/agent 0.1.4 → 0.1.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/dist/browser.mjs +11 -11
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/anonymous-dwn-api.js +184 -0
- package/dist/esm/anonymous-dwn-api.js.map +1 -0
- package/dist/esm/dwn-api.js +86 -777
- package/dist/esm/dwn-api.js.map +1 -1
- package/dist/esm/dwn-encryption.js +342 -0
- package/dist/esm/dwn-encryption.js.map +1 -0
- package/dist/esm/dwn-key-delivery.js +256 -0
- package/dist/esm/dwn-key-delivery.js.map +1 -0
- package/dist/esm/dwn-record-upgrade.js +119 -0
- package/dist/esm/dwn-record-upgrade.js.map +1 -0
- package/dist/esm/dwn-type-guards.js +23 -0
- package/dist/esm/dwn-type-guards.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocol-utils.js +158 -0
- package/dist/esm/protocol-utils.js.map +1 -0
- package/dist/esm/store-data-protocols.js +1 -1
- package/dist/esm/store-data-protocols.js.map +1 -1
- package/dist/esm/sync-engine-level.js +22 -353
- package/dist/esm/sync-engine-level.js.map +1 -1
- package/dist/esm/sync-messages.js +234 -0
- package/dist/esm/sync-messages.js.map +1 -0
- package/dist/esm/sync-topological-sort.js +143 -0
- package/dist/esm/sync-topological-sort.js.map +1 -0
- package/dist/esm/test-harness.js +20 -0
- package/dist/esm/test-harness.js.map +1 -1
- package/dist/types/anonymous-dwn-api.d.ts +140 -0
- package/dist/types/anonymous-dwn-api.d.ts.map +1 -0
- package/dist/types/dwn-api.d.ts +36 -179
- package/dist/types/dwn-api.d.ts.map +1 -1
- package/dist/types/dwn-encryption.d.ts +144 -0
- package/dist/types/dwn-encryption.d.ts.map +1 -0
- package/dist/types/dwn-key-delivery.d.ts +112 -0
- package/dist/types/dwn-key-delivery.d.ts.map +1 -0
- package/dist/types/dwn-record-upgrade.d.ts +33 -0
- package/dist/types/dwn-record-upgrade.d.ts.map +1 -0
- package/dist/types/dwn-type-guards.d.ts +9 -0
- package/dist/types/dwn-type-guards.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/protocol-utils.d.ts +70 -0
- package/dist/types/protocol-utils.d.ts.map +1 -0
- package/dist/types/sync-engine-level.d.ts +5 -42
- package/dist/types/sync-engine-level.d.ts.map +1 -1
- package/dist/types/sync-messages.d.ts +76 -0
- package/dist/types/sync-messages.d.ts.map +1 -0
- package/dist/types/sync-topological-sort.d.ts +15 -0
- package/dist/types/sync-topological-sort.d.ts.map +1 -0
- package/dist/types/test-harness.d.ts +10 -0
- package/dist/types/test-harness.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/anonymous-dwn-api.ts +263 -0
- package/src/dwn-api.ts +160 -1015
- package/src/dwn-encryption.ts +481 -0
- package/src/dwn-key-delivery.ts +370 -0
- package/src/dwn-record-upgrade.ts +166 -0
- package/src/dwn-type-guards.ts +43 -0
- package/src/index.ts +6 -0
- package/src/protocol-utils.ts +185 -0
- package/src/store-data-protocols.ts +1 -1
- package/src/sync-engine-level.ts +24 -413
- package/src/sync-messages.ts +277 -0
- package/src/sync-topological-sort.ts +167 -0
- package/src/test-harness.ts +19 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -7,10 +7,16 @@ export type * from './types/permissions.js';
|
|
|
7
7
|
export type * from './types/sync.js';
|
|
8
8
|
export type * from './types/vc.js';
|
|
9
9
|
export * from './agent-did-resolver-cache.js';
|
|
10
|
+
export * from './anonymous-dwn-api.js';
|
|
10
11
|
export * from './bearer-identity.js';
|
|
11
12
|
export * from './crypto-api.js';
|
|
12
13
|
export * from './did-api.js';
|
|
13
14
|
export * from './dwn-api.js';
|
|
15
|
+
export * from './dwn-encryption.js';
|
|
16
|
+
export * from './dwn-key-delivery.js';
|
|
17
|
+
export * from './dwn-record-upgrade.js';
|
|
18
|
+
export * from './dwn-type-guards.js';
|
|
19
|
+
export * from './protocol-utils.js';
|
|
14
20
|
export * from './hd-identity-vault.js';
|
|
15
21
|
export * from './identity-api.js';
|
|
16
22
|
export * from './local-key-manager.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,kBAAkB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,mBAAmB,qBAAqB,CAAC;AACzC,mBAAmB,2BAA2B,CAAC;AAC/C,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,eAAe,CAAC;AAEnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,kBAAkB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,mBAAmB,qBAAqB,CAAC;AACzC,mBAAmB,2BAA2B,CAAC;AAC/C,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,eAAe,CAAC;AAEnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ProtocolDefinition, ProtocolRuleSet } from '@enbox/dwn-sdk-js';
|
|
2
|
+
/**
|
|
3
|
+
* Navigates a protocol definition's structure to find the rule set at a given protocol path.
|
|
4
|
+
* @param protocolDefinition - The protocol definition to search
|
|
5
|
+
* @param protocolPath - The dot-separated protocol path (e.g. 'thread/message')
|
|
6
|
+
* @returns The rule set at the given path, or undefined if the path doesn't exist
|
|
7
|
+
*/
|
|
8
|
+
export declare function getRuleSetAtPath(protocolDefinition: ProtocolDefinition, protocolPath: string): ProtocolRuleSet | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Extracts the root context ID from a contextId or parentContextId.
|
|
11
|
+
* e.g. 'abc/def/ghi' -> 'abc', 'abc' -> 'abc'
|
|
12
|
+
* @param contextId - The context ID to extract the root from
|
|
13
|
+
* @returns The root context ID
|
|
14
|
+
*/
|
|
15
|
+
export declare function getRootContextId(contextId: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Checks if a protocol path represents a multi-party context.
|
|
18
|
+
* Returns true if the root path's subtree contains $role descendants
|
|
19
|
+
* or relational who/of $actions rules that grant read access.
|
|
20
|
+
*
|
|
21
|
+
* @param protocolDefinition - The full protocol definition
|
|
22
|
+
* @param rootProtocolPath - The root protocol path to check
|
|
23
|
+
* @returns true if the protocol path represents a multi-party context
|
|
24
|
+
*/
|
|
25
|
+
export declare function isMultiPartyContext(protocolDefinition: ProtocolDefinition, rootProtocolPath: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether any relational who/of rule in the protocol grants
|
|
28
|
+
* read access for a given actor type and ancestor path.
|
|
29
|
+
*
|
|
30
|
+
* Walks the *entire* protocol structure looking for any $actions rule that:
|
|
31
|
+
* - Has `who` equal to `actorType` ('recipient' or 'author'), or any actor
|
|
32
|
+
* type if `actorType` is `undefined`
|
|
33
|
+
* - Has `of` equal to `ofPath`
|
|
34
|
+
* - Has `can` including 'read'
|
|
35
|
+
*
|
|
36
|
+
* @param actorType - 'author' | 'recipient', or undefined for any
|
|
37
|
+
* @param ofPath - The protocol path to check (e.g. 'thread', 'email')
|
|
38
|
+
* @param protocolDefinition - The full protocol definition
|
|
39
|
+
* @returns true if a matching relational read rule exists
|
|
40
|
+
*/
|
|
41
|
+
export declare function hasRelationalReadAccess(actorType: 'author' | 'recipient' | undefined, ofPath: string, protocolDefinition: ProtocolDefinition): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Analyses a record write to determine which DIDs need context key delivery.
|
|
44
|
+
*
|
|
45
|
+
* Returns a set of participant DIDs that should receive `contextKey` records.
|
|
46
|
+
* The DWN owner (tenantDid) is always excluded — they have ProtocolPath access.
|
|
47
|
+
*
|
|
48
|
+
* Cases handled:
|
|
49
|
+
* 1. `$role` record with a recipient -> recipient is a participant
|
|
50
|
+
* 2. Record has a recipient and a relational read rule grants access
|
|
51
|
+
* via `{ who: 'recipient', of: '<path>', can: ['read'] }`
|
|
52
|
+
* 3. Record is authored by an external party -> if `{ who: 'author', of:
|
|
53
|
+
* '<path>', can: ['read'] }` rules grant read access, the author needs
|
|
54
|
+
* a context key.
|
|
55
|
+
*
|
|
56
|
+
* @param params.protocolDefinition - The installed protocol definition
|
|
57
|
+
* @param params.protocolPath - The written record's protocol path
|
|
58
|
+
* @param params.recipient - Recipient DID from the record, if any
|
|
59
|
+
* @param params.tenantDid - The DWN owner's DID (excluded from results)
|
|
60
|
+
* @param params.authorDid - Author DID if externally authored, undefined otherwise
|
|
61
|
+
* @returns Set of DIDs that need context key delivery
|
|
62
|
+
*/
|
|
63
|
+
export declare function detectNewParticipants({ protocolDefinition, protocolPath, recipient, tenantDid, authorDid }: {
|
|
64
|
+
protocolDefinition: ProtocolDefinition;
|
|
65
|
+
protocolPath: string;
|
|
66
|
+
recipient?: string;
|
|
67
|
+
tenantDid: string;
|
|
68
|
+
authorDid?: string;
|
|
69
|
+
}): Set<string>;
|
|
70
|
+
//# sourceMappingURL=protocol-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-utils.d.ts","sourceRoot":"","sources":["../../src/protocol-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,MAAM,GACnB,eAAe,GAAG,SAAS,CAS7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,kBAAkB,EACtC,gBAAgB,EAAE,MAAM,GACvB,OAAO,CA2BT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,EAC7C,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CA+BT;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE;IAC3G,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,GAAG,CAAC,MAAM,CAAC,CAgCd"}
|
|
@@ -84,59 +84,22 @@ export declare class SyncEngineLevel implements SyncEngine {
|
|
|
84
84
|
private getLocalLeaves;
|
|
85
85
|
private getRemoteLeaves;
|
|
86
86
|
/**
|
|
87
|
-
* Fetches missing messages from the remote DWN and processes them
|
|
87
|
+
* Fetches missing messages from the remote DWN and processes them locally
|
|
88
88
|
* in dependency order (topological sort).
|
|
89
|
-
*
|
|
90
|
-
* Messages that fail processing are re-fetched from the remote before each retry
|
|
91
|
-
* pass rather than buffered in memory. ReadableStream is single-use, so a failed
|
|
92
|
-
* message's data stream is consumed on the first attempt. Re-fetching provides a
|
|
93
|
-
* fresh stream without holding all record data in memory simultaneously.
|
|
94
89
|
*/
|
|
95
90
|
private pullMessages;
|
|
96
91
|
/**
|
|
97
|
-
*
|
|
98
|
-
|
|
99
|
-
private fetchRemoteMessages;
|
|
100
|
-
/**
|
|
101
|
-
* Reads missing messages from the local DWN and pushes them to the remote DWN.
|
|
102
|
-
* Messages are fetched first, then sorted in dependency order (topological sort)
|
|
103
|
-
* so that initial writes come before updates, and ProtocolsConfigures come before
|
|
104
|
-
* records that reference those protocols.
|
|
92
|
+
* Reads missing messages from the local DWN and pushes them to the remote DWN
|
|
93
|
+
* in dependency order (topological sort).
|
|
105
94
|
*/
|
|
106
95
|
private pushMessages;
|
|
107
96
|
/**
|
|
108
|
-
*
|
|
109
|
-
|
|
110
|
-
private static getMessageCid;
|
|
111
|
-
/**
|
|
112
|
-
* Reads a message from the local DWN by its CID using MessagesRead.
|
|
113
|
-
*/
|
|
114
|
-
private getLocalMessage;
|
|
115
|
-
/**
|
|
116
|
-
* Builds a dependency graph from the fetched messages and returns them in
|
|
117
|
-
* topological order so that dependencies are processed before dependents.
|
|
118
|
-
*
|
|
119
|
-
* Dependencies:
|
|
120
|
-
* - ProtocolsConfigure must come before any RecordsWrite using that protocol
|
|
121
|
-
* - Parent record must come before child record (via parentId)
|
|
122
|
-
* - Initial write must come before update writes (same recordId, not initial)
|
|
123
|
-
* - Permission grant must come before records using that permissionGrantId
|
|
97
|
+
* Delegate to the standalone `topologicalSort` function.
|
|
98
|
+
* Tests call `SyncEngineLevel.topologicalSort(...)` so this static method must remain.
|
|
124
99
|
*/
|
|
125
100
|
static topologicalSort<T extends {
|
|
126
101
|
message: GenericMessage;
|
|
127
102
|
}>(messages: T[]): T[];
|
|
128
|
-
/**
|
|
129
|
-
* Checks whether a message is an initial RecordsWrite (not an update).
|
|
130
|
-
* An initial write has recordId === message CID context or has no `dateModified` != `dateCreated`.
|
|
131
|
-
*/
|
|
132
|
-
private static isInitialWrite;
|
|
133
|
-
/**
|
|
134
|
-
* 202: message was successfully written to the remote DWN
|
|
135
|
-
* 204: an initial write message was written without any data
|
|
136
|
-
* 409: message was already present on the remote DWN
|
|
137
|
-
* RecordsDelete + 404: the initial write was not found or already deleted
|
|
138
|
-
*/
|
|
139
|
-
private static syncMessageReplyIsSuccessful;
|
|
140
103
|
/**
|
|
141
104
|
* Returns the list of sync targets: (did, dwnUrl, delegateDid?, protocol?) tuples.
|
|
142
105
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-engine-level.d.ts","sourceRoot":"","sources":["../../src/sync-engine-level.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"sync-engine-level.d.ts","sourceRoot":"","sources":["../../src/sync-engine-level.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAQ3E,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAQrE,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;CAClD,CAAC;AASF,qBAAa,eAAgB,YAAW,UAAU;IAChD;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,CAAoB;IAEnC;;OAEG;IACH,OAAO,CAAC,eAAe,CAAiB;IAExC,OAAO,CAAC,GAAG,CAA8C;IACzD,OAAO,CAAC,eAAe,CAAC,CAAiC;IACzD,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAC,CAAsB;gBAElC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,qBAAqB;IAM1D;;;;;OAKG;IACH,IAAI,KAAK,IAAI,iBAAiB,CAM7B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,iBAAiB,EAGjC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,gBAAgB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,mBAAmB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjG,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAkBzE,qBAAqB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,mBAAmB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDhD,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE;QACnC,QAAQ,EAAE,MAAM,CAAA;KACjB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCjB;;OAEG;IACU,QAAQ,CAAC,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB5D;;;OAGG;YACW,iBAAiB;IAiB/B;;;OAGG;YACW,YAAY;IAmB1B;;;OAGG;YACW,aAAa;IA6B3B;;;;;OAKG;YACW,YAAY;YA0EZ,mBAAmB;YAoBnB,oBAAoB;YA0BpB,cAAc;YAoBd,eAAe;IAkC7B;;;OAGG;YACW,YAAY;IAc1B;;;OAGG;YACW,YAAY;IAkB1B;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,CAAC,SAAS;QAAE,OAAO,EAAE,cAAc,CAAA;KAAE,EAC1D,QAAQ,EAAE,CAAC,EAAE,GACZ,CAAC,EAAE;IAIN;;OAEG;YACW,cAAc;IAsC5B;;;OAGG;YACW,wBAAwB;CAmBvC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { PermissionsApi } from './types/permissions.js';
|
|
2
|
+
import type { Web5PlatformAgent } from './types/agent.js';
|
|
3
|
+
import type { GenericMessage, UnionMessageReply } from '@enbox/dwn-sdk-js';
|
|
4
|
+
/** Entry type for fetched messages with optional data stream. */
|
|
5
|
+
export type SyncMessageEntry = {
|
|
6
|
+
message: GenericMessage;
|
|
7
|
+
dataStream?: ReadableStream<Uint8Array>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* 202: message was successfully written to the remote DWN
|
|
11
|
+
* 204: an initial write message was written without any data
|
|
12
|
+
* 409: message was already present on the remote DWN
|
|
13
|
+
* RecordsDelete + 404: the initial write was not found or already deleted
|
|
14
|
+
*/
|
|
15
|
+
export declare function syncMessageReplyIsSuccessful(reply: UnionMessageReply): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Helper to get the CID of a message for logging purposes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getMessageCid(message: GenericMessage): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetches missing messages from the remote DWN and processes them on the local DWN
|
|
22
|
+
* in dependency order (topological sort).
|
|
23
|
+
*
|
|
24
|
+
* Messages that fail processing are re-fetched from the remote before each retry
|
|
25
|
+
* pass rather than buffered in memory. ReadableStream is single-use, so a failed
|
|
26
|
+
* message's data stream is consumed on the first attempt. Re-fetching provides a
|
|
27
|
+
* fresh stream without holding all record data in memory simultaneously.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pullMessages({ did, dwnUrl, delegateDid, protocol, messageCids, agent, permissionsApi }: {
|
|
30
|
+
did: string;
|
|
31
|
+
dwnUrl: string;
|
|
32
|
+
delegateDid?: string;
|
|
33
|
+
protocol?: string;
|
|
34
|
+
messageCids: string[];
|
|
35
|
+
agent: Web5PlatformAgent;
|
|
36
|
+
permissionsApi: PermissionsApi;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Fetches messages from a remote DWN by their CIDs using MessagesRead.
|
|
40
|
+
*/
|
|
41
|
+
export declare function fetchRemoteMessages({ did, dwnUrl, delegateDid, protocol, messageCids, agent, permissionsApi }: {
|
|
42
|
+
did: string;
|
|
43
|
+
dwnUrl: string;
|
|
44
|
+
delegateDid?: string;
|
|
45
|
+
protocol?: string;
|
|
46
|
+
messageCids: string[];
|
|
47
|
+
agent: Web5PlatformAgent;
|
|
48
|
+
permissionsApi: PermissionsApi;
|
|
49
|
+
}): Promise<SyncMessageEntry[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Reads missing messages from the local DWN and pushes them to the remote DWN.
|
|
52
|
+
* Messages are fetched first, then sorted in dependency order (topological sort)
|
|
53
|
+
* so that initial writes come before updates, and ProtocolsConfigures come before
|
|
54
|
+
* records that reference those protocols.
|
|
55
|
+
*/
|
|
56
|
+
export declare function pushMessages({ did, dwnUrl, delegateDid, protocol, messageCids, agent, permissionsApi }: {
|
|
57
|
+
did: string;
|
|
58
|
+
dwnUrl: string;
|
|
59
|
+
delegateDid?: string;
|
|
60
|
+
protocol?: string;
|
|
61
|
+
messageCids: string[];
|
|
62
|
+
agent: Web5PlatformAgent;
|
|
63
|
+
permissionsApi: PermissionsApi;
|
|
64
|
+
}): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Reads a message from the local DWN by its CID using MessagesRead.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getLocalMessage({ author, delegateDid, protocol, messageCid, agent, permissionsApi }: {
|
|
69
|
+
author: string;
|
|
70
|
+
delegateDid?: string;
|
|
71
|
+
protocol?: string;
|
|
72
|
+
messageCid: string;
|
|
73
|
+
agent: Web5PlatformAgent;
|
|
74
|
+
permissionsApi: PermissionsApi;
|
|
75
|
+
}): Promise<SyncMessageEntry | undefined>;
|
|
76
|
+
//# sourceMappingURL=sync-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-messages.d.ts","sourceRoot":"","sources":["../../src/sync-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAqB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAQ9F,iEAAiE;AACjE,MAAM,MAAM,gBAAgB,GAAG;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;CAAE,CAAC;AAEpG;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAS9E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IAC7G,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IACpH,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAuE9B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IAC7G,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgChB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IAC1G,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,iBAAiB,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAwCxC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GenericMessage } from '@enbox/dwn-sdk-js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a dependency graph from the fetched messages and returns them in
|
|
4
|
+
* topological order so that dependencies are processed before dependents.
|
|
5
|
+
*
|
|
6
|
+
* Dependencies:
|
|
7
|
+
* - ProtocolsConfigure must come before any RecordsWrite using that protocol
|
|
8
|
+
* - Parent record must come before child record (via parentId)
|
|
9
|
+
* - Initial write must come before update writes (same recordId, not initial)
|
|
10
|
+
* - Permission grant must come before records using that permissionGrantId
|
|
11
|
+
*/
|
|
12
|
+
export declare function topologicalSort<T extends {
|
|
13
|
+
message: GenericMessage;
|
|
14
|
+
}>(messages: T[]): T[];
|
|
15
|
+
//# sourceMappingURL=sync-topological-sort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-topological-sort.d.ts","sourceRoot":"","sources":["../../src/sync-topological-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAiBxD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,EACnE,QAAQ,EAAE,CAAC,EAAE,GACZ,CAAC,EAAE,CAyIL"}
|
|
@@ -51,6 +51,16 @@ export declare class PlatformAgentTestHarness {
|
|
|
51
51
|
};
|
|
52
52
|
constructor(params: PlatformAgentTestHarnessParams);
|
|
53
53
|
clearStorage(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Clear only DWN-level stores (data, messages, state index, resumable tasks,
|
|
56
|
+
* sync, permissions) and the DWN-backed store caches — but preserve the
|
|
57
|
+
* agent DID, vault, and all key/DID/identity material.
|
|
58
|
+
*
|
|
59
|
+
* Use this in `beforeEach` when `createAgentDid()` (and optionally
|
|
60
|
+
* `createIdentity()`) was called once in `beforeAll` to avoid expensive
|
|
61
|
+
* DID re-creation on every test.
|
|
62
|
+
*/
|
|
63
|
+
clearDwnStores(): Promise<void>;
|
|
54
64
|
closeStorage(): Promise<void>;
|
|
55
65
|
createAgentDid(): Promise<void>;
|
|
56
66
|
createIdentity({ name, testDwnUrls }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-harness.d.ts","sourceRoot":"","sources":["../../src/test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAsB,iBAAiB,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYpI,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAyB,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAY/D,KAAK,8BAA8B,GAAG;IACpC,KAAK,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAA;IAEzC,WAAW,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC9B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,GAAG,EAAE,GAAG,CAAC;IACT,YAAY,EAAE,cAAc,CAAC;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,eAAe,EAAE,iBAAiB,CAAC;IACnC,qBAAqB,EAAE,uBAAuB,CAAC;IAC/C,SAAS,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;IACvD,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,SAAS,EAAE;QACT,QAAQ,EAAE,WAAW,CAAC;QACtB,aAAa,EAAE,gBAAgB,CAAC;QAChC,QAAQ,EAAE,WAAW,CAAC;QACtB,KAAK,EAAE,MAAM,IAAI,CAAC;KACnB,CAAA;CACF,CAAC;AAEF,qBAAa,wBAAwB;IAC5B,KAAK,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAE1C,WAAW,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC9B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,GAAG,EAAE,GAAG,CAAC;IACT,YAAY,EAAE,cAAc,CAAC;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,eAAe,EAAE,iBAAiB,CAAC;IACnC,qBAAqB,EAAE,uBAAuB,CAAC;IAC/C,SAAS,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;IACvD,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjD;;;OAGG;IACI,SAAS,EAAE;QAChB,QAAQ,EAAE,WAAW,CAAC;QACtB,aAAa,EAAE,gBAAgB,CAAC;QAChC,QAAQ,EAAE,WAAW,CAAC;QACtB,gDAAgD;QAChD,KAAK,EAAE,MAAM,IAAI,CAAC;KACnB,CAAC;gBAEU,MAAM,EAAE,8BAA8B;IAcrC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"test-harness.d.ts","sourceRoot":"","sources":["../../src/test-harness.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enbox/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@scure/bip39": "1.2.2",
|
|
74
|
-
"@enbox/dwn-clients": "0.0.
|
|
75
|
-
"@enbox/dwn-sdk-js": "0.0.
|
|
74
|
+
"@enbox/dwn-clients": "0.0.4",
|
|
75
|
+
"@enbox/dwn-sdk-js": "0.0.7",
|
|
76
76
|
"@enbox/common": "0.0.3",
|
|
77
|
-
"@enbox/crypto": "0.0.
|
|
78
|
-
"@enbox/dids": "0.0.
|
|
77
|
+
"@enbox/crypto": "0.0.4",
|
|
78
|
+
"@enbox/dids": "0.0.5",
|
|
79
79
|
"abstract-level": "1.0.4",
|
|
80
80
|
"ed25519-keygen": "0.4.11",
|
|
81
81
|
"level": "8.0.0",
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import type { DidUrlDereferencer } from '@enbox/dids';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
DateSort,
|
|
5
|
+
Pagination,
|
|
6
|
+
ProtocolsQueryFilter,
|
|
7
|
+
ProtocolsQueryReply,
|
|
8
|
+
RecordsCountMessage,
|
|
9
|
+
RecordsCountReply,
|
|
10
|
+
RecordsFilter,
|
|
11
|
+
RecordsQueryReply,
|
|
12
|
+
RecordsReadReply,
|
|
13
|
+
RecordsSubscribeReply,
|
|
14
|
+
RecordSubscriptionHandler,
|
|
15
|
+
} from '@enbox/dwn-sdk-js';
|
|
16
|
+
import type { DwnRpcRequest, Web5Rpc } from '@enbox/dwn-clients';
|
|
17
|
+
|
|
18
|
+
import { ProtocolsQuery, RecordsCount, RecordsQuery, RecordsRead, RecordsSubscribe } from '@enbox/dwn-sdk-js';
|
|
19
|
+
|
|
20
|
+
import { getDwnServiceEndpointUrls } from './utils.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parameters for constructing an {@link AnonymousDwnApi}.
|
|
24
|
+
*/
|
|
25
|
+
export type AnonymousDwnApiParams = {
|
|
26
|
+
/** A DID URL dereferencer for resolving target DID service endpoints. */
|
|
27
|
+
didResolver: DidUrlDereferencer;
|
|
28
|
+
/** An RPC client for sending messages to remote DWNs. */
|
|
29
|
+
rpcClient: Web5Rpc;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parameters for an anonymous records query.
|
|
34
|
+
* Mirrors the DWN SDK's `RecordsQueryOptions` without `signer` or delegation fields.
|
|
35
|
+
*/
|
|
36
|
+
export type AnonymousRecordsQueryParams = {
|
|
37
|
+
filter: RecordsFilter;
|
|
38
|
+
dateSort?: DateSort;
|
|
39
|
+
pagination?: Pagination;
|
|
40
|
+
messageTimestamp?: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Parameters for an anonymous records read.
|
|
45
|
+
*/
|
|
46
|
+
export type AnonymousRecordsReadParams = {
|
|
47
|
+
filter: RecordsFilter;
|
|
48
|
+
messageTimestamp?: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Parameters for an anonymous records subscribe.
|
|
53
|
+
*/
|
|
54
|
+
export type AnonymousRecordsSubscribeParams = {
|
|
55
|
+
filter: RecordsFilter;
|
|
56
|
+
dateSort?: DateSort;
|
|
57
|
+
pagination?: Pagination;
|
|
58
|
+
messageTimestamp?: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Parameters for an anonymous records count.
|
|
63
|
+
*/
|
|
64
|
+
export type AnonymousRecordsCountParams = {
|
|
65
|
+
filter: RecordsFilter;
|
|
66
|
+
messageTimestamp?: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parameters for an anonymous protocols query.
|
|
71
|
+
*/
|
|
72
|
+
export type AnonymousProtocolsQueryParams = {
|
|
73
|
+
filter?: ProtocolsQueryFilter;
|
|
74
|
+
messageTimestamp?: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A lightweight DWN API that creates **unsigned** (anonymous) DWN messages and
|
|
79
|
+
* sends them to remote DWNs via RPC.
|
|
80
|
+
*
|
|
81
|
+
* This class does not require a vault, agent DID, signing keys, or any identity
|
|
82
|
+
* infrastructure. It leverages the DWN SDK's native support for optional
|
|
83
|
+
* `signer` on read-path operations (RecordsQuery, RecordsRead, RecordsSubscribe,
|
|
84
|
+
* RecordsCount, ProtocolsQuery).
|
|
85
|
+
*
|
|
86
|
+
* Anonymous queries return only published records. Anonymous reads succeed for
|
|
87
|
+
* published records and for protocol records with `{ who: 'anyone', can: ['read'] }`.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const resolver = new UniversalResolver({ didResolvers: [DidDht, DidJwk] });
|
|
92
|
+
* const rpcClient = new Web5RpcClient();
|
|
93
|
+
* const anonymousDwn = new AnonymousDwnApi({ didResolver: resolver, rpcClient });
|
|
94
|
+
*
|
|
95
|
+
* const reply = await anonymousDwn.recordsQuery('did:dht:alice...', {
|
|
96
|
+
* filter: { protocol: 'https://social.example/posts', protocolPath: 'post' },
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export class AnonymousDwnApi {
|
|
101
|
+
private _didResolver: DidUrlDereferencer;
|
|
102
|
+
private _rpcClient: Web5Rpc;
|
|
103
|
+
|
|
104
|
+
constructor({ didResolver, rpcClient }: AnonymousDwnApiParams) {
|
|
105
|
+
this._didResolver = didResolver;
|
|
106
|
+
this._rpcClient = rpcClient;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Send an anonymous (unsigned) `RecordsQuery` to a remote DWN.
|
|
111
|
+
*
|
|
112
|
+
* Only published records are returned by the remote DWN.
|
|
113
|
+
*
|
|
114
|
+
* @param target - The DID whose DWN will be queried.
|
|
115
|
+
* @param params - Query parameters (filter, sort, pagination).
|
|
116
|
+
* @returns The raw `RecordsQueryReply` from the remote DWN.
|
|
117
|
+
*/
|
|
118
|
+
public async recordsQuery(target: string, params: AnonymousRecordsQueryParams): Promise<RecordsQueryReply> {
|
|
119
|
+
const recordsQuery = await RecordsQuery.create({
|
|
120
|
+
filter : params.filter,
|
|
121
|
+
dateSort : params.dateSort,
|
|
122
|
+
pagination : params.pagination,
|
|
123
|
+
messageTimestamp : params.messageTimestamp,
|
|
124
|
+
// No signer — creates an unsigned message.
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return await this.sendRequest<RecordsQueryReply>(target, recordsQuery.message);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Send an anonymous (unsigned) `RecordsRead` to a remote DWN.
|
|
132
|
+
*
|
|
133
|
+
* Succeeds for published records and for protocol records with
|
|
134
|
+
* `{ who: 'anyone', can: ['read'] }` rules.
|
|
135
|
+
*
|
|
136
|
+
* @param target - The DID whose DWN will be read from.
|
|
137
|
+
* @param params - Read parameters (filter).
|
|
138
|
+
* @returns The raw `RecordsReadReply` from the remote DWN.
|
|
139
|
+
*/
|
|
140
|
+
public async recordsRead(target: string, params: AnonymousRecordsReadParams): Promise<RecordsReadReply> {
|
|
141
|
+
const recordsRead = await RecordsRead.create({
|
|
142
|
+
filter : params.filter,
|
|
143
|
+
messageTimestamp : params.messageTimestamp,
|
|
144
|
+
// No signer — creates an unsigned message.
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
return await this.sendRequest<RecordsReadReply>(target, recordsRead.message);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Send an anonymous (unsigned) `RecordsSubscribe` to a remote DWN.
|
|
152
|
+
*
|
|
153
|
+
* Only published record events are received.
|
|
154
|
+
*
|
|
155
|
+
* @param target - The DID whose DWN to subscribe to.
|
|
156
|
+
* @param params - Subscribe parameters (filter).
|
|
157
|
+
* @param handler - Callback for incoming record events.
|
|
158
|
+
* @returns The raw `RecordsSubscribeReply` from the remote DWN.
|
|
159
|
+
*/
|
|
160
|
+
public async recordsSubscribe(
|
|
161
|
+
target: string,
|
|
162
|
+
params: AnonymousRecordsSubscribeParams,
|
|
163
|
+
handler: RecordSubscriptionHandler,
|
|
164
|
+
): Promise<RecordsSubscribeReply> {
|
|
165
|
+
const recordsSubscribe = await RecordsSubscribe.create({
|
|
166
|
+
filter : params.filter,
|
|
167
|
+
dateSort : params.dateSort,
|
|
168
|
+
pagination : params.pagination,
|
|
169
|
+
messageTimestamp : params.messageTimestamp,
|
|
170
|
+
// No signer — creates an unsigned message.
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return await this.sendRequest<RecordsSubscribeReply>(target, recordsSubscribe.message, undefined, handler);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Send an anonymous (unsigned) `RecordsCount` to a remote DWN.
|
|
178
|
+
*
|
|
179
|
+
* Only published records are counted.
|
|
180
|
+
*
|
|
181
|
+
* @param target - The DID whose DWN to count records in.
|
|
182
|
+
* @param params - Count parameters (filter).
|
|
183
|
+
* @returns The raw `RecordsCountReply` from the remote DWN.
|
|
184
|
+
*/
|
|
185
|
+
public async recordsCount(target: string, params: AnonymousRecordsCountParams): Promise<RecordsCountReply> {
|
|
186
|
+
const recordsCount = await RecordsCount.create({
|
|
187
|
+
filter : params.filter,
|
|
188
|
+
messageTimestamp : params.messageTimestamp,
|
|
189
|
+
// No signer — creates an unsigned message.
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
return await this.sendRequest<RecordsCountReply>(target, recordsCount.message as RecordsCountMessage);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Send an anonymous (unsigned) `ProtocolsQuery` to a remote DWN.
|
|
197
|
+
*
|
|
198
|
+
* Only published protocol definitions are returned.
|
|
199
|
+
*
|
|
200
|
+
* @param target - The DID whose DWN to query protocols from.
|
|
201
|
+
* @param params - Optional query parameters (protocol filter).
|
|
202
|
+
* @returns The raw `ProtocolsQueryReply` from the remote DWN.
|
|
203
|
+
*/
|
|
204
|
+
public async protocolsQuery(target: string, params?: AnonymousProtocolsQueryParams): Promise<ProtocolsQueryReply> {
|
|
205
|
+
const protocolsQuery = await ProtocolsQuery.create({
|
|
206
|
+
filter : params?.filter,
|
|
207
|
+
messageTimestamp : params?.messageTimestamp,
|
|
208
|
+
// No signer — creates an unsigned message.
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return await this.sendRequest<ProtocolsQueryReply>(target, protocolsQuery.message);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Resolve the target DID's DWN service endpoints and send an unsigned
|
|
216
|
+
* message to the first one that responds.
|
|
217
|
+
*
|
|
218
|
+
* Follows the same retry-over-endpoints pattern as `AgentDwnApi.sendDwnRpcRequest()`.
|
|
219
|
+
*/
|
|
220
|
+
private async sendRequest<TReply>(
|
|
221
|
+
target: string,
|
|
222
|
+
message: unknown,
|
|
223
|
+
data?: Blob,
|
|
224
|
+
subscriptionHandler?: RecordSubscriptionHandler,
|
|
225
|
+
): Promise<TReply> {
|
|
226
|
+
const dwnEndpointUrls = await getDwnServiceEndpointUrls(target, this._didResolver);
|
|
227
|
+
const errorMessages: { url: string; message: string }[] = [];
|
|
228
|
+
|
|
229
|
+
for (let dwnUrl of dwnEndpointUrls) {
|
|
230
|
+
try {
|
|
231
|
+
// For subscriptions, upgrade to WebSocket transport if available.
|
|
232
|
+
if (subscriptionHandler !== undefined) {
|
|
233
|
+
const serverInfo = await this._rpcClient.getServerInfo(dwnUrl);
|
|
234
|
+
if (!serverInfo.webSocketSupport) {
|
|
235
|
+
errorMessages.push({ url: dwnUrl, message: 'WebSocket support is not enabled on the server.' });
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const parsedUrl = new URL(dwnUrl);
|
|
240
|
+
parsedUrl.protocol = parsedUrl.protocol === 'http:' ? 'ws:' : 'wss:';
|
|
241
|
+
dwnUrl = parsedUrl.toString();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const reply = await this._rpcClient.sendDwnRequest({
|
|
245
|
+
dwnUrl,
|
|
246
|
+
targetDid : target,
|
|
247
|
+
message,
|
|
248
|
+
data,
|
|
249
|
+
subscriptionHandler : subscriptionHandler,
|
|
250
|
+
} as DwnRpcRequest);
|
|
251
|
+
|
|
252
|
+
return reply as TReply;
|
|
253
|
+
} catch (error: unknown) {
|
|
254
|
+
errorMessages.push({
|
|
255
|
+
url : dwnUrl,
|
|
256
|
+
message : (error instanceof Error) ? error.message : 'Unknown error',
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
throw new Error(`AnonymousDwnApi: Failed to send request to '${target}': ${JSON.stringify(errorMessages)}`);
|
|
262
|
+
}
|
|
263
|
+
}
|