Skip to content

Commit

Permalink
Update NodeJS VCX Wrapper demo.
Browse files Browse the repository at this point in the history
- Update readme
- Add logging
- Generate distinct wallets on every demo run
- Prefix wallet names with 'node_vcx_demo_'
- Use winston logger with colorprinting

Signed-off-by: Patrik Stas <[email protected]>
  • Loading branch information
Patrik-Stas committed Mar 14, 2019
1 parent db599d1 commit 869515f
Show file tree
Hide file tree
Showing 6 changed files with 295 additions and 64 deletions.
2 changes: 1 addition & 1 deletion vcx/wrappers/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ npm install

- Compile LibVCX Wrapper
```
npm compile
npm run compile
```
- Start [Dummy Cloud Agent](../../dummy-cloud-agent)
- Run Faber agent, representing an institution
Expand Down
34 changes: 19 additions & 15 deletions vcx/wrappers/node/demo/alice.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import {StateType} from "../dist/src";
import readlineSync from 'readline-sync'
import sleepPromise from 'sleep-promise'
import * as demoCommon from './common'
import logger from './logger'

const utime = Math.floor(new Date() / 1000);

const provisionConfig = {
'agency_url': 'http://localhost:8080',
'agency_did': 'VsKV7grR1BUE29mG2Fm2kX',
'agency_verkey': 'Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR',
'wallet_name': 'alice_wallet',
'wallet_name': `node_vcx_demo_alice_wallet_${utime}`,
'wallet_key': '123',
'payment_method': 'null',
'enterprise_seed': '000000000000000000000000Trustee1'
Expand All @@ -21,50 +24,51 @@ const logLevel = 'warn';
async function run() {
await demoCommon.initLibNullPay();

console.log("#0 initialize rust API from NodeJS");
logger.info("#0 initialize rust API from NodeJS");
await demoCommon.initRustApiAndLogger(logLevel);

console.log("#1 Provision an agent and wallet, get back configuration details");
logger.info("#1 Provision an agent and wallet, get back configuration details");
let config = await demoCommon.provisionAgentInAgency(provisionConfig);

console.log("#2 Initialize libvcx with new configuration");
logger.info("#2 Initialize libvcx with new configuration");
await demoCommon.initVcxWithProvisionedAgentConfig(config);

console.log("#9 Input faber.py invitation details");
logger.info("#9 Input faber.py invitation details");
const details = readlineSync.question('Enter your invite details: ');
const jdetails = JSON.parse(details);

console.log("#10 Convert to valid json and string and create a connection to faber");
logger.info("#10 Convert to valid json and string and create a connection to faber");
const connection_to_faber = await Connection.createWithInvite({id: 'faber', invite: JSON.stringify(jdetails)});
await connection_to_faber.connect({data: '{"use_public_did": true}'});
await connection_to_faber.updateState();

console.log("#11 Wait for faber.py to issue a credential offer");
logger.info("#11 Wait for faber.py to issue a credential offer");
await sleepPromise(5000);
const offers = await Credential.getOffers(connection_to_faber);
console.log(`Alice found following credentiaal offers: ${JSON.stringify(offers)}`);
logger.info(`Alice found ${offers.length} credential offers.`);
logger.debug(JSON.stringify(offers));

// Create a credential object from the credential offer
const credential = await Credential.create({sourceId: 'credential', offer: JSON.stringify(offers[0])});

console.log("#15 After receiving credential offer, send credential request");
logger.info("#15 After receiving credential offer, send credential request");
await credential.sendRequest({connection: connection_to_faber, payment : 0});

console.log("#16 Poll agency and accept credential offer from faber");
logger.info("#16 Poll agency and accept credential offer from faber");
let credential_state = await credential.getState();
while (credential_state !== StateType.Accepted) {
sleepPromise(2000);
await credential.updateState();
credential_state = await credential.getState();
}

console.log("#22 Poll agency for a proof request");
logger.info("#22 Poll agency for a proof request");
const requests = await DisclosedProof.getRequests(connection_to_faber);

console.log("#23 Create a Disclosed proof object from proof request");
logger.info("#23 Create a Disclosed proof object from proof request");
const proof = await DisclosedProof.create({sourceId: 'proof', request: JSON.stringify(requests[0])});

console.log("#24 Query for credentials in the wallet that satisfy the proof request");
logger.info("#24 Query for credentials in the wallet that satisfy the proof request");
const credentials = await proof.getCredentials();

// Use the first available credentials to satisfy the proof request
Expand All @@ -75,10 +79,10 @@ async function run() {
}
}

console.log("#25 Generate the proof");
logger.info("#25 Generate the proof");
await proof.generateProof({selectedCreds: credentials, selfAttestedAttrs: {}});

console.log("#26 Send the proof to faber");
logger.info("#26 Send the proof to faber");
await proof.sendProof(connection_to_faber);
}

