Skip to content

Commit

Permalink
multisig with notif
Browse files Browse the repository at this point in the history
  • Loading branch information
Rodolfo Miranda committed Sep 9, 2023
1 parent d4db431 commit 536c3b9
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 47 deletions.
221 changes: 194 additions & 27 deletions examples/integration-scripts/multisig.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import { strict as assert } from "assert";
import signify from "signify-ts";

let signify: any;
const url = "http://127.0.0.1:3901"
const boot_url = "http://127.0.0.1:3903"

// @ts-ignore
import('signify-ts').then(
(module) => {
signify = module
signify.ready().then(() => {
console.log("*** Starting MULTISIG test ***");
run().then(() => {
console.log("*** Test complete ***")
});
});
}
)
await run()

async function run() {

await signify.ready()
// Boot three clients
const bran1 = signify.randomPasscode()
const bran2 = signify.randomPasscode()
Expand Down Expand Up @@ -53,7 +42,7 @@ async function run() {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
const aid1 = await client1.identifiers().get("member1")
let aid1 = await client1.identifiers().get("member1")
await client1.identifiers().addEndRole("member1", 'agent', client1!.agent!.pre)
console.log("Member1's AID:", aid1.prefix)

Expand All @@ -69,7 +58,7 @@ async function run() {
op2 = await client2.operations().get(op2.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
const aid2 = await client2.identifiers().get("member2")
let aid2 = await client2.identifiers().get("member2")
await client2.identifiers().addEndRole("member2", 'agent', client2!.agent!.pre)
console.log("Member2's AID:", aid2.prefix)

Expand All @@ -85,11 +74,11 @@ async function run() {
op3 = await client3.operations().get(op3.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
const aid3 = await client3.identifiers().get("member3")
let aid3 = await client3.identifiers().get("member3")
await client3.identifiers().addEndRole("member3", 'agent', client3!.agent!.pre)
console.log("Member3's AID:", aid3.prefix)

// Exchenge OOBIs
// Exchange OOBIs
console.log("Resolving OOBIs")
let oobi1 = await client1.oobis().get("member1","agent")
let oobi2 = await client2.oobis().get("member2","agent")
Expand Down Expand Up @@ -163,7 +152,7 @@ async function run() {

await client1.exchanges().send("member1", "multisig", aid1, "/multisig/icp",
{'gid': serder.pre, smids: smids, rmids: smids}, embeds, recp)
console.log("Member1 create multisig, waiting for others...")
console.log("Member1 initiated multisig, waiting for others to join...")

// Second member check notifications and join the multisig
let msgSaid = ""
Expand All @@ -173,7 +162,7 @@ async function run() {
if (notif.a.r == '/multisig/icp') {
msgSaid = notif.a.d
await client2.notifications().mark(notif.i)
console.log("Member2 received request to join multisig")
console.log("Member2 received exchange message to join multisig")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
Expand Down Expand Up @@ -220,7 +209,7 @@ async function run() {
if (notif.a.r == '/multisig/icp') {
msgSaid = notif.a.d
await client3.notifications().mark(notif.i)
console.log("Member3 received request to join multisig")
console.log("Member3 received exchange message to join multisig")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
Expand Down Expand Up @@ -257,6 +246,7 @@ async function run() {
{'gid': serder.pre, smids: smids, rmids: smids}, embeds, recp)
console.log("Member3 joined, multisig waiting for others...")

// Check for completion
while (!op1["done"]) {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
Expand Down Expand Up @@ -291,9 +281,9 @@ async function run() {
console.log("Client 3 managed AIDs:", identifiers3.aids[0].name, identifiers3.aids[1].name)


// Join an interaction event with the group
// MultiSig Interaction

// Member1 propose an interaction event
// Member1 initiates an interaction event
let data = {"i": "EE77q3_zWb5ojgJr-R1vzsL5yiL4Nzm-bfSOQzQl02dy"}
let eventResponse1 = await client1.identifiers().interact("multisig", data)
op1 = await eventResponse1.op()
Expand All @@ -312,7 +302,7 @@ async function run() {

await client1.exchanges().send("member1", "multisig", aid1, "/multisig/ixn",
{'gid': serder.pre, smids: smids, rmids: smids}, xembeds, recp)
console.log("Member1 initiates interaction event, waiting for others...")
console.log("Member1 initiates interaction event, waiting for others to join...")

// Member2 check for notifications and join the interaction event
msgSaid = ""
Expand All @@ -322,7 +312,7 @@ async function run() {
if (notif.a.r == '/multisig/ixn') {
msgSaid = notif.a.d
await client2.notifications().mark(notif.i)
console.log("Member2 received request to join the interaction event")
console.log("Member2 received exchange message to join the interaction event")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
Expand Down Expand Up @@ -359,7 +349,7 @@ async function run() {
if (notif.a.r == '/multisig/ixn') {
msgSaid = notif.a.d
await client3.notifications().mark(notif.i)
console.log("Member3 received request to join the interaction event")
console.log("Member3 received exchange message to join the interaction event")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
Expand Down Expand Up @@ -401,5 +391,182 @@ async function run() {
op3 = await client3.operations().get(op3.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log("Multisig interaction comlpeted!")
console.log("Multisig interaction completed!")

// Members agree out of band to rotate keys
console.log("Members agree out of band to rotate keys")
icpResult1 = await client1.identifiers().rotate('member1')
op1 = await icpResult1.op()
while (!op1["done"]) {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
aid1 = await client1.identifiers().get("member1")

console.log("Member1 rotated keys")
icpResult2 = await client2.identifiers().rotate('member2')
op2 = await icpResult2.op()
while (!op2["done"]) {
op2 = await client2.operations().get(op2.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
aid2 = await client2.identifiers().get("member2")
console.log("Member2 rotated keys")
icpResult3 = await client3.identifiers().rotate('member3')
op3 = await icpResult3.op()
while (!op3["done"]) {
op3 = await client3.operations().get(op3.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
aid3 = await client3.identifiers().get("member3")
console.log("Member3 rotated keys")

// Update new key states
op1 = await client1.keyStates().query(aid2.prefix,1)
while (!op1["done"]) {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
let aid2State = op1["response"]
op1 = await client1.keyStates().query(aid3.prefix,1)
while (!op1["done"]) {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
let aid3State = op1["response"]

op2 = await client2.keyStates().query(aid3.prefix,1)
while (!op2["done"]) {
op2 = await client2.operations().get(op2.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
op2 = await client2.keyStates().query(aid1.prefix,1)
while (!op2["done"]) {
op2 = await client2.operations().get(op2.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
let aid1State = op2["response"]

op3 = await client3.keyStates().query(aid1.prefix,1)
while (!op3["done"]) {
op3 = await client3.operations().get(op3.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
op3 = await client3.keyStates().query(aid2.prefix,1)
while (!op3["done"]) {
op3 = await client3.operations().get(op3.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}

rstates = [aid1State, aid2State, aid3State]
states = rstates

// Multisig Rotation

// Member1 initiates a rotation event
eventResponse1 = await client1.identifiers().rotate("multisig",{states: states,rstates: rstates})
op1 = await eventResponse1.op()
serder = eventResponse1.serder
sigs = eventResponse1.sigs
sigers = sigs.map((sig: any) => new signify.Siger({qb64: sig}))

ims = signify.d(signify.messagize(serder, sigers))
atc = ims.substring(serder.size)
let rembeds = {
rot: [serder, atc],
}

smids = states.map((state) => state['i'])
recp = [aid2State, aid3State].map((state) => state['i'])

await client1.exchanges().send("member1", "multisig", aid1 , "/multisig/rot",
{'gid': serder.pre, smids: smids, rmids: smids}, rembeds, recp)
console.log("Member1 initiates rotation event, waiting for others to join...")

// Member2 check for notifications and join the rotation event
msgSaid = ""
while (msgSaid=="") {
let notifications = await client2.notifications().list()
for (let notif of notifications.notes){
if (notif.a.r == '/multisig/rot') {
msgSaid = notif.a.d
await client2.notifications().mark(notif.i)
console.log("Member2 received exchange message to join the rotation event")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
}

await new Promise(resolve => setTimeout(resolve, 5000));
res = await client2.groups().getRequest(msgSaid)
exn = res[0].exn

icpResult2 = await client2.identifiers().rotate("multisig",{states: states,rstates: rstates})
op2 = await icpResult2.op()
serder = icpResult2.serder
sigs = icpResult2.sigs
sigers = sigs.map((sig: any) => new signify.Siger({qb64: sig}))

ims = signify.d(signify.messagize(serder, sigers))
atc = ims.substring(serder.size)
rembeds = {
rot: [serder, atc],
}

smids = exn.a.smids
recp = [aid1State, aid3State].map((state) => state['i'])

await client2.exchanges().send("member2", "multisig", aid2, "/multisig/ixn",
{'gid': serder.pre, smids: smids, rmids: smids}, rembeds, recp)
console.log("Member2 joins rotation event, waiting for others...")

// Member3 check for notifications and join the rotation event
msgSaid = ""
while (msgSaid=="") {
let notifications = await client3.notifications().list(1)
for (let notif of notifications.notes){
if (notif.a.r == '/multisig/rot') {
msgSaid = notif.a.d
await client3.notifications().mark(notif.i)
console.log("Member3 received exchange message to join the rotation event")
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
res = await client3.groups().getRequest(msgSaid)
exn = res[0].exn

icpResult3 = await client3.identifiers().rotate("multisig",{states: states,rstates: rstates})
op3 = await icpResult3.op()
serder = icpResult3.serder
sigs = icpResult3.sigs
sigers = sigs.map((sig: any) => new signify.Siger({qb64: sig}))

ims = signify.d(signify.messagize(serder, sigers))
atc = ims.substring(serder.size)
rembeds = {
rot: [serder, atc],
}

smids = exn.a.smids
recp = [aid1State, aid2State].map((state) => state['i'])

await client3.exchanges().send("member3", "multisig", aid3, "/multisig/ixn",
{'gid': serder.pre, smids: smids, rmids: smids}, rembeds, recp)
console.log("Member3 joins rotation event, waiting for others...")

// 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("Multisig rotation completed!")
}
1 change: 1 addition & 0 deletions examples/integration-scripts/tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
Expand Down
30 changes: 14 additions & 16 deletions examples/integration-scripts/witness.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
// This scrip also work if you start keria with no config file with witness urls
import { strict as assert } from "assert";
import signify from "signify-ts";

let signify: any;
const url = "http://127.0.0.1:3901"
const boot_url = "http://127.0.0.1:3903"

// @ts-ignore
import('signify-ts').then(
(module) => {
signify = module
signify.ready().then(() => {
console.log("*** Starting WITNESS test ***");
run().then(() => {
console.log("*** Test complete ***")
});
});
}
)

await run()
async function run() {

await signify.ready()
// Boot client
const bran1 = signify.randomPasscode()
const client1 = new signify.SignifyClient(url, bran1, signify.Tier.low, boot_url);
Expand Down Expand Up @@ -48,9 +36,19 @@ async function run() {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
const aid1 = await client1.identifiers().get("aid1")
let aid1 = await client1.identifiers().get("aid1")
console.log("AID:",aid1.prefix)
assert.equal(aid1.state.b.length, 1)
assert.equal(aid1.state.b[0], witness)

icpResult1 = await client1.identifiers().rotate('aid1')
op1 = await icpResult1.op()
while (!op1["done"] ) {
op1 = await client1.operations().get(op1.name);
await new Promise(resolve => setTimeout(resolve, 1000));
}
aid1 = await client1.identifiers().get("aid1")
assert.equal(aid1.state.b.length, 1)
assert.equal(aid1.state.b[0], witness)

}
7 changes: 3 additions & 4 deletions src/keri/core/eventing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,9 @@ export function rotate({
throw new Error(`Invalid member combination among cuts = ${cuts}, and adds = ${adds}.`)
}

let newitsetdiff = new Set([...witset].filter(x => cutset.has(x)))
let newitset = new Set()
newitsetdiff.forEach(newitset.add, newitset)
addset.forEach(newitset.add, newitset)
let newitsetdiff = new Set(_wits)
_cuts.forEach(function(v) {newitsetdiff.delete(v) })
let newitset = new Set(function*() { yield* newitsetdiff; yield* addset; }())

if (newitset.size != (witset.size - cutset.size + addset.size)) {
throw new Error(`Invalid member combination among wits = ${wits}, cuts = ${cuts}, and adds = ${adds}.`)
Expand Down

0 comments on commit 536c3b9

Please sign in to comment.