Skip to content

Commit

Permalink
Merge pull request WebOfTrust#120 from rodolfomiranda/end_role
Browse files Browse the repository at this point in the history
Multisig end role authorization
  • Loading branch information
rodolfomiranda authored Oct 18, 2023
2 parents d2242e3 + e72da5e commit dcf6394
Showing 5 changed files with 211 additions and 7 deletions.
192 changes: 189 additions & 3 deletions examples/integration-scripts/multisig.ts
Original file line number Diff line number Diff line change
@@ -366,7 +366,6 @@ async function run() {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
console.log('Multisig created!');

const identifiers1 = await client1.identifiers().list();
assert.equal(identifiers1.aids.length, 2);
assert.equal(identifiers1.aids[0].name, 'member1');
@@ -406,6 +405,191 @@ async function run() {

let multisig = identifiers3.aids[1].prefix;

// Multisig end role
// for brevity, this script authorize only the agent of member 1
// a full implementation should repeat the process to authorize all agents

let members = await client1.identifiers().members('multisig');
let hab = await client1.identifiers().get('multisig');
let aid = hab['prefix'];
let signing = members['signing'];
let eid1 = Object.keys(signing[0].ends.agent)[0]; //agent of member 1
// other agent eids can be obtained with
// let eid2 = Object.keys(signing[1].ends.agent)[0];
// let eid3 = Object.keys(signing[2].ends.agent)[0];
console.log(`Starting multisig end role authorization for agent ${eid1}`);

// initial stamp for the event that will be passed in the exn message
// to the other members
let stamp = new Date().toISOString().replace('Z', '000+00:00');

let endRoleRes = await client1
.identifiers()
.addEndRole('multisig', 'agent', eid1, stamp);
op1 = await endRoleRes.op();
let rpy = endRoleRes.serder;
sigs = endRoleRes.sigs;
let mstate = hab['state'];
let seal = [
'SealEvent',
{ i: hab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] },
];
sigers = sigs.map((sig: any) => new signify.Siger({ qb64: sig }));
let roleims = signify.d(
signify.messagize(rpy, sigers, seal, undefined, undefined, false)
);
atc = roleims.substring(rpy.size);
let roleembeds: any = {
rpy: [rpy, atc],
};
recp = [aid2['state'], aid3['state']].map((state) => state['i']);
res = await client1
.exchanges()
.send(
'member1',
'multisig',
aid1,
'/multisig/rpy',
{ gid: aid },
roleembeds,
recp
);
console.log(
`Member1 authorized agent role to ${eid1}, waiting for others to authorize...`
);

//Member2 check for notifications and join the authorization
msgSaid = '';
while (msgSaid == '') {
let notifications = await client2.notifications().list(1);
for (let notif of notifications.notes) {
if (notif.a.r == '/multisig/rpy') {
msgSaid = notif.a.d;
await client2.notifications().mark(notif.i);
console.log(
'Member2 received exchange message to join the end role authorization'
);
}
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
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('multisig', rpyrole, rpyeid, rpystamp);
op2 = await endRoleRes.op();
rpy = endRoleRes.serder;
sigs = endRoleRes.sigs;

hab = await client2.identifiers().get('multisig');
mstate = hab['state'];
seal = [
'SealEvent',
{ i: hab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] },
];
sigers = sigs.map((sig: any) => 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'], aid3['state']].map((state) => state['i']);
res = await client2
.exchanges()
.send(
'member2',
'multisig',
aid2,
'/multisig/rpy',
{ gid: aid },
roleembeds,
recp
);
console.log(
`Member2 authorized agent role to ${eid1}, waiting for others to authorize...`
);

//Member3 check for notifications and join the authorization
msgSaid = '';
while (msgSaid == '') {
let notifications = await client3.notifications().list(1);
for (let notif of notifications.notes) {
if (notif.a.r == '/multisig/rpy') {
msgSaid = notif.a.d;
await client3.notifications().mark(notif.i);
console.log(
'Member3 received exchange message to join the end role authorization'
);
}
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
res = await client3.groups().getRequest(msgSaid);
exn = res[0].exn;
rpystamp = exn.e.rpy.dt;
rpyrole = exn.e.rpy.a.role;
rpyeid = exn.e.rpy.a.eid;
endRoleRes = await client3
.identifiers()
.addEndRole('multisig', rpyrole, rpyeid, rpystamp);

op3 = await endRoleRes.op();
rpy = endRoleRes.serder;
sigs = endRoleRes.sigs;
hab = await client3.identifiers().get('multisig');
mstate = hab['state'];
seal = [
'SealEvent',
{ i: hab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] },
];
sigers = sigs.map((sig: any) => 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'], aid2['state']].map((state) => state['i']);
res = await client3
.exchanges()
.send(
'member3',
'multisig',
aid3,
'/multisig/rpy',
{ gid: aid },
roleembeds,
recp
);
console.log(
`Member3 authorized agent role to ${eid1}, waiting for others to authorize...`
);

// Check for completion
while (!op1['done']) {
op1 = await client1.operations().get(op1.name);
await new Promise((resolve) => setTimeout(resolve, 1000));
}

while (!op2['done']) {
op2 = await client2.operations().get(op2.name);
await new Promise((resolve) => setTimeout(resolve, 1000));
}

while (!op3['done']) {
op3 = await client3.operations().get(op3.name);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
console.log(`End role authorization for agent ${eid1}completed!`);

// MultiSig Interaction

// Member1 initiates an interaction event
@@ -767,6 +951,8 @@ async function run() {
}
console.log('Multisig rotation completed!');

// Multisig Registry creation

console.log('Starting multisig registry creation');

let vcpRes1 = await client1.registries().create({
@@ -854,7 +1040,7 @@ async function run() {
regbeds,
recp
);
console.log('Member2 joins rotation event, waiting for others...');
console.log('Member2 joins registry event, waiting for others...');

// Member3 check for notifications and join the create registry event
msgSaid = '';
@@ -923,5 +1109,5 @@ async function run() {
op3 = await client3.operations().get(op3.name);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
// console.log("Multisig create registry completed!")
console.log('Multisig create registry completed!');
}
2 changes: 2 additions & 0 deletions examples/integration-scripts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/keri/app/aiding.ts
Original file line number Diff line number Diff line change
@@ -370,7 +370,7 @@ export class Identifier {
* @param {string} role Authorized role for eid
* @param {string} [eid] Optional qb64 of endpoint provider to be authorized
* @param {string} [stamp=now] Optional date-time-stamp RFC-3339 profile of iso8601 datetime. Now is the default if not provided
* @returns {Promise<any>} A promise to the result of the authorization
* @returns {Promise<EventResult>} A promise to the result of the authorization
*/
async addEndRole(
name: string,
@@ -390,12 +390,12 @@ export class Identifier {
sigs: sigs,
};

let res = await this.client.fetch(
let res = this.client.fetch(
'/identifiers/' + name + '/endroles',
'POST',
jsondata
);
return await res.json();
return new EventResult(rpy, sigs, res);
}

/**
5 changes: 4 additions & 1 deletion src/keri/app/exchanging.ts
Original file line number Diff line number Diff line change
@@ -140,7 +140,10 @@ export function exchange(
): [Serder, Uint8Array] {
const vs = versify(Ident.KERI, undefined, Serials.JSON, 0);
const ilk = Ilks.exn;
const dt = date !== undefined ? date : nowUTC().toISOString();
const dt =
date !== undefined
? date
: nowUTC().toISOString().replace('Z', '000+00:00');
const p = dig !== undefined ? dig : '';
const q = modifiers !== undefined ? modifiers : {};
const ems = embeds != undefined ? embeds : {};
13 changes: 13 additions & 0 deletions test/core/eventing.test.ts
Original file line number Diff line number Diff line change
@@ -172,5 +172,18 @@ describe('key event function', () => {
'"nt":1,"n":["EIf-ENw7PrM52w4H-S7NGU2qVIfraXVIlV9hEAaMHg7W"],"bt":0,"b":[],"c":[],"a":[]}' +
'-AABAABB3MJGmBXxSEryNHw3YwZZLRl_6Ws4Me2WFq8PrQ6WlluSOpPqbwXuiG9RvNWZkqeW8A_0VRjokGMVRZ3m-c0I'
);
let seal = [
'SealEvent',
{ i: 'EIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL', s: '0', d: 'EIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL' },
];
let msgseal = messagize(serder0, [siger], seal);
assert.equal(
d(msgseal),
'{"v":"KERI10JSON000125_","t":"icp","d":"EIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL","i"'+
':"EIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL","s":"0","kt":1,"k":["DFs8BBx86uytIM0D2BhsE5rrqVIT8ef8mflpNceHo4XH"]'+
',"nt":1,"n":["EIf-ENw7PrM52w4H-S7NGU2qVIfraXVIlV9hEAaMHg7W"],"bt":0,"b":[],"c":[],"a"'+
':[]}-FABEIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL0AAAAAAAAAAAAAAAAAAAAAAAEIflL4H4134zYoRM6ls6Q086RLC_'+
'BhfNFh5uk-WxvhsL-AABAABB3MJGmBXxSEryNHw3YwZZLRl_6Ws4Me2WFq8PrQ6WlluSOpPqbwXuiG9RvNWZkqeW8A_0VRjokGMVRZ3m-c0I'
);
});
});

0 comments on commit dcf6394

Please sign in to comment.