@enbox/api 0.1.1 → 0.2.0
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/README.md +140 -159
- package/dist/browser.mjs +23 -13
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/advanced.js +11 -0
- package/dist/esm/advanced.js.map +1 -0
- package/dist/esm/define-protocol.js +3 -3
- package/dist/esm/dwn-api.js +55 -107
- package/dist/esm/dwn-api.js.map +1 -1
- package/dist/esm/dwn-reader-api.js +128 -0
- package/dist/esm/dwn-reader-api.js.map +1 -0
- package/dist/esm/index.js +3 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/live-query.js +5 -4
- package/dist/esm/live-query.js.map +1 -1
- package/dist/esm/read-only-record.js +255 -0
- package/dist/esm/read-only-record.js.map +1 -0
- package/dist/esm/record.js +46 -57
- package/dist/esm/record.js.map +1 -1
- package/dist/esm/typed-web5.js +242 -0
- package/dist/esm/typed-web5.js.map +1 -0
- package/dist/esm/web5.js +71 -3
- package/dist/esm/web5.js.map +1 -1
- package/dist/types/advanced.d.ts +12 -0
- package/dist/types/advanced.d.ts.map +1 -0
- package/dist/types/define-protocol.d.ts +3 -3
- package/dist/types/dwn-api.d.ts +12 -89
- package/dist/types/dwn-api.d.ts.map +1 -1
- package/dist/types/dwn-reader-api.d.ts +138 -0
- package/dist/types/dwn-reader-api.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/live-query.d.ts +13 -1
- package/dist/types/live-query.d.ts.map +1 -1
- package/dist/types/protocol-types.d.ts +2 -2
- package/dist/types/read-only-record.d.ts +133 -0
- package/dist/types/read-only-record.d.ts.map +1 -0
- package/dist/types/record.d.ts +37 -17
- package/dist/types/record.d.ts.map +1 -1
- package/dist/types/{typed-dwn-api.d.ts → typed-web5.d.ts} +70 -73
- package/dist/types/typed-web5.d.ts.map +1 -0
- package/dist/types/web5.d.ts +79 -3
- package/dist/types/web5.d.ts.map +1 -1
- package/package.json +9 -5
- package/src/advanced.ts +29 -0
- package/src/define-protocol.ts +3 -3
- package/src/dwn-api.ts +88 -222
- package/src/dwn-reader-api.ts +255 -0
- package/src/index.ts +3 -2
- package/src/live-query.ts +20 -4
- package/src/protocol-types.ts +2 -2
- package/src/read-only-record.ts +328 -0
- package/src/record.ts +116 -86
- package/src/typed-web5.ts +445 -0
- package/src/web5.ts +104 -5
- package/dist/esm/typed-dwn-api.js +0 -182
- package/dist/esm/typed-dwn-api.js.map +0 -1
- package/dist/types/typed-dwn-api.d.ts.map +0 -1
- package/src/typed-dwn-api.ts +0 -370
package/src/dwn-api.ts
CHANGED
|
@@ -21,20 +21,14 @@ import {
|
|
|
21
21
|
AgentPermissionsApi,
|
|
22
22
|
} from '@enbox/agent';
|
|
23
23
|
|
|
24
|
-
import { isEmptyObject } from '@enbox/common';
|
|
25
24
|
import { DwnInterface, getRecordAuthor } from '@enbox/agent';
|
|
26
25
|
|
|
27
|
-
import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
|
|
28
|
-
|
|
29
|
-
import type { SchemaMap, TypedProtocol } from './protocol-types.js';
|
|
30
|
-
|
|
31
26
|
import { dataToBlob } from './utils.js';
|
|
32
27
|
import { LiveQuery } from './live-query.js';
|
|
33
28
|
import { PermissionGrant } from './permission-grant.js';
|
|
34
29
|
import { PermissionRequest } from './permission-request.js';
|
|
35
30
|
import { Protocol } from './protocol.js';
|
|
36
31
|
import { Record } from './record.js';
|
|
37
|
-
import { TypedDwnApi } from './typed-dwn-api.js';
|
|
38
32
|
|
|
39
33
|
/**
|
|
40
34
|
* Represents the request payload for fetching permission requests from a Decentralized Web Node (DWN).
|
|
@@ -64,9 +58,7 @@ export type FetchGrantsRequest = Omit<FetchPermissionsParams, 'author' | 'target
|
|
|
64
58
|
*
|
|
65
59
|
* This request type is used to specify the configuration options for the protocol.
|
|
66
60
|
*/
|
|
67
|
-
export type ProtocolsConfigureRequest = {
|
|
68
|
-
/** Configuration options for the protocol. */
|
|
69
|
-
message: Omit<DwnMessageParams[DwnInterface.ProtocolsConfigure], 'signer'>;
|
|
61
|
+
export type ProtocolsConfigureRequest = Omit<DwnMessageParams[DwnInterface.ProtocolsConfigure], 'signer'> & {
|
|
70
62
|
/** When true, derives and injects $encryption public keys into the protocol definition. */
|
|
71
63
|
encryption?: boolean;
|
|
72
64
|
};
|
|
@@ -92,12 +84,9 @@ export type ProtocolsConfigureResponse = DwnResponseStatus & {
|
|
|
92
84
|
* target the local DWN. If the `from` property is provided, the query will target the specified
|
|
93
85
|
* remote DWN.
|
|
94
86
|
*/
|
|
95
|
-
export type ProtocolsQueryRequest = {
|
|
87
|
+
export type ProtocolsQueryRequest = Omit<DwnMessageParams[DwnInterface.ProtocolsQuery], 'signer'> & {
|
|
96
88
|
/** Optional DID specifying the remote target DWN tenant to be queried. */
|
|
97
89
|
from?: string;
|
|
98
|
-
|
|
99
|
-
/** Query filters and options that influence the results returned. */
|
|
100
|
-
message: Omit<DwnMessageParams[DwnInterface.ProtocolsQuery], 'signer'>
|
|
101
90
|
};
|
|
102
91
|
|
|
103
92
|
/**
|
|
@@ -109,40 +98,6 @@ export type ProtocolsQueryResponse = DwnResponseStatus & {
|
|
|
109
98
|
protocols: Protocol[];
|
|
110
99
|
};
|
|
111
100
|
|
|
112
|
-
/**
|
|
113
|
-
* Type alias for {@link RecordsWriteRequest}
|
|
114
|
-
*/
|
|
115
|
-
export type RecordsCreateRequest = RecordsWriteRequest;
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Type alias for {@link RecordsWriteResponse}
|
|
119
|
-
*/
|
|
120
|
-
export type RecordsCreateResponse = RecordsWriteResponse;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Represents a request to create a new record based on an existing one.
|
|
124
|
-
*
|
|
125
|
-
* This request type allows specifying the new data for the record, along with any additional
|
|
126
|
-
* message parameters required for the write operation.
|
|
127
|
-
*/
|
|
128
|
-
export type RecordsCreateFromRequest = {
|
|
129
|
-
/** The DID of the entity authoring the record. */
|
|
130
|
-
author: string;
|
|
131
|
-
/** The new data for the record. */
|
|
132
|
-
data: unknown;
|
|
133
|
-
/** Optional additional parameters for the record write operation */
|
|
134
|
-
message?: Omit<DwnMessageParams[DwnInterface.RecordsWrite], 'signer'>;
|
|
135
|
-
/** The existing record instance that is being used as a basis for the new record. */
|
|
136
|
-
record: Record;
|
|
137
|
-
/**
|
|
138
|
-
* Controls whether the new record should be auto-encrypted.
|
|
139
|
-
*
|
|
140
|
-
* If omitted, auto-detected from the source record: if the source record was
|
|
141
|
-
* encrypted, the new record is automatically encrypted with a fresh DEK.
|
|
142
|
-
*/
|
|
143
|
-
encryption?: boolean;
|
|
144
|
-
};
|
|
145
|
-
|
|
146
101
|
/**
|
|
147
102
|
* Defines a request to delete a record from the Decentralized Web Node (DWN).
|
|
148
103
|
*
|
|
@@ -150,15 +105,12 @@ export type RecordsCreateFromRequest = {
|
|
|
150
105
|
* message parameters for the delete operation. If the `from` property is not provided, the record
|
|
151
106
|
* will be deleted from the local DWN.
|
|
152
107
|
*/
|
|
153
|
-
export type RecordsDeleteRequest = {
|
|
108
|
+
export type RecordsDeleteRequest = Omit<DwnMessageParams[DwnInterface.RecordsDelete], 'signer'> & {
|
|
154
109
|
/** Optional DID specifying the remote target DWN tenant the record will be deleted from. */
|
|
155
110
|
from?: string;
|
|
156
111
|
|
|
157
|
-
/**
|
|
112
|
+
/** Protocol URI for permission grant resolution. */
|
|
158
113
|
protocol?: string;
|
|
159
|
-
|
|
160
|
-
/** The parameters for the delete operation. */
|
|
161
|
-
message: Omit<DwnMessageParams[DwnInterface.RecordsDelete], 'signer'>;
|
|
162
114
|
};
|
|
163
115
|
|
|
164
116
|
/**
|
|
@@ -168,16 +120,10 @@ export type RecordsDeleteRequest = {
|
|
|
168
120
|
* parameters, and optionally the target DWN to query from. If the `from` property is not provided,
|
|
169
121
|
* the query will target the local DWN.
|
|
170
122
|
*/
|
|
171
|
-
export type RecordsQueryRequest = {
|
|
123
|
+
export type RecordsQueryRequest = Omit<DwnMessageParams[DwnInterface.RecordsQuery], 'signer'> & {
|
|
172
124
|
/** Optional DID specifying the remote target DWN tenant to query from and return results. */
|
|
173
125
|
from?: string;
|
|
174
126
|
|
|
175
|
-
/** Records must be scoped to a specific protocol */
|
|
176
|
-
protocol?: string;
|
|
177
|
-
|
|
178
|
-
/** The parameters for the query operation, detailing the criteria for selecting records. */
|
|
179
|
-
message: Omit<DwnMessageParams[DwnInterface.RecordsQuery], 'signer'>;
|
|
180
|
-
|
|
181
127
|
/** When true, automatically decrypts encrypted records in the query results. */
|
|
182
128
|
encryption?: boolean;
|
|
183
129
|
};
|
|
@@ -188,7 +134,7 @@ export type RecordsQueryRequest = {
|
|
|
188
134
|
*/
|
|
189
135
|
export type RecordsQueryResponse = DwnResponseStatus & {
|
|
190
136
|
/** Array of records matching the query. */
|
|
191
|
-
records
|
|
137
|
+
records: Record[];
|
|
192
138
|
|
|
193
139
|
/** If there are additional results, the messageCid of the last record will be returned as a pagination cursor. */
|
|
194
140
|
cursor?: DwnPaginationCursor;
|
|
@@ -201,16 +147,13 @@ export type RecordsQueryResponse = DwnResponseStatus & {
|
|
|
201
147
|
* additional parameters for the read operation. It's useful for fetching the details of a single
|
|
202
148
|
* record by its identifier or other criteria.
|
|
203
149
|
*/
|
|
204
|
-
export type RecordsReadRequest = {
|
|
150
|
+
export type RecordsReadRequest = Omit<DwnMessageParams[DwnInterface.RecordsRead], 'signer'> & {
|
|
205
151
|
/** Optional DID specifying the remote target DWN tenant the record will be read from. */
|
|
206
152
|
from?: string;
|
|
207
153
|
|
|
208
|
-
/**
|
|
154
|
+
/** Protocol URI for permission grant resolution. */
|
|
209
155
|
protocol?: string;
|
|
210
156
|
|
|
211
|
-
/** The parameters for the read operation, detailing the criteria for selecting the record. */
|
|
212
|
-
message: Omit<DwnMessageParams[DwnInterface.RecordsRead], 'signer'>;
|
|
213
|
-
|
|
214
157
|
/** When true, automatically decrypts the encrypted record data. */
|
|
215
158
|
encryption?: boolean;
|
|
216
159
|
};
|
|
@@ -231,15 +174,9 @@ export type RecordsReadResponse = DwnResponseStatus & {
|
|
|
231
174
|
* matching records alongside a real-time stream of deduplicated, semantically-
|
|
232
175
|
* typed change events (`create`, `update`, `delete`).
|
|
233
176
|
*/
|
|
234
|
-
export type RecordsSubscribeRequest = {
|
|
177
|
+
export type RecordsSubscribeRequest = Omit<DwnMessageParams[DwnInterface.RecordsSubscribe], 'signer'> & {
|
|
235
178
|
/** Optional DID specifying the remote target DWN tenant to subscribe from. */
|
|
236
179
|
from?: string;
|
|
237
|
-
|
|
238
|
-
/** Records must be scoped to a specific protocol. */
|
|
239
|
-
protocol?: string;
|
|
240
|
-
|
|
241
|
-
/** The parameters for the subscription operation, detailing the criteria for the subscription filter. */
|
|
242
|
-
message: Omit<DwnMessageParams[DwnInterface.RecordsSubscribe], 'signer'>;
|
|
243
180
|
};
|
|
244
181
|
|
|
245
182
|
/** Encapsulates the response from a DWN RecordsSubscribeRequest. */
|
|
@@ -254,18 +191,11 @@ export type RecordsSubscribeResponse = DwnResponseStatus & {
|
|
|
254
191
|
* This request type allows specifying the data for the new or updated record, along with any
|
|
255
192
|
* additional message parameters required for the write operation, and an optional flag to indicate
|
|
256
193
|
* whether the record should be immediately stored.
|
|
257
|
-
*
|
|
258
|
-
* @param data -
|
|
259
|
-
* @param message - , excluding the signer.
|
|
260
|
-
* @param store -
|
|
261
194
|
*/
|
|
262
|
-
export type RecordsWriteRequest = {
|
|
195
|
+
export type RecordsWriteRequest = Omit<Partial<DwnMessageParams[DwnInterface.RecordsWrite]>, 'signer' | 'data'> & {
|
|
263
196
|
/** The data payload for the record, which can be of any type. */
|
|
264
197
|
data: unknown;
|
|
265
198
|
|
|
266
|
-
/** Optional additional parameters for the record write operation. */
|
|
267
|
-
message?: Omit<Partial<DwnMessageParams[DwnInterface.RecordsWrite]>, 'signer'>;
|
|
268
|
-
|
|
269
199
|
/**
|
|
270
200
|
* Optional flag indicating whether the record should be immediately stored. If true, the record
|
|
271
201
|
* is persisted in the DWN as part of the write operation. If false, the record is created,
|
|
@@ -294,7 +224,7 @@ export type RecordsWriteResponse = DwnResponseStatus & {
|
|
|
294
224
|
* The `Record` instance representing the record that was successfully written to the
|
|
295
225
|
* DWN as a result of the write operation.
|
|
296
226
|
*/
|
|
297
|
-
record
|
|
227
|
+
record: Record;
|
|
298
228
|
};
|
|
299
229
|
|
|
300
230
|
/**
|
|
@@ -323,30 +253,6 @@ export class DwnApi {
|
|
|
323
253
|
this.permissionsApi = new AgentPermissionsApi({ agent: this.agent });
|
|
324
254
|
}
|
|
325
255
|
|
|
326
|
-
/**
|
|
327
|
-
* Returns a {@link TypedDwnApi} scoped to the given typed protocol.
|
|
328
|
-
*
|
|
329
|
-
* The returned API provides path autocompletion, typed data payloads,
|
|
330
|
-
* and automatically injects the protocol URI and protocolPath into every
|
|
331
|
-
* DWN operation.
|
|
332
|
-
*
|
|
333
|
-
* @param protocol - A typed protocol created via `defineProtocol()`.
|
|
334
|
-
* @returns A `TypedDwnApi` instance bound to the given protocol.
|
|
335
|
-
*
|
|
336
|
-
* @example
|
|
337
|
-
* ```ts
|
|
338
|
-
* const social = dwn.using(SocialGraphProtocol);
|
|
339
|
-
* const { record } = await social.write('friend', {
|
|
340
|
-
* data: { did: 'did:example:alice' },
|
|
341
|
-
* });
|
|
342
|
-
* ```
|
|
343
|
-
*/
|
|
344
|
-
public using<D extends ProtocolDefinition, M extends SchemaMap>(
|
|
345
|
-
protocol: TypedProtocol<D, M>,
|
|
346
|
-
): TypedDwnApi<D, M> {
|
|
347
|
-
return new TypedDwnApi<D, M>(this, protocol);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
256
|
/**
|
|
351
257
|
* API to interact with Grants
|
|
352
258
|
*
|
|
@@ -472,20 +378,21 @@ export class DwnApi {
|
|
|
472
378
|
* Configure method, used to setup a new protocol (or update) with the passed definitions
|
|
473
379
|
*/
|
|
474
380
|
configure: async (request: ProtocolsConfigureRequest): Promise<ProtocolsConfigureResponse> => {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
381
|
+
const { encryption, ...messageParams } = request;
|
|
382
|
+
|
|
383
|
+
const agentRequest: ProcessDwnRequest<DwnInterface.ProtocolsConfigure> = {
|
|
384
|
+
author : this.connectedDid,
|
|
385
|
+
messageParams,
|
|
386
|
+
messageType : DwnInterface.ProtocolsConfigure,
|
|
387
|
+
target : this.connectedDid,
|
|
388
|
+
encryption,
|
|
482
389
|
};
|
|
483
390
|
|
|
484
391
|
if (this.delegateDid) {
|
|
485
392
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
486
393
|
connectedDid : this.connectedDid,
|
|
487
394
|
delegateDid : this.delegateDid,
|
|
488
|
-
protocol :
|
|
395
|
+
protocol : messageParams.definition.protocol,
|
|
489
396
|
delegate : true,
|
|
490
397
|
cached : true,
|
|
491
398
|
messageType : agentRequest.messageType
|
|
@@ -515,11 +422,13 @@ export class DwnApi {
|
|
|
515
422
|
* Query the available protocols
|
|
516
423
|
*/
|
|
517
424
|
query: async (request: ProtocolsQueryRequest): Promise<ProtocolsQueryResponse> => {
|
|
425
|
+
const { from, ...messageParams } = request;
|
|
426
|
+
|
|
518
427
|
const agentRequest: ProcessDwnRequest<DwnInterface.ProtocolsQuery> = {
|
|
519
|
-
author
|
|
520
|
-
messageParams
|
|
521
|
-
messageType
|
|
522
|
-
target
|
|
428
|
+
author : this.connectedDid,
|
|
429
|
+
messageParams,
|
|
430
|
+
messageType : DwnInterface.ProtocolsQuery,
|
|
431
|
+
target : from || this.connectedDid,
|
|
523
432
|
};
|
|
524
433
|
|
|
525
434
|
if (this.delegateDid) {
|
|
@@ -530,7 +439,7 @@ export class DwnApi {
|
|
|
530
439
|
const { grant: { id: permissionGrantId } } = await this.permissionsApi.getPermissionForRequest({
|
|
531
440
|
connectedDid : this.connectedDid,
|
|
532
441
|
delegateDid : this.delegateDid,
|
|
533
|
-
protocol :
|
|
442
|
+
protocol : messageParams.filter.protocol,
|
|
534
443
|
cached : true,
|
|
535
444
|
messageType : agentRequest.messageType
|
|
536
445
|
});
|
|
@@ -548,7 +457,7 @@ export class DwnApi {
|
|
|
548
457
|
|
|
549
458
|
let agentResponse: DwnResponse<DwnInterface.ProtocolsQuery>;
|
|
550
459
|
|
|
551
|
-
if (
|
|
460
|
+
if (from) {
|
|
552
461
|
agentResponse = await this.agent.sendDwnRequest(agentRequest);
|
|
553
462
|
} else {
|
|
554
463
|
agentResponse = await this.agent.processDwnRequest(agentRequest);
|
|
@@ -568,11 +477,9 @@ export class DwnApi {
|
|
|
568
477
|
}
|
|
569
478
|
|
|
570
479
|
/**
|
|
571
|
-
* API to interact with DWN records (e.g., `dwn.records.
|
|
480
|
+
* API to interact with DWN records (e.g., `dwn.records.write()`).
|
|
572
481
|
*/
|
|
573
482
|
get records(): {
|
|
574
|
-
create: (request: RecordsCreateRequest) => Promise<RecordsCreateResponse>;
|
|
575
|
-
createFrom: (request: RecordsCreateFromRequest) => Promise<RecordsWriteResponse>;
|
|
576
483
|
delete: (request: RecordsDeleteRequest) => Promise<DwnResponseStatus>;
|
|
577
484
|
query: (request: RecordsQueryRequest) => Promise<RecordsQueryResponse>;
|
|
578
485
|
read: (request: RecordsReadRequest) => Promise<RecordsReadResponse>;
|
|
@@ -581,77 +488,33 @@ export class DwnApi {
|
|
|
581
488
|
} {
|
|
582
489
|
|
|
583
490
|
return {
|
|
584
|
-
/**
|
|
585
|
-
* Alias for the `write` method
|
|
586
|
-
*/
|
|
587
|
-
create: async (request: RecordsCreateRequest): Promise<RecordsCreateResponse> => {
|
|
588
|
-
return this.records.write(request);
|
|
589
|
-
},
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Write a record based on an existing one (useful for updating an existing record)
|
|
593
|
-
*/
|
|
594
|
-
createFrom: async (request: RecordsCreateFromRequest): Promise<RecordsWriteResponse> => {
|
|
595
|
-
const { author: inheritedAuthor, ...inheritedProperties } = request.record.toJSON();
|
|
596
|
-
|
|
597
|
-
// If `data` is being updated then `dataCid` and `dataSize` must not be present.
|
|
598
|
-
if (request.data !== undefined) {
|
|
599
|
-
delete inheritedProperties.dataCid;
|
|
600
|
-
delete inheritedProperties.dataSize;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// If `published` is set to false, ensure that `datePublished` is undefined. Otherwise, DWN SDK's schema validation
|
|
604
|
-
// will throw an error if `published` is false but `datePublished` is set.
|
|
605
|
-
if (request.message?.published === false && inheritedProperties.datePublished !== undefined) {
|
|
606
|
-
delete inheritedProperties.datePublished;
|
|
607
|
-
delete inheritedProperties.published;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// If the request changes the `author` or message `descriptor` then the deterministic `recordId` will change.
|
|
611
|
-
// As a result, we will discard the `recordId` if either of these changes occur.
|
|
612
|
-
if (!isEmptyObject(request.message) || (request.author && request.author !== inheritedAuthor)) {
|
|
613
|
-
delete inheritedProperties.recordId;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
// Auto-detect encryption from the source record if not explicitly set.
|
|
617
|
-
const shouldEncrypt = request.encryption
|
|
618
|
-
?? (request.record.encryption !== undefined);
|
|
619
|
-
|
|
620
|
-
return this.records.write({
|
|
621
|
-
data : request.data,
|
|
622
|
-
message : {
|
|
623
|
-
...inheritedProperties,
|
|
624
|
-
...request.message,
|
|
625
|
-
},
|
|
626
|
-
encryption: shouldEncrypt || undefined,
|
|
627
|
-
});
|
|
628
|
-
},
|
|
629
|
-
|
|
630
491
|
/**
|
|
631
492
|
* Delete a record
|
|
632
493
|
*/
|
|
633
494
|
delete: async (request: RecordsDeleteRequest): Promise<DwnResponseStatus> => {
|
|
495
|
+
const { from, protocol, ...messageParams } = request;
|
|
496
|
+
|
|
634
497
|
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsDelete> = {
|
|
635
498
|
/**
|
|
636
499
|
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
|
|
637
500
|
* connected with and is authorized to access the signing private key of.
|
|
638
501
|
*/
|
|
639
|
-
author
|
|
640
|
-
messageParams
|
|
641
|
-
messageType
|
|
502
|
+
author : this.connectedDid,
|
|
503
|
+
messageParams,
|
|
504
|
+
messageType : DwnInterface.RecordsDelete,
|
|
642
505
|
/**
|
|
643
506
|
* The `target` is the DID of the DWN tenant under which the delete will be executed.
|
|
644
507
|
* If `from` is provided, the delete operation will be executed on a remote DWN.
|
|
645
508
|
* Otherwise, the record will be deleted on the local DWN.
|
|
646
509
|
*/
|
|
647
|
-
target
|
|
510
|
+
target : from || this.connectedDid,
|
|
648
511
|
};
|
|
649
512
|
|
|
650
513
|
if (this.delegateDid) {
|
|
651
514
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
652
515
|
connectedDid : this.connectedDid,
|
|
653
516
|
delegateDid : this.delegateDid,
|
|
654
|
-
protocol
|
|
517
|
+
protocol,
|
|
655
518
|
delegate : true,
|
|
656
519
|
cached : true,
|
|
657
520
|
messageType : agentRequest.messageType
|
|
@@ -666,7 +529,7 @@ export class DwnApi {
|
|
|
666
529
|
|
|
667
530
|
let agentResponse: DwnResponse<DwnInterface.RecordsDelete>;
|
|
668
531
|
|
|
669
|
-
if (
|
|
532
|
+
if (from) {
|
|
670
533
|
agentResponse = await this.agent.sendDwnRequest(agentRequest);
|
|
671
534
|
} else {
|
|
672
535
|
agentResponse = await this.agent.processDwnRequest(agentRequest);
|
|
@@ -681,35 +544,36 @@ export class DwnApi {
|
|
|
681
544
|
* Query a single or multiple records based on the given filter
|
|
682
545
|
*/
|
|
683
546
|
query: async (request: RecordsQueryRequest): Promise<RecordsQueryResponse> => {
|
|
547
|
+
const { from, encryption, ...messageParams } = request;
|
|
548
|
+
|
|
684
549
|
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsQuery> = {
|
|
685
550
|
/**
|
|
686
551
|
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
|
|
687
552
|
* connected with and is authorized to access the signing private key of.
|
|
688
553
|
*/
|
|
689
|
-
author
|
|
690
|
-
messageParams
|
|
691
|
-
messageType
|
|
554
|
+
author : this.connectedDid,
|
|
555
|
+
messageParams,
|
|
556
|
+
messageType : DwnInterface.RecordsQuery,
|
|
692
557
|
/**
|
|
693
558
|
* The `target` is the DID of the DWN tenant under which the query will be executed.
|
|
694
559
|
* If `from` is provided, the query operation will be executed on a remote DWN.
|
|
695
560
|
* Otherwise, the local DWN will be queried.
|
|
696
561
|
*/
|
|
697
|
-
target
|
|
698
|
-
encryption
|
|
562
|
+
target : from || this.connectedDid,
|
|
563
|
+
encryption,
|
|
699
564
|
};
|
|
700
565
|
|
|
701
566
|
if (this.delegateDid) {
|
|
702
567
|
// if we don't find a delegated grant, we will attempt to query signing as the delegated DID
|
|
703
568
|
// This is to allow the API caller to query public records without needing to impersonate the delegate.
|
|
704
569
|
//
|
|
705
|
-
// NOTE:
|
|
706
|
-
//
|
|
707
|
-
// TODO: https://github.com/enboxorg/enbox/issues/898
|
|
570
|
+
// NOTE: For anonymous/public queries without explicit permissions, callers can use `DwnReaderApi` via `Web5.anonymous()`.
|
|
571
|
+
// See: https://github.com/enboxorg/enbox/issues/898
|
|
708
572
|
try {
|
|
709
573
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
710
574
|
connectedDid : this.connectedDid,
|
|
711
575
|
delegateDid : this.delegateDid,
|
|
712
|
-
protocol :
|
|
576
|
+
protocol : messageParams.filter?.protocol,
|
|
713
577
|
delegate : true,
|
|
714
578
|
cached : true,
|
|
715
579
|
messageType : agentRequest.messageType
|
|
@@ -726,10 +590,9 @@ export class DwnApi {
|
|
|
726
590
|
}
|
|
727
591
|
}
|
|
728
592
|
|
|
729
|
-
|
|
730
593
|
let agentResponse: DwnResponse<DwnInterface.RecordsQuery>;
|
|
731
594
|
|
|
732
|
-
if (
|
|
595
|
+
if (from) {
|
|
733
596
|
agentResponse = await this.agent.sendDwnRequest(agentRequest);
|
|
734
597
|
} else {
|
|
735
598
|
agentResponse = await this.agent.processDwnRequest(agentRequest);
|
|
@@ -739,7 +602,6 @@ export class DwnApi {
|
|
|
739
602
|
const { entries = [], status, cursor } = reply;
|
|
740
603
|
|
|
741
604
|
const records = entries.map((entry) => {
|
|
742
|
-
|
|
743
605
|
const recordOptions = {
|
|
744
606
|
/**
|
|
745
607
|
* Extract the `author` DID from the record entry since records may be signed by the
|
|
@@ -758,7 +620,7 @@ export class DwnApi {
|
|
|
758
620
|
* to determine which DWN to send subsequent read requests to in the event the data
|
|
759
621
|
* payload exceeds the threshold for being returned with queries.
|
|
760
622
|
*/
|
|
761
|
-
remoteOrigin :
|
|
623
|
+
remoteOrigin : from,
|
|
762
624
|
delegateDid : this.delegateDid,
|
|
763
625
|
protocolRole : agentRequest.messageParams.protocolRole,
|
|
764
626
|
...entry as DwnMessage[DwnInterface.RecordsWrite]
|
|
@@ -774,35 +636,37 @@ export class DwnApi {
|
|
|
774
636
|
* Read a single record based on the given filter
|
|
775
637
|
*/
|
|
776
638
|
read: async (request: RecordsReadRequest): Promise<RecordsReadResponse> => {
|
|
639
|
+
const { from, protocol, encryption, ...messageParams } = request;
|
|
640
|
+
|
|
777
641
|
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsRead> = {
|
|
778
642
|
/**
|
|
779
643
|
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
|
|
780
644
|
* connected with and is authorized to access the signing private key of.
|
|
781
645
|
*/
|
|
782
|
-
author
|
|
783
|
-
messageParams
|
|
784
|
-
messageType
|
|
646
|
+
author : this.connectedDid,
|
|
647
|
+
messageParams,
|
|
648
|
+
messageType : DwnInterface.RecordsRead,
|
|
785
649
|
/**
|
|
786
650
|
* The `target` is the DID of the DWN tenant under which the read will be executed.
|
|
787
651
|
* If `from` is provided, the read operation will be executed on a remote DWN.
|
|
788
652
|
* Otherwise, the read will occur on the local DWN.
|
|
789
653
|
*/
|
|
790
|
-
target
|
|
791
|
-
encryption
|
|
654
|
+
target : from || this.connectedDid,
|
|
655
|
+
encryption,
|
|
792
656
|
};
|
|
657
|
+
|
|
793
658
|
if (this.delegateDid) {
|
|
794
659
|
// if we don't find a delegated grant, we will attempt to read signing as the delegated DID
|
|
795
660
|
// This is to allow the API caller to read public records without needing to impersonate the delegate.
|
|
796
661
|
//
|
|
797
|
-
// NOTE:
|
|
798
|
-
//
|
|
799
|
-
// TODO: https://github.com/enboxorg/enbox/issues/898
|
|
662
|
+
// NOTE: For anonymous/public reads without explicit permissions, callers can use `DwnReaderApi` via `Web5.anonymous()`.
|
|
663
|
+
// See: https://github.com/enboxorg/enbox/issues/898
|
|
800
664
|
|
|
801
665
|
try {
|
|
802
666
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
803
667
|
connectedDid : this.connectedDid,
|
|
804
668
|
delegateDid : this.delegateDid,
|
|
805
|
-
protocol
|
|
669
|
+
protocol,
|
|
806
670
|
delegate : true,
|
|
807
671
|
cached : true,
|
|
808
672
|
messageType : agentRequest.messageType
|
|
@@ -821,7 +685,7 @@ export class DwnApi {
|
|
|
821
685
|
|
|
822
686
|
let agentResponse: DwnResponse<DwnInterface.RecordsRead>;
|
|
823
687
|
|
|
824
|
-
if (
|
|
688
|
+
if (from) {
|
|
825
689
|
agentResponse = await this.agent.sendDwnRequest(agentRequest);
|
|
826
690
|
} else {
|
|
827
691
|
agentResponse = await this.agent.processDwnRequest(agentRequest);
|
|
@@ -849,7 +713,7 @@ export class DwnApi {
|
|
|
849
713
|
* to determine which DWN to send subsequent read requests to in the event the data
|
|
850
714
|
* payload must be read again (e.g., if the data stream is consumed).
|
|
851
715
|
*/
|
|
852
|
-
remoteOrigin :
|
|
716
|
+
remoteOrigin : from,
|
|
853
717
|
delegateDid : this.delegateDid,
|
|
854
718
|
data : entry.data,
|
|
855
719
|
initialWrite : entry.initialWrite,
|
|
@@ -870,12 +734,14 @@ export class DwnApi {
|
|
|
870
734
|
* typed change events (`create`, `update`, `delete`).
|
|
871
735
|
*/
|
|
872
736
|
subscribe: async (request: RecordsSubscribeRequest): Promise<RecordsSubscribeResponse> => {
|
|
737
|
+
const { from, ...messageParams } = request;
|
|
738
|
+
|
|
873
739
|
// Build a DWN-level subscription handler that wraps raw RecordEvents
|
|
874
740
|
// into Record objects and feeds them into the LiveQuery.
|
|
875
741
|
let liveQuery: LiveQuery | undefined;
|
|
876
742
|
|
|
877
|
-
const remoteOrigin =
|
|
878
|
-
const protocolRole =
|
|
743
|
+
const remoteOrigin = from;
|
|
744
|
+
const protocolRole = messageParams.protocolRole;
|
|
879
745
|
|
|
880
746
|
type RecordEvent = {
|
|
881
747
|
message: DwnMessage[DwnInterface.RecordsWrite];
|
|
@@ -898,10 +764,10 @@ export class DwnApi {
|
|
|
898
764
|
};
|
|
899
765
|
|
|
900
766
|
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsSubscribe> = {
|
|
901
|
-
author
|
|
902
|
-
messageParams
|
|
903
|
-
messageType
|
|
904
|
-
target
|
|
767
|
+
author : this.connectedDid,
|
|
768
|
+
messageParams,
|
|
769
|
+
messageType : DwnInterface.RecordsSubscribe,
|
|
770
|
+
target : from || this.connectedDid,
|
|
905
771
|
subscriptionHandler,
|
|
906
772
|
};
|
|
907
773
|
|
|
@@ -909,14 +775,13 @@ export class DwnApi {
|
|
|
909
775
|
// if we don't find a delegated grant, we will attempt to subscribe signing as the delegated DID
|
|
910
776
|
// This is to allow the API caller to subscribe to public records without needing to impersonate the delegate.
|
|
911
777
|
//
|
|
912
|
-
// NOTE:
|
|
913
|
-
//
|
|
914
|
-
// TODO: https://github.com/enboxorg/enbox/issues/898
|
|
778
|
+
// NOTE: For anonymous/public subscriptions without explicit permissions, callers can use `DwnReaderApi` via `Web5.anonymous()`.
|
|
779
|
+
// See: https://github.com/enboxorg/enbox/issues/898
|
|
915
780
|
try {
|
|
916
781
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
917
782
|
connectedDid : this.connectedDid,
|
|
918
783
|
delegateDid : this.delegateDid,
|
|
919
|
-
protocol :
|
|
784
|
+
protocol : messageParams.filter?.protocol,
|
|
920
785
|
delegate : true,
|
|
921
786
|
cached : true,
|
|
922
787
|
messageType : agentRequest.messageType
|
|
@@ -935,14 +800,14 @@ export class DwnApi {
|
|
|
935
800
|
|
|
936
801
|
let agentResponse: DwnResponse<DwnInterface.RecordsSubscribe>;
|
|
937
802
|
|
|
938
|
-
if (
|
|
803
|
+
if (from) {
|
|
939
804
|
agentResponse = await this.agent.sendDwnRequest(agentRequest);
|
|
940
805
|
} else {
|
|
941
806
|
agentResponse = await this.agent.processDwnRequest(agentRequest);
|
|
942
807
|
}
|
|
943
808
|
|
|
944
809
|
const reply = agentResponse.reply;
|
|
945
|
-
const { status, subscription, entries = [] } = reply;
|
|
810
|
+
const { status, subscription, entries = [], cursor } = reply;
|
|
946
811
|
|
|
947
812
|
if (subscription) {
|
|
948
813
|
liveQuery = new LiveQuery({
|
|
@@ -953,6 +818,7 @@ export class DwnApi {
|
|
|
953
818
|
remoteOrigin,
|
|
954
819
|
permissionsApi : this.permissionsApi,
|
|
955
820
|
initialEntries : entries,
|
|
821
|
+
cursor,
|
|
956
822
|
subscription,
|
|
957
823
|
});
|
|
958
824
|
}
|
|
@@ -970,19 +836,19 @@ export class DwnApi {
|
|
|
970
836
|
* requires fetching from the DWN datastore.
|
|
971
837
|
*/
|
|
972
838
|
write: async (request: RecordsWriteRequest): Promise<RecordsWriteResponse> => {
|
|
973
|
-
const {
|
|
839
|
+
const { data, store, encryption, ...restParams } = request;
|
|
840
|
+
const { dataBlob, dataFormat } = dataToBlob(data, restParams.dataFormat);
|
|
841
|
+
|
|
842
|
+
const messageParams = { ...restParams, dataFormat };
|
|
974
843
|
|
|
975
844
|
const dwnRequestParams: ProcessDwnRequest<DwnInterface.RecordsWrite> = {
|
|
976
|
-
store
|
|
977
|
-
messageType
|
|
978
|
-
messageParams
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
target : this.connectedDid,
|
|
984
|
-
dataStream : dataBlob,
|
|
985
|
-
encryption : request.encryption,
|
|
845
|
+
store,
|
|
846
|
+
messageType : DwnInterface.RecordsWrite,
|
|
847
|
+
messageParams,
|
|
848
|
+
author : this.connectedDid,
|
|
849
|
+
target : this.connectedDid,
|
|
850
|
+
dataStream : dataBlob,
|
|
851
|
+
encryption,
|
|
986
852
|
};
|
|
987
853
|
|
|
988
854
|
// if impersonation is enabled, fetch the delegated grant to use with the write operation
|
|
@@ -990,7 +856,7 @@ export class DwnApi {
|
|
|
990
856
|
const { message: delegatedGrant } = await this.permissionsApi.getPermissionForRequest({
|
|
991
857
|
connectedDid : this.connectedDid,
|
|
992
858
|
delegateDid : this.delegateDid,
|
|
993
|
-
protocol :
|
|
859
|
+
protocol : messageParams.protocol,
|
|
994
860
|
delegate : true,
|
|
995
861
|
cached : true,
|
|
996
862
|
messageType : dwnRequestParams.messageType
|