Skip to content

Commit

Permalink
Merge pull request #148 from nkongsuwan/example-delegation-multisig
Browse files Browse the repository at this point in the history
Example for delegation with multisig
  • Loading branch information
lenkan committed Dec 14, 2023
2 parents d311c1e + 623f479 commit 421232d
Showing 1 changed file with 227 additions and 0 deletions.
227 changes: 227 additions & 0 deletions examples/integration-scripts/delegation-multisig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
import { strict as assert } from 'assert';
import signify from 'signify-ts';
import { resolveEnvironment } from './utils/resolve-env';

const { url, bootUrl } = resolveEnvironment();

test('delegation-multisig', async () => {
await signify.ready();
// Boot three clients
const client0 = await bootClient();
const client1 = await bootClient();
const client2 = await bootClient();

// Create four identifiers, one for each client
let aid0 = await createAID(client0, 'delegator');

Check warning on line 15 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'aid0' is never reassigned. Use 'const' instead

Check warning on line 15 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'aid0' is never reassigned. Use 'const' instead
let aid1 = await createAID(client1, 'member1');

Check warning on line 16 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'aid1' is never reassigned. Use 'const' instead

Check warning on line 16 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'aid1' is never reassigned. Use 'const' instead
let aid2 = await createAID(client2, 'member2');

Check warning on line 17 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'aid2' is never reassigned. Use 'const' instead

Check warning on line 17 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'aid2' is never reassigned. Use 'const' instead

// Exchange OOBIs
console.log('Resolving OOBIs');
let oobi0 = await client0.oobis().get('delegator', 'agent');

Check warning on line 21 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'oobi0' is never reassigned. Use 'const' instead

Check warning on line 21 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'oobi0' is never reassigned. Use 'const' instead
let oobi1 = await client1.oobis().get('member1', 'agent');

Check warning on line 22 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'oobi1' is never reassigned. Use 'const' instead

Check warning on line 22 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'oobi1' is never reassigned. Use 'const' instead
let oobi2 = await client2.oobis().get('member2', 'agent');

Check warning on line 23 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'oobi2' is never reassigned. Use 'const' instead

Check warning on line 23 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'oobi2' is never reassigned. Use 'const' instead

let op1 = await client1.oobis().resolve(oobi0.oobis[0], 'delegator');
op1 = await waitForOp(client1, op1);
op1 = await client1.oobis().resolve(oobi2.oobis[0], 'member2');
op1 = await waitForOp(client1, op1);
console.log('Member1 resolved 2 OOBIs');

let op2 = await client2.oobis().resolve(oobi0.oobis[0], 'delegator');
op1 = await waitForOp(client2, op1);
op1 = await client2.oobis().resolve(oobi1.oobis[0], 'member1');
op1 = await waitForOp(client2, op1);
console.log('Member2 resolved 2 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');

op1 = await client1.challenges().verify('member1', aid2.prefix, words);
op1 = await waitForOp(client1, op1);
console.log('Member1 verified challenge response from member2');
let exnwords = new signify.Serder(op1.response.exn);

Check warning on line 49 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and macOS-latest

'exnwords' is never reassigned. Use 'const' instead

Check warning on line 49 in examples/integration-scripts/delegation-multisig.test.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 18.12.1 and ubuntu-latest

'exnwords' is never reassigned. Use 'const' instead
op1 = await client1
.challenges()
.responded('member1', aid2.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('multisig', {
algo: signify.Algos.group,
mhab: aid1,
isith: 2,
nsith: 2,
// toad: 3,
// wits: [
// 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha',
// 'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM',
// 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX',
// ],
states: states,
rstates: rstates,
delpre: aid0.prefix,
});
op1 = await icpResult1.op();
let serder = icpResult1.serder;

let sigs = icpResult1.sigs;
let sigers = sigs.map((sig: any) => 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 waitForMessage(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('multisig', {
algo: signify.Algos.group,
mhab: aid2,
isith: icp.kt,
nsith: icp.nt,
toad: parseInt(icp.bt),
wits: icp.b,
states: states,
rstates: rstates,
delpre: aid0.prefix,
});
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);
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...');

let delegatePrefix = op1.name.split('.')[1];
assert.equal(op2.name.split('.')[1], delegatePrefix);
console.log("Delegate's prefix:", delegatePrefix);
console.log('Delegate waiting for approval...');

// Client 0 approves delegation
const anchor = {
i: delegatePrefix,
s: 0,
d: delegatePrefix,
};
await client0.identifiers().interact('delegator', anchor);
console.log('Delegator approved delegation');

// Check for completion
op1 = await waitForOp(client1, op1);
op2 = await waitForOp(client2, op2);
console.log('Delegated multisig created!');

const aid_delegate = await client1.identifiers().get('multisig');
assert.equal(aid_delegate.prefix, delegatePrefix);
}, 30000);

async function waitForOp(client: signify.SignifyClient, op: any) {
while (!op['done']) {
op = await client.operations().get(op.name);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
return op;
}

async function waitForMessage(client: signify.SignifyClient, route: string) {
let msgSaid = '';
while (msgSaid == '') {
let notifications = await client.notifications().list();
for (let 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 bootClient(): Promise<signify.SignifyClient> {
let bran = signify.randomPasscode();
let client = new signify.SignifyClient(
url,
bran,
signify.Tier.low,
bootUrl
);
await client.boot();
await client.connect();
let state = await client.state();
console.log(
'Client AID:',
state.controller.state.i,
'Agent AID: ',
state.agent.i
);
return client;
}

async function createAID(client: signify.SignifyClient, name: string) {
let icpResult1 = await client.identifiers().create(name, {
toad: 3,
wits: [
'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha',
'BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM',
'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX',
],
});
let op = await icpResult1.op();
op = await waitForOp(client, op);
let aid = await client.identifiers().get(name);
await client.identifiers().addEndRole(name, 'agent', client!.agent!.pre);
console.log(name, 'AID:', aid.prefix);
return aid;
}

0 comments on commit 421232d

Please sign in to comment.