diff --git a/examples/integration-scripts/README.md b/examples/integration-scripts/README.md deleted file mode 100644 index 07cf17d2..00000000 --- a/examples/integration-scripts/README.md +++ /dev/null @@ -1,17 +0,0 @@ -This folder contains scripts intended to test the integration between [signify-ts](https://github.com/WebOfTrust/signify-ts) and [keria](https://github.com/weboftrust/keria). The scripts execute basic KERI functionalities and may be helpful examples to implementors. - -Each script should be executed with: -`ts-node --esm script_name.ts` - -and requires [keria](https://github.com/weboftrust/keria) to be installed and running with: -`keria start --config-file demo-witness-oobis.json --config-dir ./scripts` - -If the script depends on witnesses, you need to have [keripy](https://github.com/WebOfTrust/keripy) installed and running with: -`kli witness demo` - -Additionally, if the script also depends on schemas you need to have [vLEI server](https://github.com/WebOfTrust/vLEI) installed and running with: -`vLEI-server -s ./schema/acdc -c ./samples/acdc/ -o ./samples/oobis/` - -You can also execute all script the scrip: -`run_all.sh` - diff --git a/examples/integration-scripts/challenge.ts b/examples/integration-scripts/challenge.test.ts similarity index 70% rename from examples/integration-scripts/challenge.ts rename to examples/integration-scripts/challenge.test.ts index be815fa5..d991e501 100644 --- a/examples/integration-scripts/challenge.ts +++ b/examples/integration-scripts/challenge.test.ts @@ -1,27 +1,25 @@ import { strict as assert } from 'assert'; import signify, { Serder } from 'signify-ts'; +import { resolveEnvironment } from './utils/resolve-env'; +import { waitOperation } from './utils/test-util'; -const url = 'http://127.0.0.1:3901'; -const boot_url = 'http://127.0.0.1:3903'; +const { url, bootUrl } = resolveEnvironment(); -await run(); - -async function run() { +test('challenge', async () => { await signify.ready(); - // Boot two clients const bran1 = signify.randomPasscode(); const bran2 = signify.randomPasscode(); const client1 = new signify.SignifyClient( url, bran1, signify.Tier.low, - boot_url + bootUrl ); const client2 = new signify.SignifyClient( url, bran2, signify.Tier.low, - boot_url + bootUrl ); await client1.boot(); await client2.boot(); @@ -57,12 +55,10 @@ async function run() { 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', ], }); - let op1 = await icpResult1.op(); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - const aid1 = op1['response']; + const { response: aid1 } = await waitOperation<{ i: string }>( + client1, + await icpResult1.op() + ); await client1 .identifiers() .addEndRole('alice', 'agent', client1!.agent!.pre); @@ -89,43 +85,45 @@ async function run() { const oobi1 = await client1.oobis().get('alice', 'agent'); const oobi2 = await client2.oobis().get('bob', 'agent'); - op1 = await client1.oobis().resolve(oobi2.oobis[0], 'bob'); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation( + client1, + await client1.oobis().resolve(oobi2.oobis[0], 'bob') + ); console.log("Client 1 resolved Bob's OOBI"); - op2 = await client2.oobis().resolve(oobi1.oobis[0], 'alice'); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation( + client2, + await client2.oobis().resolve(oobi1.oobis[0], 'alice') + ); console.log("Client 2 resolved Alice's OOBI"); // List Client 1 contacts let contacts1 = await client1.contacts().list(); - assert.equal(contacts1[3].alias, 'bob'); + expect(contacts1[0].alias).toEqual('bob'); + expect(contacts1[0].challenges).toHaveLength(0); // Bob responds to Alice challenge await client2.challenges().respond('bob', aid1.i, challenge1_small.words); console.log('Bob responded to Alice challenge with signed words'); // Alice verifies Bob's response - op1 = await client1 - .challenges() - .verify('alice', aid2.i, challenge1_small.words); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + const verifyOperation = await waitOperation( + client1, + await client1 + .challenges() + .verify('alice', aid2.i, challenge1_small.words) + ); console.log('Alice verified challenge response'); //Alice mark response as accepted - const exn = new Serder(op1.response.exn); - op1 = await client1.challenges().responded('alice', aid2.i, exn.ked.d); + const verifyResponse = verifyOperation.response as { + exn: Record; + }; + const exn = new Serder(verifyResponse.exn); + + await client1.challenges().responded('alice', aid2.i, exn.ked.d); console.log('Alice marked challenge response as accepted'); // Check Bob's challenge in conctats contacts1 = await client1.contacts().list(); - console.log('Challenge authenticated'); -} + expect(contacts1[0].challenges[0].authenticated).toEqual(true); +}, 30000); diff --git a/examples/integration-scripts/delegation.ts b/examples/integration-scripts/delegation.test.ts similarity index 77% rename from examples/integration-scripts/delegation.ts rename to examples/integration-scripts/delegation.test.ts index 797f43f5..f626f3fa 100644 --- a/examples/integration-scripts/delegation.ts +++ b/examples/integration-scripts/delegation.test.ts @@ -1,12 +1,11 @@ import { strict as assert } from 'assert'; import signify from 'signify-ts'; +import { resolveEnvironment } from './utils/resolve-env'; +import { resolveOobi, waitOperation } from './utils/test-util'; -const url = 'http://127.0.0.1:3901'; -const boot_url = 'http://127.0.0.1:3903'; +const { url, bootUrl } = resolveEnvironment(); -await run(); - -async function run() { +test('delegation', async () => { await signify.ready(); // Boot two clients const bran1 = signify.randomPasscode(); @@ -15,13 +14,13 @@ async function run() { url, bran1, signify.Tier.low, - boot_url + bootUrl ); const client2 = new signify.SignifyClient( url, bran2, signify.Tier.low, - boot_url + bootUrl ); await client1.boot(); await client2.boot(); @@ -52,10 +51,7 @@ async function run() { ], }); let op1 = await icpResult1.op(); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation(client1, op1); const aid1 = await client1.identifiers().get('delegator'); await client1 .identifiers() @@ -65,18 +61,14 @@ async function run() { // Client 2 resolves delegator OOBI console.log('Client 2 resolving delegator OOBI'); const oobi1 = await client1.oobis().get('delegator', 'agent'); - let op2 = await client2.oobis().resolve(oobi1.oobis[0], 'delegator'); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await resolveOobi(client2, oobi1.oobis[0], 'delegator'); console.log('OOBI resolved'); // Client 2 creates delegate AID const icpResult2 = await client2 .identifiers() .create('delegate', { delpre: aid1.prefix }); - op2 = await icpResult2.op(); + let op2 = await icpResult2.op(); const delegatePrefix = op2.name.split('.')[1]; console.log("Delegate's prefix:", delegatePrefix); console.log('Delegate waiting for approval...'); @@ -91,11 +83,8 @@ async function run() { console.log('Delegator approved delegation'); // Client 2 check approval - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation(client2, op2); const aid2 = await client2.identifiers().get('delegate'); assert.equal(aid2.prefix, delegatePrefix); console.log('Delegation approved for aid:', aid2.prefix); -} +}, 60000); diff --git a/examples/integration-scripts/request-present.ts b/examples/integration-scripts/request-present.test.ts similarity index 56% rename from examples/integration-scripts/request-present.ts rename to examples/integration-scripts/request-present.test.ts index da00f5b2..47a66b72 100644 --- a/examples/integration-scripts/request-present.ts +++ b/examples/integration-scripts/request-present.test.ts @@ -1,12 +1,15 @@ import { strict as assert } from 'assert'; import signify from 'signify-ts'; +import { resolveOobi, waitOperation } from './utils/test-util'; +import { resolveEnvironment } from './utils/resolve-env'; -const url = 'http://127.0.0.1:3901'; -const boot_url = 'http://127.0.0.1:3903'; +const { url, bootUrl, vleiServerUrl } = resolveEnvironment(); -await run(); +const schemaSAID = 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'; +const schemaOobi = `${vleiServerUrl}/oobi/${schemaSAID}`; -async function run() { +// TODO: Marked as skipped because request/present changes +test.skip('request-present', async () => { await signify.ready(); // Boot three clients const bran1 = signify.randomPasscode(); @@ -16,29 +19,35 @@ async function run() { url, bran1, signify.Tier.low, - boot_url + bootUrl ); const client2 = new signify.SignifyClient( url, bran2, signify.Tier.low, - boot_url + bootUrl ); const client3 = new signify.SignifyClient( url, bran3, signify.Tier.low, - boot_url + bootUrl ); - await client1.boot(); - await client2.boot(); - await client3.boot(); - await client1.connect(); - await client2.connect(); - await client3.connect(); - const state1 = await client1.state(); - const state2 = await client2.state(); - const state3 = await client3.state(); + + const [state1, state2, state3] = await Promise.all([ + client1 + .boot() + .then(() => client1.connect()) + .then(() => client1.state()), + client2 + .boot() + .then(() => client2.connect()) + .then(() => client2.state()), + client3 + .boot() + .then(() => client3.connect()) + .then(() => client3.state()), + ]); console.log( 'Client 1 connected. Client AID:', state1.controller.state.i, @@ -59,7 +68,7 @@ async function run() { ); // Create two identifiers, one for each client - let op1 = await client1.identifiers().create('issuer', { + const op1 = await client1.identifiers().create('issuer', { toad: 3, wits: [ 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', @@ -67,17 +76,14 @@ async function run() { 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', ], }); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation(client1, await op1.op()); const aid1 = await client1.identifiers().get('issuer'); await client1 .identifiers() .addEndRole('issuer', 'agent', client1!.agent!.pre); console.log("Issuer's AID:", aid1.prefix); - let op2 = await client2.identifiers().create('recipient', { + const op2 = await client2.identifiers().create('recipient', { toad: 3, wits: [ 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', @@ -85,17 +91,14 @@ async function run() { 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', ], }); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation(client2, await op2.op()); const aid2 = await client2.identifiers().get('recipient'); await client2 .identifiers() .addEndRole('recipient', 'agent', client2!.agent!.pre); console.log("Recipient's AID:", aid2.prefix); - let op3 = await client3.identifiers().create('verifier', { + const op3 = await client3.identifiers().create('verifier', { toad: 3, wits: [ 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha', @@ -103,82 +106,49 @@ async function run() { 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX', ], }); - while (!op3['done']) { - op3 = await client3.operations().get(op3.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await waitOperation(client3, await op3.op()); + const aid3 = await client3.identifiers().get('verifier'); await client3 .identifiers() .addEndRole('verifier', 'agent', client3!.agent!.pre); console.log("Verifier's AID:", aid3.prefix); - const schemaSAID = 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'; - // Exchenge OOBIs console.log('Resolving OOBIs...'); - const oobi1 = await client1.oobis().get('issuer', 'agent'); - const oobi2 = await client2.oobis().get('recipient', 'agent'); - const oobi3 = await client3.oobis().get('verifier', 'agent'); - const schemaOobi = 'http://127.0.0.1:7723/oobi/' + schemaSAID; + const [oobi1, oobi2, oobi3] = await Promise.all([ + client1.oobis().get('issuer', 'agent'), + client2.oobis().get('recipient', 'agent'), + client3.oobis().get('verifier', 'agent'), + ]); + + await Promise.all([ + resolveOobi(client1, oobi2.oobis[0], 'recipient'), + resolveOobi(client1, oobi3.oobis[0], 'verifier'), + resolveOobi(client1, schemaOobi, 'schema'), + ]); - op1 = await client1.oobis().resolve(oobi2.oobis[0], 'recipient'); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op1 = await client1.oobis().resolve(oobi3.oobis[0], 'verifier'); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op1 = await client1.oobis().resolve(schemaOobi, 'schema'); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } console.log('Issuer resolved 3 OOBIs'); - op2 = await client2.oobis().resolve(oobi1.oobis[0], 'issuer'); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op2 = await client2.oobis().resolve(oobi3.oobis[0], 'verifier'); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op2 = await client2.oobis().resolve(schemaOobi, 'schema'); - while (!op2['done']) { - op2 = await client2.operations().get(op2.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await Promise.all([ + resolveOobi(client2, oobi1.oobis[0], 'issuer'), + resolveOobi(client2, oobi3.oobis[0], 'verifier'), + resolveOobi(client2, schemaOobi, 'schema'), + ]); console.log('Recipient resolved 3 OOBIs'); - op3 = await client3.oobis().resolve(oobi1.oobis[0], 'issuer'); - while (!op3['done']) { - op3 = await client3.operations().get(op3.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op3 = await client3.oobis().resolve(oobi2.oobis[0], 'recipient'); - while (!op3['done']) { - op3 = await client3.operations().get(op3.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - op3 = await client3.oobis().resolve(schemaOobi, 'schema'); - while (!op3['done']) { - op3 = await client3.operations().get(op3.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + await Promise.all([ + resolveOobi(client3, oobi1.oobis[0], 'issuer'), + resolveOobi(client3, oobi2.oobis[0], 'recipient'), + resolveOobi(client3, schemaOobi, 'schema'), + ]); console.log('Verifier resolved 3 OOBIs'); // Create registry for issuer - op1 = await client1.registries().create('issuer', 'vLEI'); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } + const vcpResult = await client1 + .registries() + .create({ name: 'issuer', registryName: 'vLEI' }); + await waitOperation(client1, await vcpResult.op()); const registries = await client1.registries().list('issuer'); assert.equal(registries.length, 1); assert.equal(registries[0].name, 'vLEI'); @@ -193,14 +163,16 @@ async function run() { const vcdata = { LEI: '5493001KJTIIGC8Y1R17', }; - op1 = await client1 - .credentials() - .issue('issuer', registries[0].regk, schemaSAID, aid2.prefix, vcdata); - while (!op1['done']) { - op1 = await client1.operations().get(op1.name); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - const creds1 = await client1.credentials().list('issuer'); + const credRes = await client1.credentials().issue({ + issuerName: 'issuer', + registryId: registries[0].regk, + schemaId: schemaSAID, + recipient: aid2.prefix, + data: vcdata, + }); + await waitOperation(client1, credRes.op); + + const creds1 = await client1.credentials().list(); assert.equal(creds1.length, 1); assert.equal(creds1[0].sad.s, schemaSAID); assert.equal(creds1[0].sad.i, aid1.prefix); @@ -208,7 +180,7 @@ async function run() { console.log('Credential issued'); // Recipient check issued credential - const creds2 = await client2.credentials().list('recipient'); + const creds2 = await client2.credentials().list(); assert.equal(creds2.length, 1); assert.equal(creds2[0].sad.s, schemaSAID); assert.equal(creds2[0].sad.i, aid1.prefix); @@ -253,11 +225,10 @@ async function run() { const creds3 = await client3 .credentials() - .list('verifier', { filter: { '-i': { $eq: aid1.prefix } } }); // filter by issuer + .list({ filter: { '-i': { $eq: aid1.prefix } } }); // filter by issuer assert.equal(creds3.length, 1); assert.equal(creds3[0].sad.s, schemaSAID); assert.equal(creds3[0].sad.i, aid1.prefix); assert.equal(creds3[0].status.s, '0'); // 0 = issued assert.equal(creds3[0].sad.a.i, aid2.prefix); // verify that the issuee is the same as the presenter - console.log('Credential presented and received by verifier'); -} +}, 60000); diff --git a/examples/integration-scripts/run_all.sh b/examples/integration-scripts/run_all.sh deleted file mode 100755 index e5ae3162..00000000 --- a/examples/integration-scripts/run_all.sh +++ /dev/null @@ -1 +0,0 @@ -for f in ./*.ts; do ts-node --esm $f; done \ No newline at end of file diff --git a/examples/integration-scripts/utils/test-util.ts b/examples/integration-scripts/utils/test-util.ts index bfd2d821..28d78328 100644 --- a/examples/integration-scripts/utils/test-util.ts +++ b/examples/integration-scripts/utils/test-util.ts @@ -1,4 +1,4 @@ -import { SignifyClient } from 'signify-ts'; +import { Operation, SignifyClient } from 'signify-ts'; export function sleep(ms: number): Promise { return new Promise((resolve) => { @@ -9,13 +9,12 @@ export function sleep(ms: number): Promise { /** * Poll for operation to become completed */ -export async function waitOperation( +export async function waitOperation( client: SignifyClient, - op: any, - retries: number | undefined = undefined -): Promise { + op: Operation, + retries: number = 10 +): Promise> { const WAIT = 500; // 0.5 seconds - retries ??= 10; // default 10 retries or 5 seconds while (retries-- > 0) { op = await client.operations().get(op.name); if (op.done === true) return op; @@ -23,3 +22,12 @@ export async function waitOperation( } throw new Error(`Timeout: operation ${op.name}`); } + +export async function resolveOobi( + client: SignifyClient, + oobi: string, + alias: string +) { + const op = await client.oobis().resolve(oobi, alias); + await waitOperation(client, op); +} diff --git a/src/keri/app/contacting.ts b/src/keri/app/contacting.ts index c4485407..cb3ef2f4 100644 --- a/src/keri/app/contacting.ts +++ b/src/keri/app/contacting.ts @@ -1,4 +1,5 @@ import { SignifyClient } from './clienting'; +import { Operation } from './coring'; /** * Contacts @@ -157,13 +158,13 @@ export class Challenges { * @param {string} name Name or alias of the identifier * @param {string} source Prefix of the identifier that was challenged * @param {Array} words List of challenge words to check for - * @returns {Promise} A promise to the result + * @returns A promise to the long running operation */ async verify( name: string, source: string, words: string[] - ): Promise { + ): Promise> { const path = `/challenges/${name}/verify/${source}`; const method = 'POST'; const data = {