@enbox/api 0.0.1

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.
Files changed (92) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +585 -0
  3. package/dist/browser.js +2226 -0
  4. package/dist/browser.js.map +7 -0
  5. package/dist/browser.mjs +2226 -0
  6. package/dist/browser.mjs.map +7 -0
  7. package/dist/cjs/did-api.js +126 -0
  8. package/dist/cjs/did-api.js.map +1 -0
  9. package/dist/cjs/dwn-api.js +804 -0
  10. package/dist/cjs/dwn-api.js.map +1 -0
  11. package/dist/cjs/grant-revocation.js +183 -0
  12. package/dist/cjs/grant-revocation.js.map +1 -0
  13. package/dist/cjs/index.js +63 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/package.json +1 -0
  16. package/dist/cjs/permission-grant.js +365 -0
  17. package/dist/cjs/permission-grant.js.map +1 -0
  18. package/dist/cjs/permission-request.js +272 -0
  19. package/dist/cjs/permission-request.js.map +1 -0
  20. package/dist/cjs/protocol.js +110 -0
  21. package/dist/cjs/protocol.js.map +1 -0
  22. package/dist/cjs/record.js +1127 -0
  23. package/dist/cjs/record.js.map +1 -0
  24. package/dist/cjs/subscription-util.js +86 -0
  25. package/dist/cjs/subscription-util.js.map +1 -0
  26. package/dist/cjs/utils.js +127 -0
  27. package/dist/cjs/utils.js.map +1 -0
  28. package/dist/cjs/vc-api.js +64 -0
  29. package/dist/cjs/vc-api.js.map +1 -0
  30. package/dist/cjs/web5.js +471 -0
  31. package/dist/cjs/web5.js.map +1 -0
  32. package/dist/esm/did-api.js +69 -0
  33. package/dist/esm/did-api.js.map +1 -0
  34. package/dist/esm/dwn-api.js +573 -0
  35. package/dist/esm/dwn-api.js.map +1 -0
  36. package/dist/esm/grant-revocation.js +109 -0
  37. package/dist/esm/grant-revocation.js.map +1 -0
  38. package/dist/esm/index.js +34 -0
  39. package/dist/esm/index.js.map +1 -0
  40. package/dist/esm/permission-grant.js +233 -0
  41. package/dist/esm/permission-grant.js.map +1 -0
  42. package/dist/esm/permission-request.js +166 -0
  43. package/dist/esm/permission-request.js.map +1 -0
  44. package/dist/esm/protocol.js +67 -0
  45. package/dist/esm/protocol.js.map +1 -0
  46. package/dist/esm/record.js +814 -0
  47. package/dist/esm/record.js.map +1 -0
  48. package/dist/esm/subscription-util.js +35 -0
  49. package/dist/esm/subscription-util.js.map +1 -0
  50. package/dist/esm/utils.js +120 -0
  51. package/dist/esm/utils.js.map +1 -0
  52. package/dist/esm/vc-api.js +30 -0
  53. package/dist/esm/vc-api.js.map +1 -0
  54. package/dist/esm/web5.js +281 -0
  55. package/dist/esm/web5.js.map +1 -0
  56. package/dist/types/did-api.d.ts +66 -0
  57. package/dist/types/did-api.d.ts.map +1 -0
  58. package/dist/types/dwn-api.d.ts +336 -0
  59. package/dist/types/dwn-api.d.ts.map +1 -0
  60. package/dist/types/grant-revocation.d.ts +66 -0
  61. package/dist/types/grant-revocation.d.ts.map +1 -0
  62. package/dist/types/index.d.ts +34 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/permission-grant.d.ts +157 -0
  65. package/dist/types/permission-grant.d.ts.map +1 -0
  66. package/dist/types/permission-request.d.ts +108 -0
  67. package/dist/types/permission-request.d.ts.map +1 -0
  68. package/dist/types/protocol.d.ts +59 -0
  69. package/dist/types/protocol.d.ts.map +1 -0
  70. package/dist/types/record.d.ts +441 -0
  71. package/dist/types/record.d.ts.map +1 -0
  72. package/dist/types/subscription-util.d.ts +19 -0
  73. package/dist/types/subscription-util.d.ts.map +1 -0
  74. package/dist/types/utils.d.ts +85 -0
  75. package/dist/types/utils.d.ts.map +1 -0
  76. package/dist/types/vc-api.d.ts +24 -0
  77. package/dist/types/vc-api.d.ts.map +1 -0
  78. package/dist/types/web5.d.ts +219 -0
  79. package/dist/types/web5.d.ts.map +1 -0
  80. package/package.json +111 -0
  81. package/src/did-api.ts +90 -0
  82. package/src/dwn-api.ts +952 -0
  83. package/src/grant-revocation.ts +124 -0
  84. package/src/index.ts +35 -0
  85. package/src/permission-grant.ts +327 -0
  86. package/src/permission-request.ts +214 -0
  87. package/src/protocol.ts +87 -0
  88. package/src/record.ts +1125 -0
  89. package/src/subscription-util.ts +42 -0
  90. package/src/utils.ts +128 -0
  91. package/src/vc-api.ts +30 -0
  92. package/src/web5.ts +516 -0
