UNPKG

@enbox/api

Version:

SDK for accessing the features and capabilities of Web5

784 lines 51 kB
"use strict"; /** * NOTE: Added reference types here to avoid a `pnpm` bug during build. * https://github.com/TBD54566975/web5-js/pull/507 */ /// <reference types="@enbox/dwn-sdk-js" /> var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DwnApi = void 0; var agent_1 = require("@enbox/agent"); var common_1 = require("@enbox/common"); var agent_2 = require("@enbox/agent"); var record_js_1 = require("./record.js"); var utils_js_1 = require("./utils.js"); var protocol_js_1 = require("./protocol.js"); var permission_grant_js_1 = require("./permission-grant.js"); var permission_request_js_1 = require("./permission-request.js"); var subscription_util_js_1 = require("./subscription-util.js"); /** * Interface to interact with DWN Records and Protocols */ var DwnApi = /** @class */ (function () { function DwnApi(options) { this.agent = options.agent; this.connectedDid = options.connectedDid; this.delegateDid = options.delegateDid; this.permissionsApi = new agent_1.AgentPermissionsApi({ agent: this.agent }); } Object.defineProperty(DwnApi.prototype, "permissions", { /** * API to interact with Grants * * NOTE: This is an EXPERIMENTAL API that will change behavior. * * Currently only supports issuing requests, grants, revokes and queries on behalf without permissions or impersonation. * If the agent is connected to a delegateDid, the delegateDid will be used to sign/author the underlying records. * If the agent is not connected to a delegateDid, the connectedDid will be used to sign/author the underlying records. * * @beta */ get: function () { var _this = this; return { /** * Request permission for a specific scope. */ request: function (request) { return __awaiter(_this, void 0, void 0, function () { var message, requestParams; var _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.permissionsApi.createRequest(__assign(__assign({}, request), { author: (_a = this.delegateDid) !== null && _a !== void 0 ? _a : this.connectedDid }))]; case 1: message = (_c.sent()).message; requestParams = { connectedDid: (_b = this.delegateDid) !== null && _b !== void 0 ? _b : this.connectedDid, agent: this.agent, message: message, }; return [4 /*yield*/, permission_request_js_1.PermissionRequest.parse(requestParams)]; case 2: return [2 /*return*/, _c.sent()]; } }); }); }, /** * Grant permission for a specific scope to a grantee DID. */ grant: function (request) { return __awaiter(_this, void 0, void 0, function () { var message, grantParams; var _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.permissionsApi.createGrant(__assign(__assign({}, request), { author: (_a = this.delegateDid) !== null && _a !== void 0 ? _a : this.connectedDid }))]; case 1: message = (_c.sent()).message; grantParams = { connectedDid: (_b = this.delegateDid) !== null && _b !== void 0 ? _b : this.connectedDid, agent: this.agent, message: message, }; return [4 /*yield*/, permission_grant_js_1.PermissionGrant.parse(grantParams)]; case 2: return [2 /*return*/, _c.sent()]; } }); }); }, /** * Query permission requests. You can filter by protocol and specify if you want to query a remote DWN. */ queryRequests: function (request) { if (request === void 0) { request = {}; } return __awaiter(_this, void 0, void 0, function () { var from, params, fetchResponse, requests, fetchResponse_1, fetchResponse_1_1, permission, requestParams, _a, _b, e_1_1; var e_1, _c; var _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: from = request.from, params = __rest(request, ["from"]); return [4 /*yield*/, this.permissionsApi.fetchRequests(__assign(__assign({}, params), { author: (_d = this.delegateDid) !== null && _d !== void 0 ? _d : this.connectedDid, target: (_e = from !== null && from !== void 0 ? from : this.delegateDid) !== null && _e !== void 0 ? _e : this.connectedDid, remote: from !== undefined }))]; case 1: fetchResponse = _g.sent(); requests = []; _g.label = 2; case 2: _g.trys.push([2, 7, 8, 9]); fetchResponse_1 = __values(fetchResponse), fetchResponse_1_1 = fetchResponse_1.next(); _g.label = 3; case 3: if (!!fetchResponse_1_1.done) return [3 /*break*/, 6]; permission = fetchResponse_1_1.value; requestParams = { connectedDid: (_f = this.delegateDid) !== null && _f !== void 0 ? _f : this.connectedDid, agent: this.agent, message: permission.message, }; _b = (_a = requests).push; return [4 /*yield*/, permission_request_js_1.PermissionRequest.parse(requestParams)]; case 4: _b.apply(_a, [_g.sent()]); _g.label = 5; case 5: fetchResponse_1_1 = fetchResponse_1.next(); return [3 /*break*/, 3]; case 6: return [3 /*break*/, 9]; case 7: e_1_1 = _g.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 9]; case 8: try { if (fetchResponse_1_1 && !fetchResponse_1_1.done && (_c = fetchResponse_1.return)) _c.call(fetchResponse_1); } finally { if (e_1) throw e_1.error; } return [7 /*endfinally*/]; case 9: return [2 /*return*/, requests]; } }); }); }, /** * Query permission grants. You can filter by grantee, grantor, protocol and specify if you want to query a remote DWN. */ queryGrants: function (request) { if (request === void 0) { request = {}; } return __awaiter(_this, void 0, void 0, function () { var checkRevoked, from, params, remote, author, target, fetchResponse, grants, fetchResponse_2, fetchResponse_2_1, permission, grantParams, grantRecordId, _a, _b, e_2_1; var e_2, _c; var _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: checkRevoked = request.checkRevoked, from = request.from, params = __rest(request, ["checkRevoked", "from"]); remote = from !== undefined; author = (_d = this.delegateDid) !== null && _d !== void 0 ? _d : this.connectedDid; target = (_e = from !== null && from !== void 0 ? from : this.delegateDid) !== null && _e !== void 0 ? _e : this.connectedDid; return [4 /*yield*/, this.permissionsApi.fetchGrants(__assign(__assign({}, params), { author: author, target: target, remote: remote }))]; case 1: fetchResponse = _g.sent(); grants = []; _g.label = 2; case 2: _g.trys.push([2, 9, 10, 11]); fetchResponse_2 = __values(fetchResponse), fetchResponse_2_1 = fetchResponse_2.next(); _g.label = 3; case 3: if (!!fetchResponse_2_1.done) return [3 /*break*/, 8]; permission = fetchResponse_2_1.value; grantParams = { connectedDid: (_f = this.delegateDid) !== null && _f !== void 0 ? _f : this.connectedDid, agent: this.agent, message: permission.message, }; if (!checkRevoked) return [3 /*break*/, 5]; grantRecordId = permission.grant.id; return [4 /*yield*/, this.permissionsApi.isGrantRevoked({ author: author, target: target, grantRecordId: grantRecordId, remote: remote })]; case 4: if (_g.sent()) { return [3 /*break*/, 7]; } _g.label = 5; case 5: _b = (_a = grants).push; return [4 /*yield*/, permission_grant_js_1.PermissionGrant.parse(grantParams)]; case 6: _b.apply(_a, [_g.sent()]); _g.label = 7; case 7: fetchResponse_2_1 = fetchResponse_2.next(); return [3 /*break*/, 3]; case 8: return [3 /*break*/, 11]; case 9: e_2_1 = _g.sent(); e_2 = { error: e_2_1 }; return [3 /*break*/, 11]; case 10: try { if (fetchResponse_2_1 && !fetchResponse_2_1.done && (_c = fetchResponse_2.return)) _c.call(fetchResponse_2); } finally { if (e_2) throw e_2.error; } return [7 /*endfinally*/]; case 11: return [2 /*return*/, grants]; } }); }); } }; }, enumerable: false, configurable: true }); Object.defineProperty(DwnApi.prototype, "protocols", { /** * API to interact with DWN protocols (e.g., `dwn.protocols.configure()`). */ get: function () { var _this = this; return { /** * Configure method, used to setup a new protocol (or update) with the passed definitions */ configure: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, delegatedGrant, agentResponse, message, messageCid, status, response, metadata; return __generator(this, function (_a) { switch (_a.label) { case 0: agentRequest = { author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.ProtocolsConfigure, target: this.connectedDid }; if (!this.delegateDid) return [3 /*break*/, 2]; return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.message.definition.protocol, delegate: true, cached: true, messageType: agentRequest.messageType })]; case 1: delegatedGrant = (_a.sent()).message; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { delegatedGrant: delegatedGrant }); agentRequest.granteeDid = this.delegateDid; _a.label = 2; case 2: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 3: agentResponse = _a.sent(); message = agentResponse.message, messageCid = agentResponse.messageCid, status = agentResponse.reply.status; response = { status: status }; if (status.code < 300) { metadata = { author: this.connectedDid, messageCid: messageCid }; response.protocol = new protocol_js_1.Protocol(this.agent, message, metadata); } return [2 /*return*/, response]; } }); }); }, /** * Query the available protocols */ query: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, permissionGrantId, _error_1, agentResponse, reply, _a, entries, status, protocols; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: agentRequest = { author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.ProtocolsQuery, target: request.from || this.connectedDid }; if (!this.delegateDid) return [3 /*break*/, 4]; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.message.filter.protocol, cached: true, messageType: agentRequest.messageType })]; case 2: permissionGrantId = (_b.sent()).grant.id; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { permissionGrantId: permissionGrantId }); agentRequest.granteeDid = this.delegateDid; return [3 /*break*/, 4]; case 3: _error_1 = _b.sent(); // if a grant is not found, we should author the request as the delegated DID to get public protocols agentRequest.author = this.delegateDid; return [3 /*break*/, 4]; case 4: if (!request.from) return [3 /*break*/, 6]; return [4 /*yield*/, this.agent.sendDwnRequest(agentRequest)]; case 5: agentResponse = _b.sent(); return [3 /*break*/, 8]; case 6: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 7: agentResponse = _b.sent(); _b.label = 8; case 8: reply = agentResponse.reply; _a = reply.entries, entries = _a === void 0 ? [] : _a, status = reply.status; protocols = entries.map(function (entry) { var metadata = { author: _this.connectedDid }; return new protocol_js_1.Protocol(_this.agent, entry, metadata); }); return [2 /*return*/, { protocols: protocols, status: status }]; } }); }); } }; }, enumerable: false, configurable: true }); Object.defineProperty(DwnApi.prototype, "records", { /** * API to interact with DWN records (e.g., `dwn.records.create()`). */ get: function () { var _this = this; return { /** * Alias for the `write` method */ create: function (request) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.records.write(request)]; }); }); }, /** * Write a record based on an existing one (useful for updating an existing record) */ createFrom: function (request) { return __awaiter(_this, void 0, void 0, function () { var _a, inheritedAuthor, inheritedProperties; var _b; return __generator(this, function (_c) { _a = request.record.toJSON(), inheritedAuthor = _a.author, inheritedProperties = __rest(_a, ["author"]); // If `data` is being updated then `dataCid` and `dataSize` must not be present. if (request.data !== undefined) { delete inheritedProperties.dataCid; delete inheritedProperties.dataSize; } // If `published` is set to false, ensure that `datePublished` is undefined. Otherwise, DWN SDK's schema validation // will throw an error if `published` is false but `datePublished` is set. if (((_b = request.message) === null || _b === void 0 ? void 0 : _b.published) === false && inheritedProperties.datePublished !== undefined) { delete inheritedProperties.datePublished; delete inheritedProperties.published; } // If the request changes the `author` or message `descriptor` then the deterministic `recordId` will change. // As a result, we will discard the `recordId` if either of these changes occur. if (!(0, common_1.isEmptyObject)(request.message) || (request.author && request.author !== inheritedAuthor)) { delete inheritedProperties.recordId; } return [2 /*return*/, this.records.write({ data: request.data, message: __assign(__assign({}, inheritedProperties), request.message), })]; }); }); }, /** * Delete a record */ delete: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, delegatedGrant, agentResponse, status; return __generator(this, function (_a) { switch (_a.label) { case 0: agentRequest = { /** * The `author` is the DID that will sign the message and must be the DID the Web5 app is * connected with and is authorized to access the signing private key of. */ author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.RecordsDelete, /** * The `target` is the DID of the DWN tenant under which the delete will be executed. * If `from` is provided, the delete operation will be executed on a remote DWN. * Otherwise, the record will be deleted on the local DWN. */ target: request.from || this.connectedDid }; if (!this.delegateDid) return [3 /*break*/, 2]; return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.protocol, delegate: true, cached: true, messageType: agentRequest.messageType })]; case 1: delegatedGrant = (_a.sent()).message; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { delegatedGrant: delegatedGrant }); agentRequest.granteeDid = this.delegateDid; _a.label = 2; case 2: if (!request.from) return [3 /*break*/, 4]; return [4 /*yield*/, this.agent.sendDwnRequest(agentRequest)]; case 3: agentResponse = _a.sent(); return [3 /*break*/, 6]; case 4: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 5: agentResponse = _a.sent(); _a.label = 6; case 6: status = agentResponse.reply.status; return [2 /*return*/, { status: status }]; } }); }); }, /** * Query a single or multiple records based on the given filter */ query: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, delegatedGrant, _error_2, agentResponse, reply, _a, entries, status, cursor, records; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: agentRequest = { /** * The `author` is the DID that will sign the message and must be the DID the Web5 app is * connected with and is authorized to access the signing private key of. */ author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.RecordsQuery, /** * The `target` is the DID of the DWN tenant under which the query will be executed. * If `from` is provided, the query operation will be executed on a remote DWN. * Otherwise, the local DWN will be queried. */ target: request.from || this.connectedDid }; if (!this.delegateDid) return [3 /*break*/, 4]; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.protocol, delegate: true, cached: true, messageType: agentRequest.messageType })]; case 2: delegatedGrant = (_b.sent()).message; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { delegatedGrant: delegatedGrant }); agentRequest.granteeDid = this.delegateDid; return [3 /*break*/, 4]; case 3: _error_2 = _b.sent(); // if a grant is not found, we should author the request as the delegated DID to get public records agentRequest.author = this.delegateDid; return [3 /*break*/, 4]; case 4: if (!request.from) return [3 /*break*/, 6]; return [4 /*yield*/, this.agent.sendDwnRequest(agentRequest)]; case 5: agentResponse = _b.sent(); return [3 /*break*/, 8]; case 6: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 7: agentResponse = _b.sent(); _b.label = 8; case 8: reply = agentResponse.reply; _a = reply.entries, entries = _a === void 0 ? [] : _a, status = reply.status, cursor = reply.cursor; records = entries.map(function (entry) { var recordOptions = __assign({ /** * Extract the `author` DID from the record entry since records may be signed by the * tenant owner or any other entity. */ author: (0, agent_2.getRecordAuthor)(entry), /** * Set the `connectedDid` to currently connected DID so that subsequent calls to * {@link Record} instance methods, such as `record.update()` are executed on the * local DWN even if the record was returned by a query of a remote DWN. */ connectedDid: _this.connectedDid, /** * If the record was returned by a query of a remote DWN, set the `remoteOrigin` to * the DID of the DWN that returned the record. The `remoteOrigin` property will be used * to determine which DWN to send subsequent read requests to in the event the data * payload exceeds the threshold for being returned with queries. */ remoteOrigin: request.from, delegateDid: _this.delegateDid, protocolRole: agentRequest.messageParams.protocolRole }, entry); var record = new record_js_1.Record(_this.agent, recordOptions, _this.permissionsApi); return record; }); return [2 /*return*/, { records: records, status: status, cursor: cursor }]; } }); }); }, /** * Read a single record based on the given filter */ read: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, delegatedGrant, _error_3, agentResponse, _a, entry, status, record, recordOptions; return __generator(this, function (_b) { switch (_b.label) { case 0: agentRequest = { /** * The `author` is the DID that will sign the message and must be the DID the Web5 app is * connected with and is authorized to access the signing private key of. */ author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.RecordsRead, /** * The `target` is the DID of the DWN tenant under which the read will be executed. * If `from` is provided, the read operation will be executed on a remote DWN. * Otherwise, the read will occur on the local DWN. */ target: request.from || this.connectedDid }; if (!this.delegateDid) return [3 /*break*/, 4]; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.protocol, delegate: true, cached: true, messageType: agentRequest.messageType })]; case 2: delegatedGrant = (_b.sent()).message; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { delegatedGrant: delegatedGrant }); agentRequest.granteeDid = this.delegateDid; return [3 /*break*/, 4]; case 3: _error_3 = _b.sent(); // if a grant is not found, we should author the request as the delegated DID to get public records agentRequest.author = this.delegateDid; return [3 /*break*/, 4]; case 4: if (!request.from) return [3 /*break*/, 6]; return [4 /*yield*/, this.agent.sendDwnRequest(agentRequest)]; case 5: agentResponse = _b.sent(); return [3 /*break*/, 8]; case 6: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 7: agentResponse = _b.sent(); _b.label = 8; case 8: _a = agentResponse.reply, entry = _a.entry, status = _a.status; if (200 <= status.code && status.code <= 299) { recordOptions = __assign({ /** * Extract the `author` DID from the record since records may be signed by the * tenant owner or any other entity. */ author: (0, agent_2.getRecordAuthor)(entry.recordsWrite), /** * Set the `connectedDid` to currently connected DID so that subsequent calls to * {@link Record} instance methods, such as `record.update()` are executed on the * local DWN even if the record was read from a remote DWN. */ connectedDid: this.connectedDid, /** * If the record was returned by reading from a remote DWN, set the `remoteOrigin` to * the DID of the DWN that returned the record. The `remoteOrigin` property will be used * to determine which DWN to send subsequent read requests to in the event the data * payload must be read again (e.g., if the data stream is consumed). */ remoteOrigin: request.from, delegateDid: this.delegateDid, data: entry.data, initialWrite: entry.initialWrite }, entry.recordsWrite); record = new record_js_1.Record(this.agent, recordOptions, this.permissionsApi); } return [2 /*return*/, { record: record, status: status }]; } }); }); }, /** * Subscribes to records based on the given filter and emits events to the `subscriptionHandler`. * * @param request must include the `message` with the subscription filter and the `subscriptionHandler` to process the events. * @returns the subscription status and the subscription object used to close the subscription. */ subscribe: function (request) { return __awaiter(_this, void 0, void 0, function () { var agentRequest, delegatedGrant, _error_4, agentResponse, reply, status, subscription; return __generator(this, function (_a) { switch (_a.label) { case 0: agentRequest = { /** * The `author` is the DID that will sign the message and must be the DID the Web5 app is * connected with and is authorized to access the signing private key of. */ author: this.connectedDid, messageParams: request.message, messageType: agent_2.DwnInterface.RecordsSubscribe, /** * The `target` is the DID of the DWN tenant under which the subscribe operation will be executed. * If `from` is provided, the subscribe operation will be executed on a remote DWN. * Otherwise, the local DWN will execute the subscribe operation. */ target: request.from || this.connectedDid, /** * The handler to process the subscription events. */ subscriptionHandler: subscription_util_js_1.SubscriptionUtil.recordSubscriptionHandler({ agent: this.agent, connectedDid: this.connectedDid, delegateDid: this.delegateDid, permissionsApi: this.permissionsApi, protocolRole: request.message.protocolRole, request: request }) }; if (!this.delegateDid) return [3 /*break*/, 4]; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.protocol, delegate: true, cached: true, messageType: agentRequest.messageType })]; case 2: delegatedGrant = (_a.sent()).message; agentRequest.messageParams = __assign(__assign({}, agentRequest.messageParams), { delegatedGrant: delegatedGrant }); agentRequest.granteeDid = this.delegateDid; return [3 /*break*/, 4]; case 3: _error_4 = _a.sent(); // if a grant is not found, we should author the request as the delegated DID to get public records agentRequest.author = this.delegateDid; return [3 /*break*/, 4]; case 4: ; if (!request.from) return [3 /*break*/, 6]; return [4 /*yield*/, this.agent.sendDwnRequest(agentRequest)]; case 5: agentResponse = _a.sent(); return [3 /*break*/, 8]; case 6: return [4 /*yield*/, this.agent.processDwnRequest(agentRequest)]; case 7: agentResponse = _a.sent(); _a.label = 8; case 8: reply = agentResponse.reply; status = reply.status, subscription = reply.subscription; return [2 /*return*/, { status: status, subscription: subscription }]; } }); }); }, /** * Writes a record to the DWN * * As a convenience, the Record instance returned will cache a copy of the data. This is done * to maintain consistency with other DWN methods, like RecordsQuery, that include relatively * small data payloads when returning RecordsWrite message properties. Regardless of data * size, methods such as `record.data.stream()` will return the data when called even if it * requires fetching from the DWN datastore. */ write: function (request) { return __awaiter(_this, void 0, void 0, function () { var _a, dataBlob, dataFormat, dwnRequestParams, delegatedGrant, agentResponse, responseMessage, status, record, recordOptions; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _a = (0, utils_js_1.dataToBlob)(request.data, (_b = request.message) === null || _b === void 0 ? void 0 : _b.dataFormat), dataBlob = _a.dataBlob, dataFormat = _a.dataFormat; dwnRequestParams = { store: request.store, messageType: agent_2.DwnInterface.RecordsWrite, messageParams: __assign(__assign({}, request.message), { dataFormat: dataFormat }), author: this.connectedDid, target: this.connectedDid, dataStream: dataBlob }; if (!this.delegateDid) return [3 /*break*/, 2]; return [4 /*yield*/, this.permissionsApi.getPermissionForRequest({ connectedDid: this.connectedDid, delegateDid: this.delegateDid, protocol: request.message.protocol, delegate: true, cached: true, messageType: dwnRequestParams.messageType })]; case 1: delegatedGrant = (_c.sent()).message; dwnRequestParams.messageParams = __assign(__assign({}, dwnRequestParams.messageParams), { delegatedGrant: delegatedGrant }); dwnRequestParams.granteeDid = this.delegateDid; _c.label = 2; case 2: ; return [4 /*yield*/, this.agent.processDwnRequest(dwnRequestParams)]; case 3: agentResponse = _c.sent(); responseMessage = agentResponse.message, status = agentResponse.reply.status; if (200 <= status.code && status.code <= 299) { recordOptions = __assign({ /** * Assume the author is the connected DID since the record was just written to the * local DWN. */ author: this.connectedDid, /