@gleif-it/vlei-verifier-workflows
Version:
Workflows for vLEI users and vLEI credentials for the vLEI-verifier service
789 lines (788 loc) • 51 kB
JavaScript
"use strict";
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VleiIssuance = void 0;
const assert_1 = require("assert");
const mathjs_1 = require("mathjs");
const signify_ts_1 = require("signify-ts");
const test_util_js_1 = require("./utils/test-util.js");
const multisig_utils_js_1 = require("./utils/multisig-utils.js");
const retry_js_1 = require("./utils/retry.js");
const constants_js_1 = require("./constants.js");
const generate_test_data_js_1 = require("./utils/generate-test-data.js");
const workflow_state_js_1 = require("./workflow-state.js");
exports.VleiIssuance = {
// Create client for given AID
createClient: (secret, agentName) => __awaiter(void 0, void 0, void 0, function* () {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
console.log(`Creating client for secret: ${secret}`);
const client = yield (0, test_util_js_1.getOrCreateClients)(1, [secret], false);
workflow_state.clients.set(agentName, client[0]);
return true;
}),
// Create AID
createAid: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
console.log('Creating AID');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
let aid;
if (identifierData.type == 'singlesig') {
workflow_state.aidsInfo.set(identifierData.name, identifierData);
aid = yield exports.VleiIssuance.createAidSinglesig(identifierData);
yield exports.VleiIssuance.fetchOobi(identifierData);
yield exports.VleiIssuance.createContacts(identifierData);
yield exports.VleiIssuance.resolveOobi(identifierData);
workflow_state.aids.set(identifierData.name, aid);
}
else {
workflow_state.aidsInfo.set(identifierData.name, identifierData);
aid = yield exports.VleiIssuance.createAidMultisig(identifierData);
yield exports.VleiIssuance.fetchOobi(identifierData);
workflow_state.aids.set(identifierData.name, aid);
}
}),
// Fetch OOBIs for each client!
fetchOobis: () => __awaiter(void 0, void 0, void 0, function* () {
console.log('Fetching OOBIs');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
for (const [, aidInfo] of workflow_state.aidsInfo) {
yield exports.VleiIssuance.fetchOobi(aidInfo);
}
}),
fetchOobi: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
let client;
let oobi;
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
if (identifierData.type === 'singlesig') {
const singlesigIdentifierData = identifierData;
client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
oobi = yield client.oobis().get(identifierData.name, 'agent');
if (oobi) {
workflow_state.oobis.set(singlesigIdentifierData.name, [oobi]);
}
}
else {
const multisigIdentifierData = identifierData;
const oobis = [];
for (const _ of multisigIdentifierData.identifiers) {
const identifier = workflow_state.aidsInfo.get(multisigIdentifierData.identifiers[0]);
client = workflow_state.clients.get(identifier.agent.name);
oobi = yield client.oobis().get(identifier.name, 'agent');
oobis.push(oobi);
}
if (oobi) {
workflow_state.oobis.set(identifierData.name, oobis);
}
}
}),
// Create contacts between clients
createContacts: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
console.log('Creating Contacts');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
for (const [, contactIdentifierData] of workflow_state.aidsInfo) {
if (contactIdentifierData.type === 'multisig' ||
identifierData.type === 'multisig')
continue;
if (identifierData.name != contactIdentifierData.name) {
yield exports.VleiIssuance.createContact(identifierData, contactIdentifierData);
}
}
}),
createContact: (aidInfoA, aidInfoB) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
if (aidInfoA.type == 'singlesig') {
const singlesigIdentifierDataA = aidInfoA;
const singlesigIdentifierDataB = aidInfoB;
const clientA = workflow_state.clients.get(singlesigIdentifierDataA.agent.name);
const clientB = workflow_state.clients.get(singlesigIdentifierDataB.agent.name);
const oobiA = (_a = workflow_state.oobis.get(singlesigIdentifierDataA.name)) === null || _a === void 0 ? void 0 : _a[0].oobis[0];
const oobiB = (_b = workflow_state.oobis.get(singlesigIdentifierDataB.name)) === null || _b === void 0 ? void 0 : _b[0].oobis[0];
yield (0, test_util_js_1.getOrCreateContact)(clientA, singlesigIdentifierDataB.name, oobiB);
yield (0, test_util_js_1.getOrCreateContact)(clientB, singlesigIdentifierDataA.name, oobiA);
}
}),
// Resolve OOBIs for each client! and schema
resolveOobis: () => {
const schemaUrls = [
constants_js_1.QVI_SCHEMA_URL,
constants_js_1.LE_SCHEMA_URL,
constants_js_1.ECR_AUTH_SCHEMA_URL,
constants_js_1.ECR_SCHEMA_URL,
constants_js_1.OOR_AUTH_SCHEMA_URL,
constants_js_1.OOR_SCHEMA_URL,
];
console.log('Resolving OOBIs');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
for (const [, client] of workflow_state.clients) {
schemaUrls.forEach((schemaUrl) => __awaiter(void 0, void 0, void 0, function* () {
yield (0, test_util_js_1.resolveOobi)(client, schemaUrl);
}));
}
},
resolveOobi: (identifierData) => {
const schemaUrls = [
constants_js_1.QVI_SCHEMA_URL,
constants_js_1.LE_SCHEMA_URL,
constants_js_1.ECR_AUTH_SCHEMA_URL,
constants_js_1.ECR_SCHEMA_URL,
constants_js_1.OOR_AUTH_SCHEMA_URL,
constants_js_1.OOR_SCHEMA_URL,
];
if (identifierData.type === 'singlesig') {
console.log('Resolving OOBIs for client');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const singlesigIdentifierData = identifierData;
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
schemaUrls.forEach((schemaUrl) => __awaiter(void 0, void 0, void 0, function* () {
yield (0, test_util_js_1.resolveOobi)(client, schemaUrl);
}));
}
},
createRegistry: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
console.log('Creating Registries');
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
let registry;
if (identifierData.type == 'multisig') {
registry = yield exports.VleiIssuance.createRegistryMultisig(identifierData);
}
else {
const singlesigIdentifierData = identifierData;
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
registry = yield (0, test_util_js_1.getOrCreateRegistry)(client, workflow_state.aids.get(identifierData.name), `${identifierData.name}Registry`);
}
workflow_state.registries.set(identifierData.name, registry);
}),
createAidSinglesig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const delegator = identifierData.delegator;
const kargsSinglesigAID = {
toad: workflow_state.kargsAID.toad,
wits: workflow_state.kargsAID.wits,
};
const singlesigIdentifierData = identifierData;
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
if (delegator != null) {
try {
const aid = yield client.identifiers().get(identifierData.name);
return aid;
}
catch (_c) {
console.log(`Creating delegated AID for: ${identifierData.name}`);
}
kargsSinglesigAID.delpre = workflow_state.aids.get(delegator).prefix;
const delegatorIdentifierData = workflow_state.aidsInfo.get(delegator);
const delegatorclient = workflow_state.clients.get(delegatorIdentifierData.agent.name);
const delegatorAid = workflow_state.aids.get(delegator);
// Resolve delegator's oobi
const oobi1 = yield delegatorclient.oobis().get(delegator, 'agent');
yield (0, test_util_js_1.resolveOobi)(client, oobi1.oobis[0], delegator);
// Delegate client! creates delegate AID
const icpResult2 = yield client
.identifiers()
.create(identifierData.name, { delpre: delegatorAid.prefix });
const op2 = yield icpResult2.op();
const delegateAidPrefix = op2.name.split('.')[1];
console.log("Delegate's prefix:", delegateAidPrefix);
// client! 1 approves delegation
const anchor = {
i: delegateAidPrefix,
s: '0',
d: delegateAidPrefix,
};
const result = yield (0, retry_js_1.retry)(() => __awaiter(void 0, void 0, void 0, function* () {
const apprDelRes = yield delegatorclient
.delegations()
.approve(delegator, anchor);
yield (0, test_util_js_1.waitOperation)(delegatorclient, yield apprDelRes.op());
console.log('Delegator approve delegation submitted');
return apprDelRes;
}));
assert_1.strict.equal(JSON.stringify(result.serder.ked.a[0]), JSON.stringify(anchor));
const op3 = yield client.keyStates().query(delegatorAid.prefix, '1');
yield (0, test_util_js_1.waitOperation)(client, op3);
// Delegate client! checks approval
yield (0, test_util_js_1.waitOperation)(client, op2);
const aid2 = yield client.identifiers().get(identifierData.name);
assert_1.strict.equal(aid2.prefix, delegateAidPrefix);
console.log('Delegation approved for aid:', aid2.prefix);
yield (0, test_util_js_1.assertOperations)(delegatorclient, client);
const rpyResult2 = yield client
.identifiers()
.addEndRole(identifierData.name, 'agent', client.agent.pre);
yield (0, test_util_js_1.waitOperation)(client, yield rpyResult2.op());
return aid2;
}
else {
const aid = yield (0, test_util_js_1.getOrCreateAID)(client, identifierData.name, kargsSinglesigAID);
return aid;
}
}),
createAidMultisig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const multisigIdentifierData = identifierData;
let multisigAids = [];
const aidIdentifierNames = multisigIdentifierData.identifiers;
const issuerAids = aidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || [];
try {
for (const aidIdentifierName of aidIdentifierNames) {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aidIdentifierName);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
multisigAids.push(yield client.identifiers().get(identifierData.name));
}
const multisigAid = multisigAids[0];
console.log(`${identifierData.name} AID: ${multisigAid.prefix}`);
return multisigAid;
}
catch (_d) {
multisigAids = [];
}
if (multisigAids.length == 0) {
const rstates = issuerAids.map((aid) => aid.state);
const states = rstates;
const kargsMultisigAID = {
algo: signify_ts_1.default.Algos.group,
isith: multisigIdentifierData.isith,
nsith: multisigIdentifierData.nsith,
toad: workflow_state.kargsAID.toad,
wits: workflow_state.kargsAID.wits,
states: states,
rstates: rstates,
};
if (identifierData.delegator != null) {
kargsMultisigAID.delpre = workflow_state.aids.get(multisigIdentifierData.delegator).prefix;
}
const multisigOps = [];
for (let index = 0; index < issuerAids.length; index++) {
const aid = issuerAids[index];
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
const kargsMultisigAIDClone = Object.assign(Object.assign({}, kargsMultisigAID), { mhab: aid });
const otherAids = issuerAids.filter((aidTmp) => aid !== aidTmp);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
const op = yield (0, multisig_utils_js_1.createAIDMultisig)(client, aid, otherAids, identifierData.name, kargsMultisigAIDClone, index === 0 // Set true for the first operation
);
multisigOps.push([client, op]);
}
if (multisigIdentifierData.delegator) {
// Approve delegation
const delegatoridentifierData = workflow_state.aidsInfo.get(multisigIdentifierData.delegator);
const delegatorAidIdentifierNames = delegatoridentifierData.identifiers;
const delegatorAids = delegatorAidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || [];
const teepre = multisigOps[0][1].name.split('.')[1];
const anchor = {
i: teepre,
s: '0',
d: teepre,
};
let delegatorClientInitiator;
const delegatorMultisigAid = workflow_state.aids.get(delegatoridentifierData.name);
const delegateOps = [];
for (let index = 0; index < delegatoridentifierData.identifiers.length; index++) {
const curAidName = delegatoridentifierData.identifiers[index];
const curidentifierData = workflow_state.aidsInfo.get(curAidName);
const aid = workflow_state.aids.get(curAidName);
const otherAids = delegatorAids.filter((aidTmp) => aid.prefix !== aidTmp.prefix);
const delegatorclient = workflow_state.clients.get(curidentifierData.agent.name);
const delApprOp = yield (0, multisig_utils_js_1.delegateMultisig)(delegatorclient, aid, otherAids, delegatorMultisigAid, anchor, index === 0);
delegateOps.push([delegatorclient, delApprOp]);
if (index === 0) {
delegatorClientInitiator = delegatorclient;
}
else {
yield (0, test_util_js_1.waitAndMarkNotification)(delegatorClientInitiator, '/multisig/ixn');
}
}
for (const [client, op] of delegateOps) {
yield (0, test_util_js_1.waitOperation)(client, op);
}
for (const identifier of delegatoridentifierData.identifiers) {
const curidentifierData = workflow_state.aidsInfo.get(identifier);
const delegatorclient = workflow_state.clients.get(curidentifierData.agent.name);
const queryOp1 = yield delegatorclient
.keyStates()
.query(delegatorMultisigAid.prefix, '1');
yield (0, test_util_js_1.waitOperation)(delegatorclient, queryOp1);
}
for (const identifier of multisigIdentifierData.identifiers) {
const curidentifierData = workflow_state.aidsInfo.get(identifier);
const delegateeclient = workflow_state.clients.get(curidentifierData.agent.name);
const ksteetor1 = yield delegateeclient
.keyStates()
.query(delegatorMultisigAid.prefix, '1');
yield (0, test_util_js_1.waitOperation)(delegateeclient, ksteetor1);
}
}
// Wait for all multisig operations to complete
for (const [client, op] of multisigOps) {
yield (0, test_util_js_1.waitOperation)(client, op);
}
// Wait for multisig inception notifications for all clients
const tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/icp');
// Retrieve the newly created AIDs for all clients
multisigAids = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return yield client.identifiers().get(identifierData.name);
})));
(0, assert_1.strict)(multisigAids.every((aid) => aid.prefix === multisigAids[0].prefix));
(0, assert_1.strict)(multisigAids.every((aid) => aid.name === multisigAids[0].name));
const multisigAid = multisigAids[0];
// Skip if they have already been authorized.
let oobis = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return yield client.oobis().get(multisigAid.name, 'agent');
})));
if (oobis.some((oobi) => oobi.oobis.length == 0)) {
const timestamp = (0, test_util_js_1.createTimestamp)();
// Add endpoint role for all clients
const roleOps = yield Promise.all(issuerAids.map((aid, index) => __awaiter(void 0, void 0, void 0, function* () {
const otherAids = issuerAids.filter((_, i) => i !== index);
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return yield (0, multisig_utils_js_1.addEndRoleMultisig)(client, multisigAid.name, aid, otherAids, multisigAid, timestamp, index === 0);
})));
// Wait for all role operations to complete for each client!
for (const [i, roleOpGroup] of roleOps.entries()) {
for (const roleOp of roleOpGroup) {
const tmpAidData = workflow_state.aidsInfo.get(issuerAids[i].name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
yield (0, test_util_js_1.waitOperation)(client, roleOp);
}
}
// Wait for role resolution notifications for all clients
// await waitAndMarkNotification(workflow_state.clients.get(workflow_state.aidsInfo.get(issuerAids[0].name).agent.name), "/multisig/rpy");
yield Promise.all(issuerAids.map((aid) => {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return (0, test_util_js_1.waitAndMarkNotification)(client, '/multisig/rpy');
}));
// Retrieve the OOBI again after the operation for all clients
oobis = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return yield client.oobis().get(multisigAid.name, 'agent');
})));
}
// Ensure that all OOBIs are consistent across all clients
(0, assert_1.strict)(oobis.every((oobi) => oobi.role === oobis[0].role));
(0, assert_1.strict)(oobis.every((oobi) => oobi.oobis[0] === oobis[0].oobis[0]));
const oobi = oobis[0].oobis[0].split('/agent/')[0];
const clients = Array.from(workflow_state.clients.values()).flat();
yield Promise.all(clients.map((client) => __awaiter(void 0, void 0, void 0, function* () { return yield (0, test_util_js_1.getOrCreateContact)(client, multisigAid.name, oobi); })));
console.log(`${identifierData.name} AID: ${multisigAid.prefix}`);
return multisigAid;
}
}),
createRegistryMultisig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () {
const multisigIdentifierData = identifierData;
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const multisigAid = workflow_state.aids.get(identifierData.name);
const registryIdentifierName = `${identifierData.name}Registry`;
const aidIdentifierNames = multisigIdentifierData.identifiers;
const registries = new Array();
const issuerAids = aidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || [];
// Check if the registries already exist
for (const aidIdentifierName of aidIdentifierNames) {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aidIdentifierName);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
let tmpRegistry = yield client.registries().list(multisigAid.name);
tmpRegistry = tmpRegistry.filter((reg) => reg.name == `${identifierData.name}Registry`);
registries.push(tmpRegistry);
}
// Check if registries exist
const allEmpty = registries.every((registry) => registry.length === 0);
if (allEmpty) {
const nonce = signify_ts_1.default.randomNonce();
const registryOps = issuerAids.map((aid, index) => {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const otherAids = issuerAids.filter((_, i) => i !== index);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return (0, multisig_utils_js_1.createRegistryMultisig)(client, aid, otherAids, multisigAid, registryIdentifierName, nonce, index === 0 // Use true for the first operation, false for others
);
});
// Await all registry creation operations
const createdOps = yield Promise.all(registryOps);
// Wait for all operations to complete across multiple clients
yield Promise.all(createdOps.map((op, index) => __awaiter(void 0, void 0, void 0, function* () {
const tmpAidData = workflow_state.aidsInfo.get(issuerAids[index].name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return yield (0, test_util_js_1.waitOperation)(client, op);
})));
// Wait for multisig inception notification for each client!
const tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/vcp');
// Recheck the registries for each client!
const updatedRegistries = yield Promise.all(issuerAids.map((aid) => {
const tmpAidData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(tmpAidData.agent.name);
return client.registries().list(multisigAid.name);
}));
// Update the `registries` array with the new values
registries.splice(0, registries.length, ...updatedRegistries);
// Ensure that all registries match the first one
const firstRegistry = registries[0][0];
registries.forEach((registry) => {
assert_1.strict.equal(registry[0].regk, firstRegistry.regk);
assert_1.strict.equal(registry[0].name, firstRegistry.name);
});
// Save the first registry and return it
workflow_state.registries.set(multisigAid.name, firstRegistry);
console.log(`${multisigAid.name} Registry created`);
return firstRegistry;
}
else {
return registries[0][0];
}
}),
getOrIssueCredential: (credId_1, credName_1, attributes_1, issuerAidKey_1, issueeAidKey_1, credSourceId_1, ...args_1) => __awaiter(void 0, [credId_1, credName_1, attributes_1, issuerAidKey_1, issueeAidKey_1, credSourceId_1, ...args_1], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData = false, testName = 'default_test') {
return workflow_state_js_1.WorkflowState.getInstance().aidsInfo.get(issuerAidKey).type === 'multisig'
? yield exports.VleiIssuance.getOrIssueCredentialMultiSig(credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData, testName)
: yield exports.VleiIssuance.getOrIssueCredentialSingleSig(credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData, testName);
}),
revokeCredential: (credId_2, issuerAidKey_2, issueeAidKey_2, ...args_2) => __awaiter(void 0, [credId_2, issuerAidKey_2, issueeAidKey_2, ...args_2], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey);
if (issuerAidInfo.type === 'multisig') {
return yield exports.VleiIssuance.revokeCredentialMultiSig(credId, issuerAidKey, issueeAidKey, generateTestData, testName);
}
else {
return yield exports.VleiIssuance.revokeCredentialSingleSig(credId, issuerAidKey, issueeAidKey, generateTestData, testName);
}
}),
getOrIssueCredentialSingleSig: (credId_3, credName_2, attributes_2, issuerAidKey_3, issueeAidKey_3, credSourceId_2, ...args_3) => __awaiter(void 0, [credId_3, credName_2, attributes_2, issuerAidKey_3, issueeAidKey_3, credSourceId_2, ...args_3], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData = false, testName = 'default_test') {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const credInfo = workflow_state.credentialsInfo.get(credName);
const issuerAID = workflow_state.aids.get(issuerAidKey);
const recipientAID = workflow_state.aids.get(issueeAidKey);
const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey);
const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey);
const issuerclient = workflow_state.clients.get(issuerAIDInfo.agent.name);
const recipientclient = workflow_state.clients.get(recipientAIDInfo.agent.name);
const issuerRegistry = workflow_state.registries.get(issuerAIDInfo.name);
const schema = workflow_state.schemas[credInfo.schema];
const rules = workflow_state.rules[credInfo.rules];
const privacy = credInfo.privacy;
let credSource = null;
if (credSourceId != null) {
const credType = credInfo.credSource['type'];
const issuerCred = workflow_state.credentials.get(credSourceId);
const credO = credInfo.credSource['o'] || null;
credSource = exports.VleiIssuance.buildCredSource(credType, issuerCred, credO);
}
if (attributes['AID'] != null) {
attributes.AID = workflow_state.aids.get(attributes['AID']).prefix;
}
const credData = Object.assign(Object.assign({}, credInfo.attributes), attributes);
const cred = yield (0, test_util_js_1.getOrIssueCredential)(issuerclient, issuerAID, recipientAID, issuerRegistry, credData, schema, rules || undefined, credSource || undefined, (0, mathjs_1.boolean)(privacy || false));
let credHolder = yield (0, test_util_js_1.getReceivedCredential)(recipientclient, cred.sad.d);
if (!credHolder) {
yield (0, test_util_js_1.sendGrantMessage)(issuerclient, issuerAID, recipientAID, cred);
yield (0, test_util_js_1.sendAdmitMessage)(recipientclient, recipientAID, issuerAID);
credHolder = yield (0, retry_js_1.retry)(() => __awaiter(void 0, void 0, void 0, function* () {
const cCred = yield (0, test_util_js_1.getReceivedCredential)(recipientclient, cred.sad.d);
(0, assert_1.strict)(cCred !== undefined);
return cCred;
}), constants_js_1.CRED_RETRY_DEFAULTS);
}
assert_1.strict.equal(credHolder.sad.d, cred.sad.d);
assert_1.strict.equal(credHolder.sad.s, schema);
assert_1.strict.equal(credHolder.sad.i, issuerAID.prefix);
assert_1.strict.equal(credHolder.sad.a.i, recipientAID.prefix);
assert_1.strict.equal(credHolder.status.s, '0');
(0, assert_1.strict)(credHolder.atc !== undefined);
workflow_state.credentials.set(credId, cred);
const credCesr = yield recipientclient.credentials().get(cred.sad.d, true);
if (generateTestData) {
const tmpCred = cred;
const testData = {
aid: recipientAID.prefix,
lei: credData.LEI,
credential: { raw: tmpCred, cesr: credCesr },
engagementContextRole: credData.engagementContextRole || credData.officialRole,
};
yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey);
}
const response = {
roleClient: recipientclient,
ecrAid: recipientAID,
creds: { [credId]: { cred: cred, credCesr: credCesr } },
idAlias: issueeAidKey,
};
return [response, credData.engagementContextRole];
}),
getOrIssueCredentialMultiSig: (credId_4, credName_3, attributes_3, issuerAidKey_4, issueeAidKey_4, credSourceId_3, ...args_4) => __awaiter(void 0, [credId_4, credName_3, attributes_3, issuerAidKey_4, issueeAidKey_4, credSourceId_3, ...args_4], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, _generateTestData = false, _testName = 'default_test') {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const credInfo = workflow_state.credentialsInfo.get(credName);
const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey);
const recipientAidInfo = workflow_state.aidsInfo.get(issueeAidKey);
const issuerAIDMultisig = workflow_state.aids.get(issuerAidKey);
const recipientAID = workflow_state.aids.get(issueeAidKey);
const schema = workflow_state.schemas[credInfo.schema];
let rules = workflow_state.rules[credInfo.rules];
const privacy = credInfo.privacy;
const registryName = issuerAidInfo.name;
const issuerRegistry = workflow_state.registries.get(registryName);
const issuerAids = issuerAidInfo.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
let recepientAids = [];
if (recipientAidInfo.type === 'multisig') {
const multisigIdentifierData = recipientAidInfo;
recepientAids =
multisigIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
}
else {
recepientAids = [workflow_state.aids.get(recipientAidInfo.name)];
}
let credSource = null;
if (credSourceId != null) {
const credType = credInfo.credSource['type'];
const issuerCred = workflow_state.credentials.get(credSourceId);
const credO = credInfo.credSource['o'] || null;
credSource = exports.VleiIssuance.buildCredSource(credType, issuerCred, credO);
credSource = credSource ? { e: credSource } : undefined;
}
rules = rules ? { r: rules } : undefined;
// Issuing a credential
let creds = yield Promise.all(issuerAids.map((aid) => {
const identifierData = workflow_state.aidsInfo.get(aid.name);
const singlesigData = identifierData;
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, test_util_js_1.getIssuedCredential)(client, issuerAIDMultisig, recipientAID, schema);
}));
if (creds.every((cred) => !cred)) {
if (attributes['AID'] != null) {
attributes.AID = workflow_state.aids.get(attributes['AID']).prefix;
}
const credData = Object.assign(Object.assign({}, credInfo.attributes), attributes);
const kargsSub = Object.assign({ i: recipientAID.prefix, dt: (0, test_util_js_1.createTimestamp)(), u: privacy ? new signify_ts_1.default.Salter({}).qb64 : undefined }, credData);
const kargsIss = Object.assign(Object.assign({ i: issuerAIDMultisig.prefix, ri: issuerRegistry.regk, s: schema, a: kargsSub, u: privacy ? new signify_ts_1.default.Salter({}).qb64 : undefined }, credSource), rules);
const IssOps = yield Promise.all(issuerAids.map((aid, index) => {
const identifierData = workflow_state.aidsInfo.get(aid.name);
const singlesigData = identifierData;
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, multisig_utils_js_1.issueCredentialMultisig)(client, aid, issuerAids.filter((_, i) => i !== index), issuerAIDMultisig.name, kargsIss, index === 0);
}));
yield Promise.all(issuerAids.map((aid, index) => {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, test_util_js_1.waitOperation)(client, IssOps[index]);
}));
let tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/iss');
creds = yield Promise.all(issuerAids.map((aid) => {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, test_util_js_1.getIssuedCredential)(client, issuerAIDMultisig, recipientAID, schema);
}));
(0, test_util_js_1.sleep)(1000);
const grantTime = (0, test_util_js_1.createTimestamp)();
yield Promise.all(creds.map((cred, index) => {
const singlesigData = workflow_state.aidsInfo.get(issuerAids[index].name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, multisig_utils_js_1.grantMultisig)(client, issuerAids[index], issuerAids.filter((_, i) => i !== index), issuerAIDMultisig, recipientAID, cred, grantTime, index === 0);
}));
(0, test_util_js_1.sleep)(1000);
tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/exn');
}
const cred = creds[0];
// Exchange grant and admit messages.
// Check if the recipient is a singlesig AID
if (recipientAidInfo.type === 'multisig') {
let credsReceived = yield Promise.all(recepientAids.map((aid) => {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, test_util_js_1.getReceivedCredential)(client, cred.sad.d);
}));
if (credsReceived.every((cred) => cred === undefined)) {
const admitTime = (0, test_util_js_1.createTimestamp)();
yield Promise.all(recepientAids.map((aid, index) => {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, multisig_utils_js_1.admitMultisig)(client, aid, recepientAids.filter((_, i) => i !== index), recipientAID, issuerAIDMultisig, admitTime);
}));
(0, test_util_js_1.sleep)(2000);
for (const aid of issuerAids) {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit');
}
for (const aid of recepientAids) {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/multisig/exn');
}
for (const aid of recepientAids) {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit');
}
(0, test_util_js_1.sleep)(1000);
credsReceived = yield Promise.all(recepientAids.map((aid) => {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigData.agent.name);
return (0, test_util_js_1.waitForCredential)(client, cred.sad.d);
}));
// Assert received credential details
for (const credReceived of credsReceived) {
assert_1.strict.equal(cred.sad.d, credReceived.sad.d);
}
}
}
else {
const singlesigData = workflow_state.aidsInfo.get(recepientAids[0].name);
let credReceived = yield (0, test_util_js_1.getReceivedCredential)(workflow_state.clients.get(singlesigData.agent.name), cred.sad.d);
if (!credReceived) {
yield (0, test_util_js_1.admitSinglesig)(workflow_state.clients.get(singlesigData.agent.name), workflow_state.aids.get(recepientAids[0].name).name, issuerAIDMultisig);
(0, test_util_js_1.sleep)(2000);
for (const aid of issuerAids) {
const singlesigData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit');
}
credReceived = yield (0, test_util_js_1.waitForCredential)(workflow_state.clients.get(singlesigData.agent.name), cred.sad.d);
}
assert_1.strict.equal(cred.sad.d, credReceived.sad.d);
}
console.log(`${issuerAIDMultisig.name} has issued a ${recipientAID.name} vLEI credential with SAID:`, cred.sad.d);
workflow_state.credentials.set(credId, cred);
return [cred, null];
}),
revokeCredentialSingleSig: (credId_5, issuerAidKey_5, issueeAidKey_5, ...args_5) => __awaiter(void 0, [credId_5, issuerAidKey_5, issueeAidKey_5, ...args_5], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const cred = workflow_state.credentials.get(credId);
const issuerAID = workflow_state.aids.get(issuerAidKey);
const recipientAID = workflow_state.aids.get(issueeAidKey);
const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey);
const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey);
const recipientclient = workflow_state.clients.get(recipientAIDInfo.agent.name);
const issuerclient = workflow_state.clients.get(issuerAIDInfo.agent.name);
const revCred = yield (0, test_util_js_1.revokeCredential)(issuerclient, issuerAID, cred.sad.d);
workflow_state.credentials.set(credId, revCred);
const credCesr = yield issuerclient.credentials().get(revCred.sad.d, true);
if (generateTestData) {
const tmpCred = revCred;
const testData = {
aid: recipientAID.prefix,
lei: revCred.sad.a.LEI,
credential: { raw: tmpCred, cesr: credCesr },
engagementContextRole: revCred.sad.a.engagementContextRole || revCred.sad.a.officialRole,
};
yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey, 'revoked_');
}
const response = {
roleClient: recipientclient,
ecrAid: recipientAID,
creds: { credId: { cred: cred, credCesr: credCesr } },
idAlias: issueeAidKey,
};
return [response, revCred.sad.a.engagementContextRole];
}),
revokeCredentialMultiSig: (credId_6, issuerAidKey_6, issueeAidKey_6, ...args_6) => __awaiter(void 0, [credId_6, issuerAidKey_6, issueeAidKey_6, ...args_6], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const recipientAID = workflow_state.aids.get(issueeAidKey);
const cred = workflow_state.credentials.get(credId);
const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey);
const issuerAIDMultisig = workflow_state.aids.get(issuerAidKey);
const issuerAids = issuerAidInfo.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
let issuerclient;
const revOps = [];
let i = 0;
const REVTIME = new Date().toISOString().replace('Z', '000+00:00');
for (const issuerAid of issuerAids) {
const aidInfo = workflow_state.aidsInfo.get(issuerAid.name);
issuerclient = workflow_state.clients.get(aidInfo.agent.name);
if (i != 0) {
const msgSaid = yield (0, test_util_js_1.waitAndMarkNotification)(issuerclient, '/multisig/rev');
console.log(`Multisig AID ${issuerAid.name} received exchange message to join the credential revocation event`);
yield issuerclient.groups().getRequest(msgSaid);
}
const revResult = yield issuerclient
.credentials()
.revoke(issuerAIDMultisig.name, cred.sad.d, REVTIME);
revOps.push([issuerclient, revResult.op]);
yield (0, multisig_utils_js_1.multisigRevoke)(issuerclient, issuerAid.name, issuerAIDMultisig.name, revResult.rev, revResult.anc);
i += 1;
}
for (const [client, op] of revOps) {
yield (0, test_util_js_1.waitOperation)(client, op);
}
const revCred = yield issuerclient.credentials().get(cred.sad.d);
workflow_state.credentials.set(credId, revCred);
if (generateTestData) {
const tmpCred = revCred;
const credCesr = yield issuerclient
.credentials()
.get(revCred.sad.d, true);
const testData = {
aid: recipientAID.prefix,
lei: revCred.sad.a.LEI,
credential: { raw: tmpCred, cesr: credCesr },
engagementContextRole: revCred.sad.a.engagementContextRole || revCred.sad.a.officialRole,
};
yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey, 'revoked_');
}
return [revCred, null];
}),
notifyCredentialIssuee: (credId, issuerAidKey, issueeAidKey) => __awaiter(void 0, void 0, void 0, function* () {
const workflow_state = workflow_state_js_1.WorkflowState.getInstance();
const cred = workflow_state.credentials.get(credId);
if (!cred) {
console.log(`notifyCredential: credential with credId=${credId} was not found`);
throw new Error(`notifyCredential: credential with credId=${credId} was not found`);
}
const issuerAID = workflow_state.aids.get(issuerAidKey);
const recipientAID = workflow_state.aids.get(issueeAidKey);
const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey);
const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey);
if (issuerAIDInfo.type === 'multisig') {
const multisigIdentifierData = issuerAIDInfo;
const schema = workflow_state.schemas[cred.schema];
const issuerAids = multisigIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
const creds = yield Promise.all(issuerAids.map((aid) => {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
return (0, test_util_js_1.getIssuedCredential)(client, issuerAID, recipientAID, schema);
}));
(0, test_util_js_1.sleep)(1000);
const grantTime = (0, test_util_js_1.createTimestamp)();
yield Promise.all(creds.map((cred, index) => {
const singlesigIdentifierData = workflow_state.aidsInfo.get(issuerAids[index].name);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
return (0, multisig_utils_js_1.grantMultisig)(client, issuerAids[index], issuerAids.filter((_, i) => i !== index), issuerAID, recipientAID, cred, grantTime, index === 0);
}));
}
else {
const singlesigIdentifierData = issuerAIDInfo;
const issuerclient = workflow_state.clients.get(singlesigIdentifierData.agent.name);
yield (0, test_util_js_1.sendGrantMessage)(issuerclient, issuerAID, recipientAID, cred);
}
if (recipientAIDInfo.type === 'multisig') {
const multisigRecipientIdentifierData = recipientAIDInfo;
const multisigIssuerIdentifierData = issuerAIDInfo;
const admitTime = (0, test_util_js_1.createTimestamp)();
const issuerAids = multisigIssuerIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
const recepientAids = multisigRecipientIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || [];
yield Promise.all(recepientAids.map((aid, index) => {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
const client = workflow_state.clients.get(singlesigIdentifierData.agent.name);
return (0, multisig_utils_js_1.admitMultisig)(client, aid, recepientAids.filter((_, i) => i !== index), recipientAID, issuerAID, admitTime);
}));
(0, test_util_js_1.sleep)(2000);
for (const aid of issuerAids) {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/exn/ipex/admit');
}
for (const aid of recepientAids) {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/multisig/exn');
}
for (const aid of recepientAids) {
const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name);
yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/exn/ipex/admit');
}
(0, test_util_js_1.sleep)(1000);