@enbox/api
Version:
SDK for accessing the features and capabilities of Web5
784 lines • 51 kB
JavaScript
"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,
/