@@ -0,0 +1,124 @@
1
+ import { AgentPermissionsApi, DwnDataEncodedRecordsWriteMessage, DwnResponseStatus, getRecordAuthor, SendDwnRequest, Web5Agent } from '@enbox/agent';
2
+ import { DwnInterface } from '@enbox/agent';
3
+ import { Convert } from '@enbox/common';
4
+
5
+ /**
6
+ * Represents the structured data model of a GrantRevocation record, encapsulating the essential fields that define.
7
+ */
8
+ export interface GrantRevocationModel {
9
+ /** The DWN message used to construct this revocation */
10
+ rawMessage: DwnDataEncodedRecordsWriteMessage;
11
+ }
12
+
13
+ /**
14
+ * Represents the options for creating a new GrantRevocation instance.
15
+ */
16
+ export interface GrantRevocationOptions {
17
+ /** The DID of the DWN tenant under which record operations are being performed. */
18
+ connectedDid: string;
19
+ /** The DWN message used to construct this revocation */
20
+ message: DwnDataEncodedRecordsWriteMessage;
21
+ }
22
+
23
+ /**
24
+ * The `PermissionGrantRevocation` class encapsulates a permissions protocol `grant/revocation` record, providing a more
25
+ * developer-friendly interface for working with Decentralized Web Node (DWN) records.
26
+ *
27
+ * Methods are provided to manage the grant revocation's lifecycle, including writing to remote DWNs.
28
+ *
29
+ * @beta
30
+ */
31
+ export class PermissionGrantRevocation implements GrantRevocationModel {
32
+ /** The PermissionsAPI used to interact with the underlying revocation */
33
+ private _permissions: AgentPermissionsApi;
34
+ /** The DID to use as the author and default target for the underlying revocation */
35
+ private _connectedDid: string;
36
+ /** The DWN `RecordsWrite` message, along with encodedData that represents the revocation */
37
+ private _message: DwnDataEncodedRecordsWriteMessage;
38
+
39
+ private constructor(permissions: AgentPermissionsApi, options: GrantRevocationOptions) {
40
+ this._permissions = permissions;
41
+ this._connectedDid = options.connectedDid;
42
+
43
+ // Store the message that represents the grant.
44
+ this._message = options.message;
45
+ }
46
+
47
+ /** The author of the underlying revocation message */
48
+ get author() {
49
+ return getRecordAuthor(this._message);
50
+ }
51
+
52
+ /** parses the grant revocation given am agent, connectedDid and data encoded records write message */
53
+ static async parse({ connectedDid, agent, message }:{
54
+ connectedDid: string;
55
+ agent: Web5Agent;
56
+ message: DwnDataEncodedRecordsWriteMessage;
57
+ }): Promise<PermissionGrantRevocation> {
58
+ const permissions = new AgentPermissionsApi({ agent });
59
+ return new PermissionGrantRevocation(permissions, { connectedDid, message });
60
+ }
61
+
62
+ /** The agent to use for this instantiation of the grant revocation */
63
+ private get agent(): Web5Agent {
64
+ return this._permissions.agent;
65
+ }
66
+
67
+ /** The raw `RecordsWrite` DWN message with encoded data that was used to instantiate this grant revocation */
68
+ get rawMessage(): DwnDataEncodedRecordsWriteMessage {
69
+ return this._message;
70
+ }
71
+
72
+ /**
73
+ * Send the current grant revocation to a remote DWN by specifying their DID
74
+ * If no DID is specified, the target is assumed to be the owner (connectedDID).
75
+ *
76
+ * @param target - the optional DID to send the grant revocation to, if none is set it is sent to the connectedDid
77
+ * @returns the status of the send grant revocation request
78
+ *
79
+ * @beta
80
+ */
81
+ async send(target?: string): Promise<DwnResponseStatus> {
82
+ target ??= this._connectedDid;
83
+
84
+ const { encodedData, ...rawMessage } = this._message;
85
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
86
+
87
+ const sendRequestOptions: SendDwnRequest<DwnInterface.RecordsWrite> = {
88
+ messageType : DwnInterface.RecordsWrite,
89
+ author : this._connectedDid,
90
+ target : target,
91
+ dataStream,
92
+ rawMessage,
93
+ };
94
+
95
+ // Send the current/latest state to the target.
96
+ const { reply } = await this.agent.sendDwnRequest(sendRequestOptions);
97
+ return reply;
98
+ }
99
+
100
+ /**
101
+ * Stores the current grant revocation to the owner's DWN.
102
+ *
103
+ * @param importGrant - if true, the grant revocation will signed by the owner before storing it to the owner's DWN. Defaults to false.
104
+ * @returns the status of the store request
105
+ *
106
+ * @beta
107
+ */
108
+ async store(importRevocation?: boolean): Promise<DwnResponseStatus> {
109
+ const { encodedData, ...rawMessage } = this.rawMessage;
110
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
111
+
112
+ const { reply, message } = await this.agent.processDwnRequest({
113
+ author : this._connectedDid,
114
+ target : this._connectedDid,
115
+ messageType : DwnInterface.RecordsWrite,
116
+ signAsOwner : importRevocation,
117
+ rawMessage,
118
+ dataStream,
119
+ });
120
+
121
+ this._message = { ...message, encodedData: encodedData };
122
+ return { status: reply.status };
123
+ }
124
+ }
package/src/index.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Making developing with Web5 components at least 5 times easier to work with.
3
+ *
4
+ * Web5 consists of the following components:
5
+ * - Decentralized Identifiers
6
+ * - Verifiable Credentials
7
+ * - DWeb Node personal datastores
8
+ *
9
+ * The SDK sets out to gather the most oft used functionality from all three of
10
+ * these pillar technologies to provide a simple library that is as close to
11
+ * effortless as possible.
12
+ *
13
+ * The SDK is currently still under active development, but having entered the
14
+ * Tech Preview phase there is now a drive to avoid unnecessary changes unless
15
+ * backwards compatibility is provided. Additional functionality will be added
16
+ * in the lead up to 1.0 final, and modifications will be made to address
17
+ * issues and community feedback.
18
+ *
19
+ * [Link to GitHub Repo](https://github.com/TBD54566975/web5-js)
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+
24
+ export * from './did-api.js';
25
+ export * from './dwn-api.js';
26
+ export * from './grant-revocation.js';
27
+ export * from './permission-grant.js';
28
+ export * from './permission-request.js';
29
+ export * from './protocol.js';
30
+ export * from './record.js';
31
+ export * from './vc-api.js';
32
+ export * from './web5.js';
33
+
34
+ import * as utils from './utils.js';
35
+ export { utils };
@@ -0,0 +1,327 @@
1
+ import type {
2
+ DwnDataEncodedRecordsWriteMessage,
3
+ DwnPermissionConditions,
4
+ DwnPermissionScope,
5
+ DwnResponseStatus,
6
+ SendDwnRequest,
7
+ Web5Agent
8
+ } from '@enbox/agent';
9
+
10
+ import { Convert } from '@enbox/common';
11
+ import {
12
+ AgentPermissionsApi,
13
+ DwnInterface,
14
+ DwnPermissionGrant,
15
+ } from '@enbox/agent';
16
+ import { PermissionGrantRevocation } from './grant-revocation.js';
17
+
18
+ /**
19
+ * Represents the structured data model of a PermissionGrant record, encapsulating the essential fields that define
20
+ */
21
+ export interface PermissionGrantModel {
22
+ /**
23
+ * The ID of the permission grant, which is the record ID DWN message.
24
+ */
25
+ readonly id: string;
26
+
27
+ /**
28
+ * The grantor of the permission.
29
+ */
30
+ readonly grantor: string;
31
+
32
+ /**
33
+ * The grantee of the permission.
34
+ */
35
+ readonly grantee: string;
36
+
37
+ /**
38
+ * The date at which the grant was given.
39
+ */
40
+ readonly dateGranted: string;
41
+
42
+ /**
43
+ * Optional string that communicates what the grant would be used for
44
+ */
45
+ readonly description?: string;
46
+
47
+ /**
48
+ * Optional CID of a permission request. This is optional because grants may be given without being officially requested
49
+ */
50
+ readonly requestId?: string;
51
+
52
+ /**
53
+ * Timestamp at which this grant will no longer be active.
54
+ */
55
+ readonly dateExpires: string;
56
+
57
+ /**
58
+ * Whether this grant is delegated or not. If `true`, the `grantedTo` will be able to act as the `grantedTo` within the scope of this grant.
59
+ */
60
+ readonly delegated?: boolean;
61
+
62
+ /**
63
+ * The scope of the allowed access.
64
+ */
65
+ readonly scope: DwnPermissionScope;
66
+
67
+ /**
68
+ * Optional conditions that must be met when the grant is used.
69
+ */
70
+ readonly conditions?: DwnPermissionConditions;
71
+ }
72
+
73
+ /**
74
+ * Represents the options for creating a new PermissionGrant instance.
75
+ */
76
+ export interface PermissionGrantOptions {
77
+ /** The DID to use when interacting with the underlying DWN record representing the grant */
78
+ connectedDid: string;
79
+ /** The underlying DWN `RecordsWrite` message along with encoded data that represent the grant */
80
+ message: DwnDataEncodedRecordsWriteMessage;
81
+ /** The agent to use when interacting with the underlying DWN record representing the grant */
82
+ agent: Web5Agent;
83
+ }
84
+
85
+ /**
86
+ * The `PermissionGrant` class encapsulates a permissions protocol `grant` record, providing a more
87
+ * developer-friendly interface for working with Decentralized Web Node (DWN) records.
88
+ *
89
+ * Methods are provided to revoke, check if isRevoked, and manage the grant's lifecycle, including writing to remote DWNs.
90
+ *
91
+ * @beta
92
+ */
93
+ export class PermissionGrant implements PermissionGrantModel {
94
+ /** The PermissionsAPI used to interact with the underlying permission grant */
95
+ private _permissions: AgentPermissionsApi;
96
+ /** The DID to use as the author and default target for the underlying permission grant */
97
+ private _connectedDid: string;
98
+ /** The underlying DWN `RecordsWrite` message along with encoded data that represent the grant */
99
+ private _message: DwnDataEncodedRecordsWriteMessage;
100
+ /** The parsed grant object */
101
+ private _grant: DwnPermissionGrant;
102
+
103
+ private constructor({ api, connectedDid, message, grant }:{
104
+ api: AgentPermissionsApi;
105
+ connectedDid: string;
106
+ message: DwnDataEncodedRecordsWriteMessage;
107
+ grant: DwnPermissionGrant;
108
+ }) {
109
+ this._permissions = api;
110
+
111
+ // Store the connected DID for convenience.
112
+ this._connectedDid = connectedDid;
113
+
114
+ // Store the message that represents the grant.
115
+ this._message = message;
116
+
117
+ // Store the parsed grant object.
118
+ this._grant = grant;
119
+ }
120
+
121
+ /** parses the grant given an agent, connectedDid and data encoded records write message */
122
+ static async parse(options: PermissionGrantOptions): Promise<PermissionGrant> {
123
+ //TODO: this does not have to be async https://github.com/TBD54566975/web5-js/pull/831/files
124
+ const grant = await DwnPermissionGrant.parse(options.message);
125
+ const api = new AgentPermissionsApi({ agent: options.agent });
126
+ return new PermissionGrant({ ...options, grant, api });
127
+ }
128
+
129
+ /** The agent to use for this instantiation of the grant */
130
+ private get agent(): Web5Agent {
131
+ return this._permissions.agent;
132
+ }
133
+
134
+ /** The grant's ID, which is also the underlying record's ID */
135
+ get id(): string {
136
+ return this._grant.id;
137
+ }
138
+
139
+ /** The DID which granted the permission */
140
+ get grantor(): string {
141
+ return this._grant.grantor;
142
+ }
143
+
144
+ /** The DID which the permission was granted to */
145
+ get grantee(): string {
146
+ return this._grant.grantee;
147
+ }
148
+
149
+ /** The date the permission was granted */
150
+ get dateGranted(): string {
151
+ return this._grant.dateGranted;
152
+ }
153
+
154
+ /** (optional) Description of the permission grant */
155
+ get description(): string | undefined {
156
+ return this._grant.description;
157
+ }
158
+
159
+ /** (optional) The Id of the PermissionRequest if one was used */
160
+ get requestId(): string | undefined {
161
+ return this._grant.requestId;
162
+ }
163
+
164
+ /** The date on which the permission expires */
165
+ get dateExpires(): string {
166
+ return this._grant.dateExpires;
167
+ }
168
+
169
+ /** Whether or not the permission grant can be used to impersonate the grantor */
170
+ get delegated(): boolean | undefined {
171
+ return this._grant.delegated;
172
+ }
173
+
174
+ /** The permission scope under which the grant is valid */
175
+ get scope(): DwnPermissionScope {
176
+ return this._grant.scope;
177
+ }
178
+
179
+ /** The conditions under which the grant is valid */
180
+ get conditions(): DwnPermissionConditions {
181
+ return this._grant.conditions;
182
+ }
183
+
184
+ /** The raw `RecordsWrite` DWN message with encoded data that was used to instantiate this grant */
185
+ get rawMessage(): DwnDataEncodedRecordsWriteMessage {
186
+ return this._message;
187
+ }
188
+
189
+ /**
190
+ * Send the current grant to a remote DWN by specifying their DID
191
+ * If no DID is specified, the target is assumed to be the owner (connectedDID).
192
+ *
193
+ * @param target - the optional DID to send the grant to, if none is set it is sent to the connectedDid
194
+ * @returns the status of the send grant request
195
+ *
196
+ * @beta
197
+ */
198
+ async send(target?: string): Promise<DwnResponseStatus> {
199
+ target ??= this._connectedDid;
200
+
201
+ const { encodedData, ...rawMessage } = this._message;
202
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
203
+
204
+ const sendRequestOptions: SendDwnRequest<DwnInterface.RecordsWrite> = {
205
+ messageType : DwnInterface.RecordsWrite,
206
+ author : this._connectedDid,
207
+ target : target,
208
+ dataStream,
209
+ rawMessage,
210
+ };
211
+
212
+ // Send the current/latest state to the target.
213
+ const { reply } = await this.agent.sendDwnRequest(sendRequestOptions);
214
+ return reply;
215
+ }
216
+
217
+ /**
218
+ * Stores the current grant to the owner's DWN.
219
+ *
220
+ * @param importGrant - if true, the grant will signed by the owner before storing it to the owner's DWN. Defaults to false.
221
+ * @returns the status of the store request
222
+ *
223
+ * @beta
224
+ */
225
+ async store(importGrant: boolean = false): Promise<DwnResponseStatus> {
226
+ const { encodedData, ...rawMessage } = this.rawMessage;
227
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
228
+
229
+ const { reply, message } = await this.agent.processDwnRequest({
230
+ store : true,
231
+ author : this._connectedDid,
232
+ target : this._connectedDid,
233
+ messageType : DwnInterface.RecordsWrite,
234
+ signAsOwner : importGrant,
235
+ rawMessage,
236
+ dataStream,
237
+ });
238
+
239
+ this._message = { ...message, encodedData: encodedData };
240
+ return { status: reply.status };
241
+ }
242
+
243
+ /**
244
+ * Signs the current grant as the owner and optionally stores it to the owner's DWN.
245
+ * This is useful when importing a grant that was signed by someone else into your own DWN.
246
+ *
247
+ * @param store - if true, the grant will be stored to the owner's DWN after signing. Defaults to true.
248
+ * @returns the status of the import request
249
+ *
250
+ * @beta
251
+ */
252
+ async import(store: boolean = false): Promise<DwnResponseStatus> {
253
+ const { encodedData, ...rawMessage } = this.rawMessage;
254
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
255
+
256
+ const { reply, message } = await this.agent.processDwnRequest({
257
+ store,
258
+ author : this._connectedDid,
259
+ target : this._connectedDid,
260
+ messageType : DwnInterface.RecordsWrite,
261
+ signAsOwner : true,
262
+ rawMessage,
263
+ dataStream,
264
+ });
265
+
266
+ this._message = { ...message, encodedData: encodedData };
267
+ return { status: reply.status };
268
+ }
269
+
270
+ /**
271
+ * Revokes the grant and optionally stores the revocation to the owner's DWN.
272
+ *
273
+ * @param store - if true, the revocation will be stored to the owner's DWN. Defaults to true.
274
+ * @returns {PermissionGrantRevocation} the grant revocation object
275
+ *
276
+ * @beta
277
+ */
278
+ async revoke(store: boolean = true): Promise<PermissionGrantRevocation> {
279
+ const revocation = await this._permissions.createRevocation({
280
+ store,
281
+ author : this._connectedDid,
282
+ grant : this._grant,
283
+ });
284
+
285
+ return PermissionGrantRevocation.parse({
286
+ connectedDid : this._connectedDid,
287
+ agent : this.agent,
288
+ message : revocation.message,
289
+ });
290
+ }
291
+
292
+ /**
293
+ * Checks if the grant has been revoked.
294
+ *
295
+ * @param remote - if true, the check will be made against the remote DWN. Defaults to false.
296
+ * @returns true if the grant has been revoked, false otherwise.
297
+ * @throws if there is an error checking the revocation status.
298
+ *
299
+ * @beta
300
+ */
301
+ isRevoked(remote: boolean = false): Promise<boolean> {
302
+ return this._permissions.isGrantRevoked({
303
+ author : this._connectedDid,
304
+ target : this.grantor,
305
+ grantRecordId : this.id,
306
+ remote
307
+ });
308
+ }
309
+
310
+ /**
311
+ * @returns the JSON representation of the grant
312
+ */
313
+ toJSON(): DwnPermissionGrant {
314
+ return {
315
+ id : this.id,
316
+ grantor : this.grantor,
317
+ grantee : this.grantee,
318
+ dateGranted : this.dateGranted,
319
+ description : this.description,
320
+ requestId : this.requestId,
321
+ dateExpires : this.dateExpires,
322
+ delegated : this.delegated,
323
+ scope : this.scope,
324
+ conditions : this.conditions
325
+ };
326
+ }
327
+ }
@@ -0,0 +1,214 @@
1
+ import { AgentPermissionsApi, DwnDataEncodedRecordsWriteMessage, DwnPermissionConditions, DwnPermissionRequest, DwnPermissionScope, DwnResponseStatus, SendDwnRequest, Web5Agent } from '@enbox/agent';
2
+ import { DwnInterface } from '@enbox/agent';
3
+ import { Convert } from '@enbox/common';
4
+ import { PermissionGrant } from './permission-grant.js';
5
+
6
+ /**
7
+ * Represents the structured data model of a PermissionsRequest record, encapsulating the essential fields that define
8
+ * the request's data and payload within a Decentralized Web Node (DWN).
9
+ */
10
+ export interface PermissionRequestModel {
11
+ /**
12
+ * The ID of the permission request, which is the record ID DWN message.
13
+ */
14
+ readonly id: string;
15
+
16
+ /**
17
+ * The requester for of the permission.
18
+ */
19
+ readonly requester: string;
20
+
21
+ /**
22
+ * Optional string that communicates what the requested grant would be used for.
23
+ */
24
+ readonly description?: string;
25
+
26
+ /**
27
+ * Whether the requested grant is delegated or not.
28
+ * If `true`, the `requestor` will be able to act as the grantor of the permission within the scope of the requested grant.
29
+ */
30
+ readonly delegated?: boolean;
31
+
32
+ /**
33
+ * The scope of the allowed access.
34
+ */
35
+ readonly scope: DwnPermissionScope;
36
+
37
+ /**
38
+ * Optional conditions that must be met when the requested grant is used.
39
+ */
40
+ readonly conditions?: DwnPermissionConditions;
41
+ }
42
+
43
+ /**
44
+ * The `PermissionRequest` class encapsulates a permissions protocol `request` record, providing a more
45
+ * developer-friendly interface for working with Decentralized Web Node (DWN) records.
46
+ *
47
+ * Methods are provided to grant the request and manage the request's lifecycle, including writing to remote DWNs.
48
+ *
49
+ * @beta
50
+ */
51
+ export class PermissionRequest implements PermissionRequestModel {
52
+ /** The PermissionsAPI used to interact with the underlying permission request */
53
+ private _permissions: AgentPermissionsApi;
54
+ /** The DID to use as the author and default target for the underlying permission request */
55
+ private _connectedDid: string;
56
+ /** The underlying DWN `RecordsWrite` message along with encoded data that represent the request */
57
+ private _message: DwnDataEncodedRecordsWriteMessage;
58
+ /** The parsed permission request object */
59
+ private _request: DwnPermissionRequest;
60
+
61
+ private constructor({ api, connectedDid, message, request }: {
62
+ api: AgentPermissionsApi;
63
+ connectedDid: string;
64
+ message: DwnDataEncodedRecordsWriteMessage;
65
+ request: DwnPermissionRequest;
66
+ }) {
67
+ this._permissions = api;
68
+ this._connectedDid = connectedDid;
69
+
70
+ // Store the parsed request object.
71
+ this._request = request;
72
+
73
+ // Store the message that represents the grant.
74
+ this._message = message;
75
+ }
76
+
77
+ /** parses the request given an agent, connectedDid and data encoded records write message */
78
+ static async parse({ connectedDid, agent, message }:{
79
+ connectedDid: string;
80
+ agent: Web5Agent;
81
+ message: DwnDataEncodedRecordsWriteMessage;
82
+ }): Promise<PermissionRequest> {
83
+ //TODO: this does not have to be async https://github.com/TBD54566975/web5-js/pull/831/files
84
+ const request = await DwnPermissionRequest.parse(message);
85
+ const api = new AgentPermissionsApi({ agent });
86
+ return new PermissionRequest({ api, connectedDid, message, request });
87
+ }
88
+
89
+ /** The agent to use for this instantiation of the request */
90
+ private get agent(): Web5Agent {
91
+ return this._permissions.agent;
92
+ }
93
+
94
+ /** The request's ID, which is also the underlying record's ID */
95
+ get id() {
96
+ return this._request.id;
97
+ }
98
+
99
+ /** The DID that is requesting a permission */
100
+ get requester() {
101
+ return this._request.requester;
102
+ }
103
+
104
+ /** (optional) Description of the permission request */
105
+ get description() {
106
+ return this._request.description;
107
+ }
108
+
109
+ /** Whether or not the permission request can be used to impersonate the grantor */
110
+ get delegated() {
111
+ return this._request.delegated;
112
+ }
113
+
114
+ /** The permission scope under which the requested grant would be valid */
115
+ get scope() {
116
+ return this._request.scope;
117
+ }
118
+
119
+ /** The conditions under which the requested grant would be valid */
120
+ get conditions() {
121
+ return this._request.conditions;
122
+ }
123
+
124
+ /** The `RecordsWrite` DWN message with encoded data that was used to instantiate this request */
125
+ get rawMessage(): DwnDataEncodedRecordsWriteMessage {
126
+ return this._message;
127
+ }
128
+
129
+ /**
130
+ * Send the current permission request to a remote DWN by specifying their DID
131
+ * If no DID is specified, the target is assumed to be the owner (connectedDID).
132
+ *
133
+ * @param target - the optional DID to send the permission request to, if none is set it is sent to the connectedDid
134
+ * @returns the status of the send permission request
135
+ *
136
+ * @beta
137
+ */
138
+ async send(target?: string): Promise<DwnResponseStatus> {
139
+ target ??= this._connectedDid;
140
+
141
+ const { encodedData, ...rawMessage } = this._message;
142
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
143
+
144
+ const sendRequestOptions: SendDwnRequest<DwnInterface.RecordsWrite> = {
145
+ messageType : DwnInterface.RecordsWrite,
146
+ author : this._connectedDid,
147
+ target : target,
148
+ dataStream,
149
+ rawMessage,
150
+ };
151
+
152
+ // Send the current/latest state to the target.
153
+ const { reply } = await this.agent.sendDwnRequest(sendRequestOptions);
154
+ return reply;
155
+ }
156
+
157
+ /**
158
+ * Stores the current permission request to the owner's DWN.
159
+ *
160
+ * @param importGrant - if true, the permission request will signed by the owner before storing it to the owner's DWN. Defaults to false.
161
+ * @returns the status of the store request
162
+ *
163
+ * @beta
164
+ */
165
+ async store(): Promise<DwnResponseStatus> {
166
+ const { encodedData, ...rawMessage } = this.rawMessage;
167
+ const dataStream = new Blob([ Convert.base64Url(encodedData).toUint8Array() ]);
168
+
169
+ const { reply, message } = await this.agent.processDwnRequest({
170
+ author : this._connectedDid,
171
+ target : this._connectedDid,
172
+ messageType : DwnInterface.RecordsWrite,
173
+ rawMessage,
174
+ dataStream,
175
+ });
176
+
177
+ this._message = { ...message, encodedData: encodedData };
178
+ return { status: reply.status };
179
+ }
180
+
181
+ /**
182
+ * Grants the permission request to the requester.
183
+ *
184
+ * @param dateExpires - the date when the permission grant will expire.
185
+ * @param store - if true, the permission grant will be stored in the owner's DWN. Defaults to true.
186
+ * @returns {PermissionGrant} the granted permission.
187
+ *
188
+ * @beta
189
+ */
190
+ async grant(dateExpires: string, store: boolean = true): Promise<PermissionGrant> {
191
+ const { message } = await this._permissions.createGrant({
192
+ requestId : this.id,
193
+ grantedTo : this.requester,
194
+ scope : this.scope,
195
+ delegated : this.delegated,
196
+ author : this._connectedDid,
197
+ store,
198
+ dateExpires,
199
+ });
200
+
201
+ return PermissionGrant.parse({
202
+ connectedDid : this._connectedDid,
203
+ agent : this.agent,
204
+ message
205
+ });
206
+ }
207
+
208
+ /**
209
+ * @returns the JSON representation of the permission request
210
+ */
211
+ toJSON(): PermissionRequestModel {
212
+ return this._request;
213
+ }
214
+ }