This SDK wraps calls to IBM Verify Credential Account Service APIs in a set of javascript functions.
Save openssi-websdk
as a dependency of your Node.js project:
npm install --save openssi-websdk
- Using Promises
- Getting started
- Connecting with other agents
- Issuing credentials
- Verifying
- More information
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)}`)
});
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_name = 'my_agent';
const agent_password = 'my_password';
const agent = new Agent(account_url, 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)}`)
})();
In order to interact with other agents to issue credentials, request verifications, etc., you must first establish a secure connection with those agents. There are two ways to establish connections, in-band and out-of-band.
If a name or url of another other agent is provided when creating the connection, this agent will attempt to contact the other agent and deliver the connection offer on your behalf.
Create a Connection
for another agent with the state outbound_offer
and wait for it to enter the
connected
state:
const to = {
url: 'https://theiragent:@theiraccount.example.com'
};
const connection_offer = await agent.createConnection(to);
const accepted_connection = await agent.waitForConnection(connection_offer.id);
Get a list of connections with the state inbound_offer
and change their state to connected
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);
}
If another agent's name or url are not specified when creating the connection, this agent will not attempt to deliver the created connection offer.
Create a Connection
without specifying a name or url for another agent:
const connection_offer = await agent.createConnection();
// Deliver the connection_offer to the other agent's user and wait for them to send it to their agent.
const accepted_connection = await agent.waitForConnection(connection_offer.id);
waitForConnection()
is a helper method provided for your convenience. You could just as easily write your own logic for waiting on connections to be accepted. In either case, you should probable delete connections that are not accepted using thedeleteConnection()
method.
Post a given connection offer object to your agent.
const accepted_connection = await agent.acceptConnection(connection_offer);
Once you have a Connection
to another agent, you can offer Credentials
over that connection.
In order to issue credentials, you will need write access to the ledger. This is only possible if your agent is a
TRUST_ANCHOR
.
const agent_info = await agent.getIdentity();
console.log(agent_info.role);
if (role !== 'TRUST_ANCHOR') {
// Your admin will be the first agent that was created on your account
const agent_admin_name = 'my_admin';
const agent_admin_password = 'my_admin_password';
const updated_agent = await agent.onboardAsTrustAnchor(agent_admin_name, agent_admin_password);
}
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);
In order to issue credentials, you need to publish a CredentialDefinition
on the ledger:
const cred_def = await agent.createCredentialDefinition(cred_schema.id);
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);
Find Credential
s 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');
}
Once you have a Connection
to another agent, you can send and receive Verifications
over that connection.
You must publish a ProofSchema
before creating a verification. ProofSchema
s 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);
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);
Get a list of Verification
s 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');
}
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')
}
}
The SDK code has fairly extensive JSDoc comments. Read these to get a better understanding of all the capabilities of this SDK.