npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

openssi-websdk

v1.0.4-alpha

Published

A SDK for issuing and verifying digital credentials through a cloud agent

Downloads

341

Readme

npm version

openssi-websdk

This SDK wraps calls to IBM Verify Credential Account Service APIs in a set of javascript functions.

Installation

Save openssi-websdk as a dependency of your Node.js project:

npm install --save openssi-websdk

Table of Contents

Using Promises

Functions that involve calls to the cloud agent are async functions, meaning that they return Promises You can call these functions from an async context as follows:

const agent_info = await agent.getIdentity();
console.log(`Agent Info: ${JSON.stringify(agent_info, 0, 1)}`)

or from a nonasync context:

agent.getIdentity().then((agent_info) => {
    console.log(`Agent Info: ${JSON.stringify(agent_info, 0, 1)}`)
});

Getting started

Create an instance of Agent and connect to your cloud agent:

const Agent = require('openssi-websdk').Agent;

const account_url = 'https://myaccount.example.com';
const agent_id = '01234567890'
const agent_name = 'my_agent';
const agent_password = 'my_password';

const agent = new Agent(account_url, agent_id, agent_name, agent_password);

(async () => {
	// Check the username and password by hitting the API
    const agentInfo = await agent.getIdentity();
    console.log(`Agent info: ${JSON.stringify(agentInfo, 0, 1)}`)
})();

Connecting with other agents

In order to interact with other agents to issue credentials, request verifications, exchange messages, etc., you must first establish a secure connection with those agents. Connections can be established with invitations.

Creating an invitation

Building a connection begins with an invitation. An agent must create an invitation and provide it to another agent with whom it would like to connect.

const direct_= true; // messages will be sent directly to the inviter
const manual_accept = false; // the inviter's agent will automatically accept any cunnetcion offer from this invitation
const max_acceptances = -1; // set no limit on how many times this invitaton may be accepted 
const properties = null; // properties to set on the inviter's side of the connection

const invitation = await agent.createInvitation(direct_route, manual_accept, max_acceptances, properties);

Communicating an invitation

Invitation urls must be communicated to other parties out-of-band (outside of the agency). For example, they may be provided to other parties in a registration form, publicly on a web page, or embedded in a QR code displayed by a web app or printed on a piece of paper.

Accepting an invitation

You can accept an invitation provided to you. This will generate a connection object that will have the state "connected" once the connection offer is accepted by the inviter.

const url = invitation_url; // Invitation url to accept
const connection = await agent.acceptInvitation(invitation_url);

Accepting the connection offer

As an inviter, at the time of invitation creation, you can specify whether you want your agent to automatically accept any connection offer associated with this invitation or you can choose to manually accept each invitation. For example, you may choose to allow connections based on some kind of business logic.

const opts = {
	state: 'inbound_offer'
};
const inbound_offers = await agent.getConnections(opts);

for (const index in inbound_offers) {
	const accepted_connection = await agent.acceptConnection(inbound_offers[index].id);
}

Issuing credentials

Once you have a Connection to another agent, you can offer Credentials over that connection.

Checking your agent's role

In order to issue credentials, you will need write access to the ledger. This is only possible if your agent is an ENDORSER.

const agent_info = await agent.getIdentity();

console.log(agent_info.issuer);

if (agent_info.issuer !== true) {
	const updated_agent = await agent.onboardAsTrustAnchor();
}

Publishing a credential schema

In order to issue credentials, you need to publish a CredentialSchema on the ledger:

const name = "My Schema";
const version = "0.0.1";
const attributes = [
	'first_name',
	'last_name'
];

const cred_schema = await agent.createCredentialSchema(name, version, attributes);

Publishing a credential definition

In order to issue credentials, you need to publish a CredentialDefinition on the ledger:

const cred_def = await agent.createCredentialDefinition(cred_schema.id);

Offering credentials

Create a Credential marked for the other agent with the state 'outbound_offer' and wait for it to enter the issued state:

const to = {
	did: accepted_connection.remote.pairwise.did
};

const attributes = {
	'first_name': 'John',
	'last_name': 'Doe'
};

const credential_offer = await agent.offerCredential(to, cred_def.id, attributes);
const issued_credential = await agent.waitForCredential(credential_offer.id);

Accepting offered credentials

Find Credentials with the state inbound_offer and change their state to accepted:

const opts = {
	state: 'inbound_offer'
};

const credential_offers = await agent.getCredentials(opts);
for (const index in credential_offers) {
	const accepted_credential = await agent.updateCredential(credential_offers[index].id, 'accepted');
}

Verifying

Once you have a Connection to another agent, you can send and receive Verifications over that connection.

Publishing a proof schema

You must publish a ProofSchema before creating a verification. ProofSchemas describe the information that can be requested in a Verification.

const name = 'first_and_last_name';
const version = '0.0.1';
const requested_attributes = {
	first_name_referent: {
		name: 'first_name'
	},
	last_name_referent: {
		name: 'last_name',
		restrictions: [
			{
				cred_def_id: cred_def.id
			}
		]
	}
};

const proof_schema = await agent.createProofSchema(name, version, requested_attributes);

Retrieving credential schemas, credential definitions from issuers

Proof schemas with more stringent requirements oftern require credential schema id's or credential definition id's that are only known by the issuers that originally published them. For scenarios where the verifier is not also the issuer of the required credentials, it is possible to query credential definitions and schemas from all other issuers in the agency or even filter it down to a specific issuer if you know their public DID.

const all = true; // look for credential definitions published by agents other than the current agent
const opts = {
	owner_did: '01234567890'
};

const dmv_cred_defs = await this.agent.getCredentialDefinitions(all, opts);

Requesting verification

Create a Verification with the state outbound_proof_request to send a proof request to a given agent based on a published proof schema:

const to = {
	did: accepted_connection.remote.pairwise.did
};

const proof_request = await agent.createVerification(to, proof_schema.id, 'outbound_proof_request');
const finished_verification = await agent.waitForVerification(proof_request.id);

Responding to proof requests

Get a list of Verifications with the state inbound_proof_request and change their state to proof_generated and then proof_shared:

const opts = {
	state: 'inbound_proof_request'
};

const inbound_proof_requests = await agent.getVerifications(opts);

for (const index in inbound_proof_requests) {
	const verification = inbound_proof_requests[index];
	await agent.updateVerification(verification.id, 'proof_generated');
	await agent.updateVerification(verification.id, 'proof_shared');
}

Checking the values in a proof

Check the revealed attributes in a Verification that has reached the passed state.

for (const index in finished_verification.info.attributes) {
    const attr = finished_verification.info.attributes[index];
    
    console.log(`${attr.cred_def_id ? '*' : ' '}${attr.name} = ${attr.value}`);
    
    if (attr.name === 'first_name') {
    	assert(attr.value === 'John');
    } else if (attr.name === 'last_name') {
    	assert(attr.cred_def_id && attr.value === 'Doe')
    }
}

More information

The SDK code has fairly extensive JSDoc comments. Read these to get a better understanding of all the capabilities of this SDK.