Expand Down
66 changes: 35 additions & 31 deletions vcx/wrappers/node/demo/faber.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import {StateType, ProofState} from "../dist/src";
import sleepPromise from 'sleep-promise'
import * as demoCommon from "./common";
import {getRandomInt} from "./common";
import logger from './logger'

const utime = Math.floor(new Date() / 1000);

const provisionConfig = {
'agency_url': 'http://localhost:8080',
'agency_did': 'VsKV7grR1BUE29mG2Fm2kX',
'agency_verkey': 'Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR',
'wallet_name': 'faber_wallet',
'wallet_name': `node_vcx_demo_faber_wallet_${utime}`,
'wallet_key': '123',
'payment_method': 'null',
'enterprise_seed': '000000000000000000000000Trustee1'
Expand All @@ -24,16 +26,18 @@ const logLevel = 'error';
async function run() {
await demoCommon.initLibNullPay();

console.log("#0 initialize rust API from NodeJS");
logger.info("#0 initialize rust API from NodeJS");
await demoCommon.initRustApiAndLogger(logLevel);

console.log("#1 Provision an agent and wallet, get back configuration details");
logger.info("#1 Provision an agent and wallet, get back configuration details");
logger.debug(`Config used to provision agent in agency: ${JSON.stringify(provisionConfig, null, 2)}`);
let config = await demoCommon.provisionAgentInAgency(provisionConfig);

console.log("#2 Initialize libvcx with new configuration");
logger.info("#2 Initialize libvcx with new configuration");
logger.debug(`${JSON.stringify(config, null, 2)}`);
await demoCommon.initVcxWithProvisionedAgentConfig(config);

console.log("#3 Create a new schema on the ledger");
logger.info("#3 Create a new schema on the ledger");
const version = `${getRandomInt(1, 101)}.${getRandomInt(1, 101)}.${getRandomInt(1, 101)}`;
const schemaData = {
data: {
Expand All @@ -47,9 +51,9 @@ async function run() {

const schema = await Schema.create(schemaData);
const schemaId = await schema.getSchemaId();
console.log(`Created schema with id ${schemaId}`);
logger.info(`Created schema with id ${schemaId}`);

console.log("#4 Create a new credential definition on the ledger");
logger.info("#4 Create a new credential definition on the ledger");
const data = {
name: 'DemoCredential123',
paymentHandle: 0,
Expand All @@ -63,37 +67,37 @@ async function run() {
const cred_def = await CredentialDef.create(data);
const cred_def_id = await cred_def.getCredDefId();
const credDefHandle = cred_def.handle;
console.log(`Created credential with id ${cred_def_id} and handle ${credDefHandle}`);
logger.info(`Created credential with id ${cred_def_id} and handle ${credDefHandle}`);

console.log("#5 Create a connection to alice and print out the invite details");
logger.info("#5 Create a connection to alice and print out the invite details");
const connectionToAlice = await Connection.create({id: 'alice'});
await connectionToAlice.connect('{"use_public_did": true}');
await connectionToAlice.updateState();
const details = await connectionToAlice.inviteDetails(false);
console.log("\n\n**invite details**");
console.log("**You'll ge queried to paste this data to alice side of the demo. This is invitation to connect.**");
console.log("**It's assumed this is obtained by Alice from Faber by some existing secure channel.**");
console.log("**Could be on website via HTTPS, QR code scanned at Faber institution, ...**");
console.log("\n******************\n\n");
console.log(JSON.stringify(JSON.parse(details)));
console.log("\n\n******************\n\n");

console.log("#6 Polling agency and waiting for alice to accept the invitation. (start alice.py now)");
logger.info("\n\n**invite details**");
logger.info("**You'll ge queried to paste this data to alice side of the demo. This is invitation to connect.**");
logger.info("**It's assumed this is obtained by Alice from Faber by some existing secure channel.**");
logger.info("**Could be on website via HTTPS, QR code scanned at Faber institution, ...**");
logger.info("\n******************\n\n");
logger.info(JSON.stringify(JSON.parse(details)));
logger.info("\n\n******************\n\n");

logger.info("#6 Polling agency and waiting for alice to accept the invitation. (start alice.py now)");
let connection_state = await connectionToAlice.getState();
while (connection_state !== StateType.Accepted) {
await sleepPromise(2000);
await connectionToAlice.updateState();
connection_state = await connectionToAlice.getState();
}
console.log(`Connection to alice was Accepted!`);
logger.info(`Connection to alice was Accepted!`);

const schema_attrs = {
'name': 'alice',
'date': '05-2018',
'degree': 'maths',
};

console.log("#12 Create an IssuerCredential object using the schema and credential definition")
logger.info("#12 Create an IssuerCredential object using the schema and credential definition")

const credentialForAlice = await IssuerCredential.create({
attr: schema_attrs,
Expand All @@ -103,23 +107,23 @@ async function run() {
price: '0'
});

console.log("#13 Issue credential offer to alice");
logger.info("#13 Issue credential offer to alice");
await credentialForAlice.sendOffer(connectionToAlice);
await credentialForAlice.updateState();

console.log("#14 Poll agency and wait for alice to send a credential request");
logger.info("#14 Poll agency and wait for alice to send a credential request");
let credential_state = await credentialForAlice.getState();
while (credential_state !== StateType.RequestReceived) {
await sleepPromise(2000);
await credentialForAlice.updateState();
credential_state = await credentialForAlice.getState();
}

console.log("#17 Issue credential to alice");
logger.info("#17 Issue credential to alice");
await credentialForAlice.sendCredential(connectionToAlice);


console.log("#18 Wait for alice to accept credential");
logger.info("#18 Wait for alice to accept credential");
await credentialForAlice.updateState();
credential_state = await credentialForAlice.getState();
while (credential_state !== StateType.Accepted) {
Expand All @@ -134,33 +138,33 @@ async function run() {
{'name': 'degree', 'restrictions': [{'issuer_did': config['institution_did']}]}
];

console.log("#19 Create a Proof object");
logger.info("#19 Create a Proof object");
const proof = await Proof.create({
sourceId: "213",
attrs: proofAttributes,
name: 'proofForAlice',
revocationInterval: {}
});

console.log("#20 Request proof of degree from alice");
logger.info("#20 Request proof of degree from alice");
await proof.requestProof(connectionToAlice);

console.log("#21 Poll agency and wait for alice to provide proof");
logger.info("#21 Poll agency and wait for alice to provide proof");
let proofState = await proof.getState();
while (proofState !== StateType.Accepted) {
sleepPromise(2000);
await proof.updateState();
proofState = await proof.getState();
}

console.log("#27 Process the proof provided by alice");
logger.info("#27 Process the proof provided by alice");
await proof.getProof(connectionToAlice);

console.log("#28 Check if proof is valid");
logger.info("#28 Check if proof is valid");
if (proof.proofState === ProofState.Verified) {
console.log("proof is verified!!")
logger.info("proof is verified!!")
} else {
console.log("could not verify proof :(")
logger.info("could not verify proof :(")
}
}

Expand Down
22 changes: 22 additions & 0 deletions vcx/wrappers/node/demo/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { createLogger, format, transports } = require('winston');
const { label } = format;

const prettyFormatter = format.combine(
format.printf(
info => `${info.label} [${info.level}]: ${info.message}`
)
);

const logger = createLogger({
level: 'debug',
format: format.combine(
label({ label: 'Demo Faber:' }),
format.colorize({all: true}),
prettyFormatter
),
transports: [
new transports.Console(),
]
});

export default logger;
Loading

0 comments on commit 869515f

Please sign in to comment.