From 2ed39090dd18d8bbe32f3d0de4c6b938914c07ea Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Tue, 9 Jan 2024 09:27:08 -0500 Subject: [PATCH 1/5] create initial version of multisig-holder script --- .../multisig-holder.test.ts | 696 ++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 examples/integration-scripts/multisig-holder.test.ts diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts new file mode 100644 index 00000000..7a69bd6a --- /dev/null +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -0,0 +1,696 @@ +import { strict as assert } from 'assert'; +import signify, { + SignifyClient, + Serder, + IssueCredentialResult, + IssueCredentialArgs, +} from 'signify-ts'; +import { resolveEnvironment } from './utils/resolve-env'; +import { waitForNotifications, waitOperation } from './utils/test-util'; +import { getOrCreateClient } from './utils/test-setup'; + +const { vleiServerUrl } = resolveEnvironment(); +const WITNESS_AIDS = [ + 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', + 'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM', + 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', +]; + +const SCHEMA_SAID = 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'; +const SCHEMA_OOBI = `${vleiServerUrl}/oobi/${SCHEMA_SAID}`; + +test('multisig', async function run() { + await signify.ready(); + // Boot Four clients + const [client1, client2, client3] = await Promise.all([ + getOrCreateClient(), + getOrCreateClient(), + getOrCreateClient() + ]); + + // Create three identifiers, one for each client + let [aid1, aid2, aid3] = await Promise.all([ + createAID(client1, 'member1', WITNESS_AIDS), + createAID(client2, 'member2', WITNESS_AIDS), + createAID(client3, 'issuer', WITNESS_AIDS), + ]); + + await createRegistry(client3, 'issuer', 'issuer-reg'); + + // Exchange OOBIs + console.log('Resolving OOBIs'); + const [oobi1, oobi2, oobi3] = await Promise.all([ + client1.oobis().get('member1', 'agent'), + client2.oobis().get('member2', 'agent'), + client3.oobis().get('issuer', 'agent') + ]); + + let op1 = await client1.oobis().resolve(oobi2.oobis[0], 'member2'); + op1 = await waitOperation(client1, op1); + op1 = await client1.oobis().resolve(oobi3.oobis[0], 'issuer'); + op1 = await waitOperation(client1, op1); + op1 = await client1.oobis().resolve(SCHEMA_OOBI, 'schema'); + op1 = await waitOperation(client1, op1); + console.log('Member1 resolved 3 OOBIs'); + + let op2 = await client2.oobis().resolve(oobi1.oobis[0], 'member1'); + op2 = await waitOperation(client2, op2); + op2 = await client2.oobis().resolve(oobi3.oobis[0], 'issuer'); + op2 = await waitOperation(client2, op2); + op2 = await client2.oobis().resolve(SCHEMA_OOBI, 'schema'); + op2 = await waitOperation(client2, op2); + console.log('Member2 resolved 3 OOBIs'); + + let op3 = await client3.oobis().resolve(oobi1.oobis[0], 'member1'); + op3 = await waitOperation(client3, op3); + op3 = await client3.oobis().resolve(oobi2.oobis[0], 'member2'); + op3 = await waitOperation(client3, op3); + op3 = await client3.oobis().resolve(SCHEMA_OOBI, 'schema'); + op3 = await waitOperation(client3, op3); + console.log('Issuer resolved 3 OOBIs'); + + // // First member challenge the other members with a random list of words + // // List of words should be passed to the other members out of band + // // The other members should do the same challenge/response flow, not shown here for brevity + // const words = (await client1.challenges().generate(128)).words; + // console.log('Member1 generated challenge words:', words); + + // await client2.challenges().respond('member2', aid1.prefix, words); + // console.log('Member2 responded challenge with signed words'); + + // await client3.challenges().respond('member3', aid1.prefix, words); + // console.log('Member3 responded challenge with signed words'); + + // op1 = await client1.challenges().verify('member1', aid2.prefix, words); + // op1 = await waitOperation(client1, op1); + // console.log('Member1 verified challenge response from member2'); + // let exnwords = new Serder(op1.response.exn); + // op1 = await client1 + // .challenges() + // .responded('member1', aid2.prefix, exnwords.ked.d); + // console.log('Member1 marked challenge response as accepted'); + + // op1 = await client1.challenges().verify('member1', aid3.prefix, words); + // op1 = await waitOperation(client1, op1); + // console.log('Member1 verified challenge response from member3'); + // exnwords = new Serder(op1.response.exn); + // op1 = await client1 + // .challenges() + // .responded('member1', aid3.prefix, exnwords.ked.d); + // console.log('Member1 marked challenge response as accepted'); + + //// First member start the creation of a multisig identifier + let rstates = [aid1['state'], aid2['state']]; + let states = rstates; + let icpResult1 = await client1.identifiers().create('holder', { + algo: signify.Algos.group, + mhab: aid1, + isith: 2, + nsith: 2, + toad: aid1.state.b.length, + wits: aid1.state.b, + states: states, + rstates: rstates, + }); + op1 = await icpResult1.op(); + let serder = icpResult1.serder; + + let sigs = icpResult1.sigs; + let sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + + let ims = signify.d(signify.messagize(serder, sigers)); + let atc = ims.substring(serder.size); + let embeds = { + icp: [serder, atc], + }; + + let smids = states.map((state) => state['i']); + let recp = [aid2['state']].map((state) => state['i']); + + await client1 + .exchanges() + .send( + 'member1', + 'multisig', + aid1, + '/multisig/icp', + { gid: serder.pre, smids: smids, rmids: smids }, + embeds, + recp + ); + console.log('Member1 initiated multisig, waiting for others to join...'); + + // Second member check notifications and join the multisig + + let msgSaid = await waitAndMarkNotification(client2, '/multisig/icp'); + console.log('Member2 received exchange message to join multisig'); + + let res = await client2.groups().getRequest(msgSaid); + let exn = res[0].exn; + let icp = exn.e.icp; + + let icpResult2 = await client2.identifiers().create('holder', { + algo: signify.Algos.group, + mhab: aid2, + isith: icp.kt, + nsith: icp.nt, + toad: parseInt(icp.bt), + wits: icp.b, + states: states, + rstates: rstates, + }); + op2 = await icpResult2.op(); + serder = icpResult2.serder; + sigs = icpResult2.sigs; + sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + + ims = signify.d(signify.messagize(serder, sigers)); + atc = ims.substring(serder.size); + embeds = { + icp: [serder, atc], + }; + + smids = exn.a.smids; + recp = [aid1['state']].map((state) => state['i']); + + await client2 + .exchanges() + .send( + 'member2', + 'multisig', + aid2, + '/multisig/icp', + { gid: serder.pre, smids: smids, rmids: smids }, + embeds, + recp + ); + console.log('Member2 joined multisig, waiting for others...'); + + // Check for completion + op1 = await waitOperation(client1, op1); + op2 = await waitOperation(client2, op2); + console.log('Multisig created!'); + + const identifiers1 = await client1.identifiers().list(); + assert.equal(identifiers1.aids.length, 2); + + const identifiers2 = await client2.identifiers().list(); + assert.equal(identifiers2.aids.length, 2); + + console.log( + 'Member 1 managed AIDs:\n', + identifiers1.aids[0].name, + `[${identifiers1.aids[0].prefix}]\n`, + identifiers1.aids[1].name, + `[${identifiers1.aids[1].prefix}]` + ); + console.log( + 'Member 2 managed AIDs:\n', + identifiers2.aids[0].name, + `[${identifiers2.aids[0].prefix}]\n`, + identifiers2.aids[1].name, + `[${identifiers2.aids[1].prefix}]` + ); + + const multisig = identifiers2.aids[1].prefix; + + // Multisig end role + + aid1 = await client1.identifiers().get('member1'); + aid2 = await client2.identifiers().get('member2'); + const members = await client1.identifiers().members('holder'); + let ghab1 = await client1.identifiers().get('holder'); + const signing = members['signing']; + const eid1 = Object.keys(signing[0].ends.agent)[0]; + const eid2 = Object.keys(signing[1].ends.agent)[0]; + + console.log(`Starting multisig end role authorization for agent ${eid1}`); + + + let stamp = createTimestamp(); + + let endRoleRes = await client1.identifiers().addEndRole('holder', 'agent', eid1, stamp); + op1 = await endRoleRes.op(); + let rpy = endRoleRes.serder; + sigs = endRoleRes.sigs; + let ghabState1 = ghab1['state']; + let seal = [ + 'SealEvent', + { i: ghab1['prefix'], s: ghabState1['ee']['s'], d: ghabState1['ee']['d'] }, + ]; + sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + let roleims = signify.d( + signify.messagize(rpy, sigers, seal, undefined, undefined, false) + ); + atc = roleims.substring(rpy.size); + let roleembeds = { + rpy: [rpy, atc], + }; + recp = [aid2['state']].map((state) => state['i']); + res = await client1 + .exchanges() + .send( + 'member1', + 'multisig', + aid1, + '/multisig/rpy', + { gid: ghab1['prefix'] }, + roleembeds, + recp + ); + console.log( + `Member1 authorized agent role to ${eid1}, waiting for others to authorize...` + ); + + //Member2 check for notifications and join the authorization + msgSaid = await waitAndMarkNotification(client2, '/multisig/rpy'); + console.log( + 'Member2 received exchange message to join the end role authorization' + ); + res = await client2.groups().getRequest(msgSaid); + exn = res[0].exn; + // stamp, eid and role are provided in the exn message + let rpystamp = exn.e.rpy.dt; + let rpyrole = exn.e.rpy.a.role; + let rpyeid = exn.e.rpy.a.eid; + + endRoleRes = await client2 + .identifiers() + .addEndRole('holder', rpyrole, rpyeid, rpystamp); + op2 = await endRoleRes.op(); + rpy = endRoleRes.serder; + sigs = endRoleRes.sigs; + + let ghab2 = await client2.identifiers().get('holder'); + let ghabState2 = ghab2['state']; + seal = [ + 'SealEvent', + { i: ghab2['prefix'], s: ghabState2['ee']['s'], d: ghabState2['ee']['d'] }, + ]; + sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + roleims = signify.d( + signify.messagize(rpy, sigers, seal, undefined, undefined, false) + ); + atc = roleims.substring(rpy.size); + roleembeds = { + rpy: [rpy, atc], + }; + recp = [aid1['state']].map((state) => state['i']); + res = await client2 + .exchanges() + .send( + 'member2', + 'multisig', + aid2, + '/multisig/rpy', + { gid: ghab2['prefix'] }, + roleembeds, + recp + ); + console.log( + `Member2 authorized agent role to ${eid1}, waiting for others to authorize...` + ); + // Check for completion + op1 = await waitOperation(client1, op1, 30); + op2 = await waitOperation(client2, op2, 30); + console.log(`End role authorization for agent ${eid1}completed!`); + + + console.log(`Starting multisig end role authorization for agent ${eid2}`); + + endRoleRes = await client1 + .identifiers() + .addEndRole('holder', 'agent', eid2, stamp); + op1 = await endRoleRes.op(); + rpy = endRoleRes.serder; + sigs = endRoleRes.sigs; + + ghab1 = await client1.identifiers().get('holder'); + ghabState1 = ghab1['state']; + seal = [ + 'SealEvent', + { i: ghab1['prefix'], s: ghabState1['ee']['s'], d: ghabState1['ee']['d'] }, + ]; + sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + roleims = signify.d( + signify.messagize(rpy, sigers, seal, undefined, undefined, false) + ); + atc = roleims.substring(rpy.size); + roleembeds = { + rpy: [rpy, atc], + }; + recp = [aid2['state']].map((state) => state['i']); + res = await client1 + .exchanges() + .send( + 'member1', + 'multisig', + aid1, + '/multisig/rpy', + { gid: ghab1['prefix'] }, + roleembeds, + recp + ); + console.log( + `Member1 authorized agent role to ${eid2}, waiting for others to authorize...` + ); + + //Member2 check for notifications and join the authorization + msgSaid = await waitAndMarkNotification(client2, '/multisig/rpy'); + console.log( + 'Member2 received exchange message to join the end role authorization' + ); + res = await client2.groups().getRequest(msgSaid); + exn = res[0].exn; + // stamp, eid and role are provided in the exn message + rpystamp = exn.e.rpy.dt; + rpyrole = exn.e.rpy.a.role; + rpyeid = exn.e.rpy.a.eid; + endRoleRes = await client2 + .identifiers() + .addEndRole('holder', rpyrole, rpyeid, rpystamp); + op2 = await endRoleRes.op(); + + rpy = endRoleRes.serder; + sigs = endRoleRes.sigs; + + ghab2 = await client2.identifiers().get('holder'); + ghabState2 = ghab2['state']; + seal = [ + 'SealEvent', + { i: ghab2['prefix'], s: ghabState2['ee']['s'], d: ghabState2['ee']['d'] }, + ]; + + sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); + roleims = signify.d( + signify.messagize(rpy, sigers, seal, undefined, undefined, false) + ); + atc = roleims.substring(rpy.size); + roleembeds = { + rpy: [rpy, atc], + }; + recp = [aid1['state']].map((state) => state['i']); + res = await client2 + .exchanges() + .send( + 'member2', + 'multisig', + aid2, + '/multisig/rpy', + { gid: ghab2['prefix'] }, + roleembeds, + recp + ); + + console.log( + `Member2 authorized agent role to ${eid2}, waiting for others to authorize...` + ); + // Check for completion + op1 = await waitOperation(client1, op1); + op2 = await waitOperation(client2, op2); + console.log(`End role authorization for agent ${eid2}completed!`); + + + // Holder resolve multisig OOBI + const oobiMultisig = await client1.oobis().get('holder', 'agent'); + console.log(`Memeber1: Holder multisig AID OOBIs` + JSON.stringify(oobiMultisig)); + + const oobiMultisig2 = await client2.oobis().get('holder', 'agent'); + console.log(`Memeber2: Holder multisig AID OOBIs` + JSON.stringify(oobiMultisig2)); + + + op3 = await client3.oobis().resolve(oobiMultisig.oobis[0], 'holder'); + op3 = await waitOperation(client3, op3); + console.log(`Issuer resolved multisig holder OOBI`); + + + let holderAid = await client1.identifiers().get('holder'); + aid1 = await client1.identifiers().get('member1'); + aid2 = await client2.identifiers().get('member2'); + + console.log(`Issuer starting credential issuance to holder...`); + const registires = await client3.registries().list('issuer'); + await issueCredential(client3, { + issuerName: 'issuer', + registryId: registires[0].regk, + schemaId: SCHEMA_SAID, + recipient: holderAid['prefix'], + data: { + LEI: '5493001KJTIIGC8Y1R17', + }, + }); + console.log(`Issuer sent credential grant to holder.`); + + console.log(`Member1 waits for grant notification...`); + let grantMsgSaid = await waitForNotification(client1, '/exn/ipex/grant') + console.log('Member1 received grant exn notification...'); + let exnRes = await client1.exchanges().get(grantMsgSaid) + + recp = [aid2['state']].map((state) => state['i']); + await multisigAdmitCredential( + client1, + 'holder', + 'member1', + exnRes.exn.d, + exnRes.exn.i, + recp + ) + console.log(`Member1 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) + + ////let grantMsgSaid2 = await waitAndMarkNotification(client2, '/exn/ipex/grant') + //let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant', true) + let grantMsgSaid2_1 = await waitForNotification(client2, '/multisig/exn', true) + console.log('Member2 received grant exn notification...'); + //assert.equal(grantMsgSaid, grantMsgSaid2); + + //let exnRes2 = await client2.exchanges().get(grantMsgSaid2) + let exnRes2_1 = await client2.exchanges().get(grantMsgSaid2_1) + console.log(`Memeber2: received grant multisig/exn notifications` + JSON.stringify(exnRes2_1)); + + let recp2 = [aid1['state']].map((state) => state['i']); + await multisigAdmitCredential( + client2, + 'holder', + 'member2', + exnRes.exn.d, + exnRes.exn.i, + recp2 + ) + console.log(`Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) + + // msgSaid = await waitForNotification(client3, '/exn/ipex/admit'); + // console.log('Member1 received exn notification with the admit response'); + + let creds = await client1.credentials().list(); + console.log(`Member1 has ${creds.length} credential`); + + while (creds.length < 1) { + console.log(' No credentials yet...'); + await new Promise((resolve) => setTimeout(resolve, 500)); + creds = await client1.credentials().list(); + } + console.log(`Holder has ${creds.length} credential ` + JSON.stringify(creds)); + + +}, 360000); + +async function waitAndMarkNotification(client: SignifyClient, route: string) { + const notes = await waitForNotifications(client, route); + + await Promise.all( + notes.map(async (note) => { + await client.notifications().mark(note.i); + }) + ); + + return notes[notes.length - 1]?.a.d ?? ''; +} + +export async function waitForNotification( + client: SignifyClient, + route: string, + enableLog: boolean = false +) { + if (enableLog === true) { + console.log(` Waiting for notification with route : ${route}`) + } + let msgSaid = '' + while (msgSaid == '') { + const notifications = await client.notifications().list() + if (enableLog === true) { + console.log(` Notifications list : ${JSON.stringify(notifications)}`) + } + for (const notif of notifications.notes) { + if (notif.a.r == route) { + msgSaid = notif.a.d + await client.notifications().mark(notif.i) + } + } + await new Promise((resolve) => setTimeout(resolve, 1000)) + } + return msgSaid +} + +async function createAID(client: SignifyClient, name: string, wits: string[]) { + const icpResult1 = await client.identifiers().create(name, { + toad: wits.length, + wits: wits, + }); + await waitOperation(client, await icpResult1.op()); + const aid = await client.identifiers().get(name); + await client.identifiers().addEndRole(name, 'agent', client!.agent!.pre); + console.log(name, 'AID:', aid.prefix); + return aid; +} + +async function createRegistry( + client: SignifyClient, + name: string, + registryName: string +) { + const result = await client.registries().create({ name, registryName }); + const op = await result.op(); + await waitOperation(client, op); + + const registries = await client.registries().list(name); + assert.equal(registries.length, 1); + assert.equal(registries[0].name, registryName); + + return registries[0]; +} + +async function issueCredential( + client: SignifyClient, + args: IssueCredentialArgs +) { + const result = await client.credentials().issue(args); + + await waitOperation(client, result.op); + + const creds = await client.credentials().list(); + assert.equal(creds.length, 1); + assert.equal(creds[0].sad.s, args.schemaId); + assert.equal(creds[0].status.s, '0'); + + const dt = createTimestamp(); + + if (args.recipient) { + const [grant, gsigs, end] = await client.ipex().grant({ + senderName: args.issuerName, + recipient: args.recipient, + datetime: dt, + acdc: result.acdc, + anc: result.anc, + iss: result.iss, + }); + + // await client + // .exchanges() + // .sendFromEvents(args.issuerName, 'credential', grant, gsigs, end, [ + // args.recipient, + // ]); + + await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); + } + + console.log('Grant message sent'); + + return creds[0]; +} + +function createTimestamp() { + const dt = new Date().toISOString().replace('Z', '000+00:00'); + return dt; +} + +async function multisigAdmitCredential( + client: SignifyClient, + groupName: string, + memberAlias: string, + grantSaid: string, + issuerPrefix: string, + recipients: string[] +) { + const dt = createTimestamp() + + let mHab = await client.identifiers().get(memberAlias) + let gHab = await client.identifiers().get(groupName) + + const [admit, sigs, end] = await client + .ipex() + .admit(groupName, '', grantSaid, dt) + + await client.ipex().submitAdmit(groupName, admit, sigs, end, [issuerPrefix]); + // await client + // .exchanges() + // .sendFromEvents(groupName, 'credential', admit, sigs, end, [issuerPrefix]) + + if (recipients?.length < 1) { + return; + } + + let mstate = gHab['state'] + let seal = [ + 'SealEvent', + { i: gHab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] } + ] + let sigers = sigs.map((sig: any) => new signify.Siger({ qb64: sig })) + let ims = signify.d(signify.messagize(admit, sigers, seal)) + let atc = ims.substring(admit.size) + atc += end + let gembeds = { + exn: [admit, atc] + } + + await client + .exchanges() + .send( + mHab.name, + 'multisig', + mHab, + '/multisig/exn', + { gid: gHab['prefix'] }, + gembeds, + recipients + ) +} + + +async function multisigIssue( + client: SignifyClient, + memberName: string, + groupName: string, + result: IssueCredentialResult +) { + const leaderHab = await client.identifiers().get(memberName); + const groupHab = await client.identifiers().get(groupName); + const members = await client.identifiers().members(groupName); + + const keeper = client.manager!.get(groupHab); + const sigs = await keeper.sign(signify.b(result.anc.raw)); + const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); + const ims = signify.d(signify.messagize(result.anc, sigers)); + const atc = ims.substring(result.anc.size); + + const embeds = { + acdc: [result.acdc, ''], + iss: [result.iss, ''], + anc: [result.anc, atc], + }; + + const recipients = members.signing + .map((m: { aid: string }) => m.aid) + .filter((aid: string) => aid !== leaderHab.prefix); + + await client + .exchanges() + .send( + memberName, + 'multisig', + leaderHab, + '/multisig/iss', + { gid: groupHab.prefix }, + embeds, + recipients + ); +} From 1abc08c9b2435f27788f8a9705008f48d4f45b21 Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Tue, 9 Jan 2024 19:33:15 -0500 Subject: [PATCH 2/5] add more logs to debug multisig-holder.test.ts script --- .../multisig-holder.test.ts | 173 +++++++----------- 1 file changed, 67 insertions(+), 106 deletions(-) diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts index 7a69bd6a..5986cd87 100644 --- a/examples/integration-scripts/multisig-holder.test.ts +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -4,9 +4,10 @@ import signify, { Serder, IssueCredentialResult, IssueCredentialArgs, + Operation, } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env'; -import { waitForNotifications, waitOperation } from './utils/test-util'; +import { sleep, waitForNotifications } from './utils/test-util'; import { getOrCreateClient } from './utils/test-setup'; const { vleiServerUrl } = resolveEnvironment(); @@ -69,36 +70,6 @@ test('multisig', async function run() { op3 = await waitOperation(client3, op3); console.log('Issuer resolved 3 OOBIs'); - // // First member challenge the other members with a random list of words - // // List of words should be passed to the other members out of band - // // The other members should do the same challenge/response flow, not shown here for brevity - // const words = (await client1.challenges().generate(128)).words; - // console.log('Member1 generated challenge words:', words); - - // await client2.challenges().respond('member2', aid1.prefix, words); - // console.log('Member2 responded challenge with signed words'); - - // await client3.challenges().respond('member3', aid1.prefix, words); - // console.log('Member3 responded challenge with signed words'); - - // op1 = await client1.challenges().verify('member1', aid2.prefix, words); - // op1 = await waitOperation(client1, op1); - // console.log('Member1 verified challenge response from member2'); - // let exnwords = new Serder(op1.response.exn); - // op1 = await client1 - // .challenges() - // .responded('member1', aid2.prefix, exnwords.ked.d); - // console.log('Member1 marked challenge response as accepted'); - - // op1 = await client1.challenges().verify('member1', aid3.prefix, words); - // op1 = await waitOperation(client1, op1); - // console.log('Member1 verified challenge response from member3'); - // exnwords = new Serder(op1.response.exn); - // op1 = await client1 - // .challenges() - // .responded('member1', aid3.prefix, exnwords.ked.d); - // console.log('Member1 marked challenge response as accepted'); - //// First member start the creation of a multisig identifier let rstates = [aid1['state'], aid2['state']]; let states = rstates; @@ -313,7 +284,7 @@ test('multisig', async function run() { // Check for completion op1 = await waitOperation(client1, op1, 30); op2 = await waitOperation(client2, op2, 30); - console.log(`End role authorization for agent ${eid1}completed!`); + console.log(`End role authorization for agent ${eid1} completed!`); console.log(`Starting multisig end role authorization for agent ${eid2}`); @@ -408,15 +379,15 @@ test('multisig', async function run() { // Check for completion op1 = await waitOperation(client1, op1); op2 = await waitOperation(client2, op2); - console.log(`End role authorization for agent ${eid2}completed!`); + console.log(`End role authorization for agent ${eid2} completed!`); // Holder resolve multisig OOBI const oobiMultisig = await client1.oobis().get('holder', 'agent'); - console.log(`Memeber1: Holder multisig AID OOBIs` + JSON.stringify(oobiMultisig)); + console.log(`Memeber1: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig)); const oobiMultisig2 = await client2.oobis().get('holder', 'agent'); - console.log(`Memeber2: Holder multisig AID OOBIs` + JSON.stringify(oobiMultisig2)); + console.log(`Memeber2: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig2)); op3 = await client3.oobis().resolve(oobiMultisig.oobis[0], 'holder'); @@ -430,6 +401,7 @@ test('multisig', async function run() { console.log(`Issuer starting credential issuance to holder...`); const registires = await client3.registries().list('issuer'); + let recps: string[] = [aid1['prefix'], aid2['prefix']] await issueCredential(client3, { issuerName: 'issuer', registryId: registires[0].regk, @@ -438,12 +410,14 @@ test('multisig', async function run() { data: { LEI: '5493001KJTIIGC8Y1R17', }, - }); + } + , recps + ); console.log(`Issuer sent credential grant to holder.`); - console.log(`Member1 waits for grant notification...`); + let grantMsgSaid = await waitForNotification(client1, '/exn/ipex/grant') - console.log('Member1 received grant exn notification...'); + console.log(`Member1 received /exn/ipex/grant msg with SAID: ${grantMsgSaid} `); let exnRes = await client1.exchanges().get(grantMsgSaid) recp = [aid2['state']].map((state) => state['i']); @@ -457,15 +431,15 @@ test('multisig', async function run() { ) console.log(`Member1 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) - ////let grantMsgSaid2 = await waitAndMarkNotification(client2, '/exn/ipex/grant') - //let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant', true) - let grantMsgSaid2_1 = await waitForNotification(client2, '/multisig/exn', true) - console.log('Member2 received grant exn notification...'); - //assert.equal(grantMsgSaid, grantMsgSaid2); - //let exnRes2 = await client2.exchanges().get(grantMsgSaid2) - let exnRes2_1 = await client2.exchanges().get(grantMsgSaid2_1) - console.log(`Memeber2: received grant multisig/exn notifications` + JSON.stringify(exnRes2_1)); + let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant') + //grantMsgSaid2 = await waitForNotification(client2, '/multisig/exn', true) + console.log(`Member2 received /exn/ipex/grant msg with SAID: ${grantMsgSaid2} `); + let exnRes2 = await client2.exchanges().get(grantMsgSaid2) + + assert.equal(grantMsgSaid, grantMsgSaid2); + + console.log(`Member2 /exn/ipex/grant msg : ` + JSON.stringify(exnRes2)); let recp2 = [aid1['state']].map((state) => state['i']); await multisigAdmitCredential( @@ -476,21 +450,28 @@ test('multisig', async function run() { exnRes.exn.i, recp2 ) - console.log(`Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) + console.log(`Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) // msgSaid = await waitForNotification(client3, '/exn/ipex/admit'); - // console.log('Member1 received exn notification with the admit response'); + // console.log('Issuer received exn admit response'); - let creds = await client1.credentials().list(); - console.log(`Member1 has ${creds.length} credential`); + let creds1 = await client1.credentials().list(); + console.log(`Member1 has ${creds1.length} credential`); - while (creds.length < 1) { - console.log(' No credentials yet...'); - await new Promise((resolve) => setTimeout(resolve, 500)); - creds = await client1.credentials().list(); - } - console.log(`Holder has ${creds.length} credential ` + JSON.stringify(creds)); + const MAX_RETRIES: number = 10 + let retryCount = 0 + while (retryCount < MAX_RETRIES) { + retryCount = retryCount + 1 + console.log(` retry-${retryCount}: No credentials yet...`); + + creds1 = await client1.credentials().list(); + if (creds1.length > 0) + break; + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + console.log(`Member1 has ${creds1.length} credential : ` + JSON.stringify(creds1)); + assert.equal(creds1.length, 1); }, 360000); @@ -509,13 +490,17 @@ async function waitAndMarkNotification(client: SignifyClient, route: string) { export async function waitForNotification( client: SignifyClient, route: string, - enableLog: boolean = false + enableLog: boolean = false, + maxRetries: number = 10 ) { if (enableLog === true) { console.log(` Waiting for notification with route : ${route}`) } + let retryCount = 0 let msgSaid = '' while (msgSaid == '') { + retryCount = retryCount + 1 + const notifications = await client.notifications().list() if (enableLog === true) { console.log(` Notifications list : ${JSON.stringify(notifications)}`) @@ -526,11 +511,30 @@ export async function waitForNotification( await client.notifications().mark(notif.i) } } + if (retryCount >= maxRetries) { + console.log(`No notification found with route : ${route}`) + break; + } + await new Promise((resolve) => setTimeout(resolve, 1000)) } return msgSaid } +export async function waitOperation( + client: SignifyClient, + op: Operation, + retries: number = 10 +): Promise> { + const WAIT = 1000; + while (retries-- > 0) { + op = await client.operations().get(op.name); + if (op.done === true) return op; + await sleep(WAIT); + } + throw new Error(`Timeout: operation ${op.name}`); +} + async function createAID(client: SignifyClient, name: string, wits: string[]) { const icpResult1 = await client.identifiers().create(name, { toad: wits.length, @@ -561,7 +565,8 @@ async function createRegistry( async function issueCredential( client: SignifyClient, - args: IssueCredentialArgs + args: IssueCredentialArgs, + recps: string[] ) { const result = await client.credentials().issue(args); @@ -584,13 +589,9 @@ async function issueCredential( iss: result.iss, }); - // await client - // .exchanges() - // .sendFromEvents(args.issuerName, 'credential', grant, gsigs, end, [ - // args.recipient, - // ]); - - await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); + //// TODO: use multisig holder as exn recipient + //await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); + await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, recps); } console.log('Grant message sent'); @@ -653,44 +654,4 @@ async function multisigAdmitCredential( gembeds, recipients ) -} - - -async function multisigIssue( - client: SignifyClient, - memberName: string, - groupName: string, - result: IssueCredentialResult -) { - const leaderHab = await client.identifiers().get(memberName); - const groupHab = await client.identifiers().get(groupName); - const members = await client.identifiers().members(groupName); - - const keeper = client.manager!.get(groupHab); - const sigs = await keeper.sign(signify.b(result.anc.raw)); - const sigers = sigs.map((sig: string) => new signify.Siger({ qb64: sig })); - const ims = signify.d(signify.messagize(result.anc, sigers)); - const atc = ims.substring(result.anc.size); - - const embeds = { - acdc: [result.acdc, ''], - iss: [result.iss, ''], - anc: [result.anc, atc], - }; - - const recipients = members.signing - .map((m: { aid: string }) => m.aid) - .filter((aid: string) => aid !== leaderHab.prefix); - - await client - .exchanges() - .send( - memberName, - 'multisig', - leaderHab, - '/multisig/iss', - { gid: groupHab.prefix }, - embeds, - recipients - ); -} +} \ No newline at end of file From ad5dc1a9cb23c5af07f5805fa811f32267072dd2 Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Tue, 9 Jan 2024 20:27:18 -0500 Subject: [PATCH 3/5] format code --- .../multisig-holder.test.ts | 175 +++++++++++------- 1 file changed, 103 insertions(+), 72 deletions(-) diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts index 5986cd87..848899da 100644 --- a/examples/integration-scripts/multisig-holder.test.ts +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -26,7 +26,7 @@ test('multisig', async function run() { const [client1, client2, client3] = await Promise.all([ getOrCreateClient(), getOrCreateClient(), - getOrCreateClient() + getOrCreateClient(), ]); // Create three identifiers, one for each client @@ -43,7 +43,7 @@ test('multisig', async function run() { const [oobi1, oobi2, oobi3] = await Promise.all([ client1.oobis().get('member1', 'agent'), client2.oobis().get('member2', 'agent'), - client3.oobis().get('issuer', 'agent') + client3.oobis().get('issuer', 'agent'), ]); let op1 = await client1.oobis().resolve(oobi2.oobis[0], 'member2'); @@ -185,7 +185,7 @@ test('multisig', async function run() { const multisig = identifiers2.aids[1].prefix; - // Multisig end role + // Multisig end role aid1 = await client1.identifiers().get('member1'); aid2 = await client2.identifiers().get('member2'); @@ -197,17 +197,22 @@ test('multisig', async function run() { console.log(`Starting multisig end role authorization for agent ${eid1}`); - let stamp = createTimestamp(); - let endRoleRes = await client1.identifiers().addEndRole('holder', 'agent', eid1, stamp); + let endRoleRes = await client1 + .identifiers() + .addEndRole('holder', 'agent', eid1, stamp); op1 = await endRoleRes.op(); let rpy = endRoleRes.serder; sigs = endRoleRes.sigs; let ghabState1 = ghab1['state']; let seal = [ 'SealEvent', - { i: ghab1['prefix'], s: ghabState1['ee']['s'], d: ghabState1['ee']['d'] }, + { + i: ghab1['prefix'], + s: ghabState1['ee']['s'], + d: ghabState1['ee']['d'], + }, ]; sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); let roleims = signify.d( @@ -256,7 +261,11 @@ test('multisig', async function run() { let ghabState2 = ghab2['state']; seal = [ 'SealEvent', - { i: ghab2['prefix'], s: ghabState2['ee']['s'], d: ghabState2['ee']['d'] }, + { + i: ghab2['prefix'], + s: ghabState2['ee']['s'], + d: ghabState2['ee']['d'], + }, ]; sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); roleims = signify.d( @@ -286,7 +295,6 @@ test('multisig', async function run() { op2 = await waitOperation(client2, op2, 30); console.log(`End role authorization for agent ${eid1} completed!`); - console.log(`Starting multisig end role authorization for agent ${eid2}`); endRoleRes = await client1 @@ -300,7 +308,11 @@ test('multisig', async function run() { ghabState1 = ghab1['state']; seal = [ 'SealEvent', - { i: ghab1['prefix'], s: ghabState1['ee']['s'], d: ghabState1['ee']['d'] }, + { + i: ghab1['prefix'], + s: ghabState1['ee']['s'], + d: ghabState1['ee']['d'], + }, ]; sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); roleims = signify.d( @@ -349,7 +361,11 @@ test('multisig', async function run() { ghabState2 = ghab2['state']; seal = [ 'SealEvent', - { i: ghab2['prefix'], s: ghabState2['ee']['s'], d: ghabState2['ee']['d'] }, + { + i: ghab2['prefix'], + s: ghabState2['ee']['s'], + d: ghabState2['ee']['d'], + }, ]; sigers = sigs.map((sig) => new signify.Siger({ qb64: sig })); @@ -381,44 +397,48 @@ test('multisig', async function run() { op2 = await waitOperation(client2, op2); console.log(`End role authorization for agent ${eid2} completed!`); - // Holder resolve multisig OOBI const oobiMultisig = await client1.oobis().get('holder', 'agent'); - console.log(`Memeber1: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig)); + console.log( + `Memeber1: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig) + ); const oobiMultisig2 = await client2.oobis().get('holder', 'agent'); - console.log(`Memeber2: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig2)); - + console.log( + `Memeber2: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig2) + ); op3 = await client3.oobis().resolve(oobiMultisig.oobis[0], 'holder'); op3 = await waitOperation(client3, op3); console.log(`Issuer resolved multisig holder OOBI`); - let holderAid = await client1.identifiers().get('holder'); aid1 = await client1.identifiers().get('member1'); aid2 = await client2.identifiers().get('member2'); console.log(`Issuer starting credential issuance to holder...`); const registires = await client3.registries().list('issuer'); - let recps: string[] = [aid1['prefix'], aid2['prefix']] - await issueCredential(client3, { - issuerName: 'issuer', - registryId: registires[0].regk, - schemaId: SCHEMA_SAID, - recipient: holderAid['prefix'], - data: { - LEI: '5493001KJTIIGC8Y1R17', + let recps: string[] = [aid1['prefix'], aid2['prefix']]; + await issueCredential( + client3, + { + issuerName: 'issuer', + registryId: registires[0].regk, + schemaId: SCHEMA_SAID, + recipient: holderAid['prefix'], + data: { + LEI: '5493001KJTIIGC8Y1R17', + }, }, - } - , recps + recps ); console.log(`Issuer sent credential grant to holder.`); - - let grantMsgSaid = await waitForNotification(client1, '/exn/ipex/grant') - console.log(`Member1 received /exn/ipex/grant msg with SAID: ${grantMsgSaid} `); - let exnRes = await client1.exchanges().get(grantMsgSaid) + let grantMsgSaid = await waitForNotification(client1, '/exn/ipex/grant'); + console.log( + `Member1 received /exn/ipex/grant msg with SAID: ${grantMsgSaid} ` + ); + let exnRes = await client1.exchanges().get(grantMsgSaid); recp = [aid2['state']].map((state) => state['i']); await multisigAdmitCredential( @@ -428,14 +448,17 @@ test('multisig', async function run() { exnRes.exn.d, exnRes.exn.i, recp - ) - console.log(`Member1 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) - + ); + console.log( + `Member1 admitted credential with SAID : ${exnRes.exn.e.acdc.d}` + ); - let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant') + let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant'); //grantMsgSaid2 = await waitForNotification(client2, '/multisig/exn', true) - console.log(`Member2 received /exn/ipex/grant msg with SAID: ${grantMsgSaid2} `); - let exnRes2 = await client2.exchanges().get(grantMsgSaid2) + console.log( + `Member2 received /exn/ipex/grant msg with SAID: ${grantMsgSaid2} ` + ); + let exnRes2 = await client2.exchanges().get(grantMsgSaid2); assert.equal(grantMsgSaid, grantMsgSaid2); @@ -449,8 +472,10 @@ test('multisig', async function run() { exnRes.exn.d, exnRes.exn.i, recp2 - ) - console.log(`Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}`) + ); + console.log( + `Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}` + ); // msgSaid = await waitForNotification(client3, '/exn/ipex/admit'); // console.log('Issuer received exn admit response'); @@ -458,21 +483,21 @@ test('multisig', async function run() { let creds1 = await client1.credentials().list(); console.log(`Member1 has ${creds1.length} credential`); - const MAX_RETRIES: number = 10 - let retryCount = 0 + const MAX_RETRIES: number = 10; + let retryCount = 0; while (retryCount < MAX_RETRIES) { - retryCount = retryCount + 1 + retryCount = retryCount + 1; console.log(` retry-${retryCount}: No credentials yet...`); creds1 = await client1.credentials().list(); - if (creds1.length > 0) - break; + if (creds1.length > 0) break; await new Promise((resolve) => setTimeout(resolve, 1000)); } - console.log(`Member1 has ${creds1.length} credential : ` + JSON.stringify(creds1)); + console.log( + `Member1 has ${creds1.length} credential : ` + JSON.stringify(creds1) + ); assert.equal(creds1.length, 1); - }, 360000); async function waitAndMarkNotification(client: SignifyClient, route: string) { @@ -494,31 +519,33 @@ export async function waitForNotification( maxRetries: number = 10 ) { if (enableLog === true) { - console.log(` Waiting for notification with route : ${route}`) + console.log(` Waiting for notification with route : ${route}`); } - let retryCount = 0 - let msgSaid = '' + let retryCount = 0; + let msgSaid = ''; while (msgSaid == '') { - retryCount = retryCount + 1 + retryCount = retryCount + 1; - const notifications = await client.notifications().list() + const notifications = await client.notifications().list(); if (enableLog === true) { - console.log(` Notifications list : ${JSON.stringify(notifications)}`) + console.log( + ` Notifications list : ${JSON.stringify(notifications)}` + ); } for (const notif of notifications.notes) { if (notif.a.r == route) { - msgSaid = notif.a.d - await client.notifications().mark(notif.i) + msgSaid = notif.a.d; + await client.notifications().mark(notif.i); } } if (retryCount >= maxRetries) { - console.log(`No notification found with route : ${route}`) + console.log(`No notification found with route : ${route}`); break; } - await new Promise((resolve) => setTimeout(resolve, 1000)) + await new Promise((resolve) => setTimeout(resolve, 1000)); } - return msgSaid + return msgSaid; } export async function waitOperation( @@ -591,7 +618,9 @@ async function issueCredential( //// TODO: use multisig holder as exn recipient //await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); - await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, recps); + await client + .ipex() + .submitGrant(args.issuerName, grant, gsigs, end, recps); } console.log('Grant message sent'); @@ -612,16 +641,18 @@ async function multisigAdmitCredential( issuerPrefix: string, recipients: string[] ) { - const dt = createTimestamp() + const dt = createTimestamp(); - let mHab = await client.identifiers().get(memberAlias) - let gHab = await client.identifiers().get(groupName) + let mHab = await client.identifiers().get(memberAlias); + let gHab = await client.identifiers().get(groupName); const [admit, sigs, end] = await client .ipex() - .admit(groupName, '', grantSaid, dt) + .admit(groupName, '', grantSaid, dt); - await client.ipex().submitAdmit(groupName, admit, sigs, end, [issuerPrefix]); + await client + .ipex() + .submitAdmit(groupName, admit, sigs, end, [issuerPrefix]); // await client // .exchanges() // .sendFromEvents(groupName, 'credential', admit, sigs, end, [issuerPrefix]) @@ -630,18 +661,18 @@ async function multisigAdmitCredential( return; } - let mstate = gHab['state'] + let mstate = gHab['state']; let seal = [ 'SealEvent', - { i: gHab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] } - ] - let sigers = sigs.map((sig: any) => new signify.Siger({ qb64: sig })) - let ims = signify.d(signify.messagize(admit, sigers, seal)) - let atc = ims.substring(admit.size) - atc += end + { i: gHab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] }, + ]; + let sigers = sigs.map((sig: any) => new signify.Siger({ qb64: sig })); + let ims = signify.d(signify.messagize(admit, sigers, seal)); + let atc = ims.substring(admit.size); + atc += end; let gembeds = { - exn: [admit, atc] - } + exn: [admit, atc], + }; await client .exchanges() @@ -653,5 +684,5 @@ async function multisigAdmitCredential( { gid: gHab['prefix'] }, gembeds, recipients - ) -} \ No newline at end of file + ); +} From b4b3bf3095597fbae14c230292975a144d5122b1 Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Sun, 14 Jan 2024 20:49:16 -0500 Subject: [PATCH 4/5] refractor multisig-holder test - refractor multisig-holder test - fix multisig-holder not receiving credential bug in multisig-holder.test.ts --- .../multisig-holder.test.ts | 104 +++--------------- 1 file changed, 18 insertions(+), 86 deletions(-) diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts index 848899da..d74819e8 100644 --- a/examples/integration-scripts/multisig-holder.test.ts +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -1,13 +1,7 @@ import { strict as assert } from 'assert'; -import signify, { - SignifyClient, - Serder, - IssueCredentialResult, - IssueCredentialArgs, - Operation, -} from 'signify-ts'; +import signify, { SignifyClient, IssueCredentialArgs } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env'; -import { sleep, waitForNotifications } from './utils/test-util'; +import { waitForNotifications, waitOperation } from './utils/test-util'; import { getOrCreateClient } from './utils/test-setup'; const { vleiServerUrl } = resolveEnvironment(); @@ -20,6 +14,8 @@ const WITNESS_AIDS = [ const SCHEMA_SAID = 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'; const SCHEMA_OOBI = `${vleiServerUrl}/oobi/${SCHEMA_SAID}`; +const TIME = createTimestamp(); + test('multisig', async function run() { await signify.ready(); // Boot Four clients @@ -291,8 +287,8 @@ test('multisig', async function run() { `Member2 authorized agent role to ${eid1}, waiting for others to authorize...` ); // Check for completion - op1 = await waitOperation(client1, op1, 30); - op2 = await waitOperation(client2, op2, 30); + op1 = await waitOperation(client1, op1); + op2 = await waitOperation(client2, op2); console.log(`End role authorization for agent ${eid1} completed!`); console.log(`Starting multisig end role authorization for agent ${eid2}`); @@ -398,17 +394,10 @@ test('multisig', async function run() { console.log(`End role authorization for agent ${eid2} completed!`); // Holder resolve multisig OOBI - const oobiMultisig = await client1.oobis().get('holder', 'agent'); - console.log( - `Memeber1: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig) - ); - - const oobiMultisig2 = await client2.oobis().get('holder', 'agent'); - console.log( - `Memeber2: Holder multisig AID OOBIs: ` + JSON.stringify(oobiMultisig2) - ); + const oobisRes = await client1.oobis().get('holder', 'agent'); + let oobiMultisig = oobisRes.oobis[0].split('/agent/')[0]; - op3 = await client3.oobis().resolve(oobiMultisig.oobis[0], 'holder'); + op3 = await client3.oobis().resolve(oobiMultisig, 'holder'); op3 = await waitOperation(client3, op3); console.log(`Issuer resolved multisig holder OOBI`); @@ -434,7 +423,10 @@ test('multisig', async function run() { ); console.log(`Issuer sent credential grant to holder.`); - let grantMsgSaid = await waitForNotification(client1, '/exn/ipex/grant'); + let grantMsgSaid = await waitAndMarkNotification( + client1, + '/exn/ipex/grant' + ); console.log( `Member1 received /exn/ipex/grant msg with SAID: ${grantMsgSaid} ` ); @@ -453,8 +445,10 @@ test('multisig', async function run() { `Member1 admitted credential with SAID : ${exnRes.exn.e.acdc.d}` ); - let grantMsgSaid2 = await waitForNotification(client2, '/exn/ipex/grant'); - //grantMsgSaid2 = await waitForNotification(client2, '/multisig/exn', true) + let grantMsgSaid2 = await waitAndMarkNotification( + client2, + '/exn/ipex/grant' + ); console.log( `Member2 received /exn/ipex/grant msg with SAID: ${grantMsgSaid2} ` ); @@ -477,9 +471,6 @@ test('multisig', async function run() { `Member2 admitted credential with SAID : ${exnRes.exn.e.acdc.d}` ); - // msgSaid = await waitForNotification(client3, '/exn/ipex/admit'); - // console.log('Issuer received exn admit response'); - let creds1 = await client1.credentials().list(); console.log(`Member1 has ${creds1.length} credential`); @@ -512,56 +503,6 @@ async function waitAndMarkNotification(client: SignifyClient, route: string) { return notes[notes.length - 1]?.a.d ?? ''; } -export async function waitForNotification( - client: SignifyClient, - route: string, - enableLog: boolean = false, - maxRetries: number = 10 -) { - if (enableLog === true) { - console.log(` Waiting for notification with route : ${route}`); - } - let retryCount = 0; - let msgSaid = ''; - while (msgSaid == '') { - retryCount = retryCount + 1; - - const notifications = await client.notifications().list(); - if (enableLog === true) { - console.log( - ` Notifications list : ${JSON.stringify(notifications)}` - ); - } - for (const notif of notifications.notes) { - if (notif.a.r == route) { - msgSaid = notif.a.d; - await client.notifications().mark(notif.i); - } - } - if (retryCount >= maxRetries) { - console.log(`No notification found with route : ${route}`); - break; - } - - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - return msgSaid; -} - -export async function waitOperation( - client: SignifyClient, - op: Operation, - retries: number = 10 -): Promise> { - const WAIT = 1000; - while (retries-- > 0) { - op = await client.operations().get(op.name); - if (op.done === true) return op; - await sleep(WAIT); - } - throw new Error(`Timeout: operation ${op.name}`); -} - async function createAID(client: SignifyClient, name: string, wits: string[]) { const icpResult1 = await client.identifiers().create(name, { toad: wits.length, @@ -641,25 +582,16 @@ async function multisigAdmitCredential( issuerPrefix: string, recipients: string[] ) { - const dt = createTimestamp(); - let mHab = await client.identifiers().get(memberAlias); let gHab = await client.identifiers().get(groupName); const [admit, sigs, end] = await client .ipex() - .admit(groupName, '', grantSaid, dt); + .admit(groupName, '', grantSaid, TIME); await client .ipex() .submitAdmit(groupName, admit, sigs, end, [issuerPrefix]); - // await client - // .exchanges() - // .sendFromEvents(groupName, 'credential', admit, sigs, end, [issuerPrefix]) - - if (recipients?.length < 1) { - return; - } let mstate = gHab['state']; let seal = [ From b6d7059a8e7418f0729d89d2ffbcd1080003c27e Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Mon, 15 Jan 2024 15:54:55 -0500 Subject: [PATCH 5/5] refractor: use multisig holder aid to send cred grant - refractor: use multisig holder aid to send cred grant instead of member AIDs Signed-off-by: arshdeep singh --- .../multisig-holder.test.ts | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/examples/integration-scripts/multisig-holder.test.ts b/examples/integration-scripts/multisig-holder.test.ts index d74819e8..ccc76871 100644 --- a/examples/integration-scripts/multisig-holder.test.ts +++ b/examples/integration-scripts/multisig-holder.test.ts @@ -67,9 +67,9 @@ test('multisig', async function run() { console.log('Issuer resolved 3 OOBIs'); //// First member start the creation of a multisig identifier - let rstates = [aid1['state'], aid2['state']]; - let states = rstates; - let icpResult1 = await client1.identifiers().create('holder', { + const rstates = [aid1['state'], aid2['state']]; + const states = rstates; + const icpResult1 = await client1.identifiers().create('holder', { algo: signify.Algos.group, mhab: aid1, isith: 2, @@ -179,8 +179,6 @@ test('multisig', async function run() { `[${identifiers2.aids[1].prefix}]` ); - const multisig = identifiers2.aids[1].prefix; - // Multisig end role aid1 = await client1.identifiers().get('member1'); @@ -407,20 +405,15 @@ test('multisig', async function run() { console.log(`Issuer starting credential issuance to holder...`); const registires = await client3.registries().list('issuer'); - let recps: string[] = [aid1['prefix'], aid2['prefix']]; - await issueCredential( - client3, - { - issuerName: 'issuer', - registryId: registires[0].regk, - schemaId: SCHEMA_SAID, - recipient: holderAid['prefix'], - data: { - LEI: '5493001KJTIIGC8Y1R17', - }, + await issueCredential(client3, { + issuerName: 'issuer', + registryId: registires[0].regk, + schemaId: SCHEMA_SAID, + recipient: holderAid['prefix'], + data: { + LEI: '5493001KJTIIGC8Y1R17', }, - recps - ); + }); console.log(`Issuer sent credential grant to holder.`); let grantMsgSaid = await waitAndMarkNotification( @@ -533,8 +526,7 @@ async function createRegistry( async function issueCredential( client: SignifyClient, - args: IssueCredentialArgs, - recps: string[] + args: IssueCredentialArgs ) { const result = await client.credentials().issue(args); @@ -557,11 +549,9 @@ async function issueCredential( iss: result.iss, }); - //// TODO: use multisig holder as exn recipient - //await client.ipex().submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); await client .ipex() - .submitGrant(args.issuerName, grant, gsigs, end, recps); + .submitGrant(args.issuerName, grant, gsigs, end, [args.recipient]); } console.log('Grant message sent');