Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@trackback/agent

trackback-blockchain45GPL-3.0-or-later0.0.1-alpha.48TypeScript support: included

TrackBack agent SDK

DID, DID document, Verifiable Credential, W3C, Substrate, Polkadot, Web3, TrackBack, Blockchain, Self Sovereign Identity

readme

ExpTrackback Logo

TrackBack Agent SDK TrackBack Agent SDK Build Node Version Lerna

TrackBack Agent SDK

  • Create, Revoke, Resolve, Update DIDs
  • Connects with TrackBack chain
  • Store DID documents in a Decentralised file store ( IPFS for MVP stage)
  • This is a part of SDKs for Verifiable Credentials, Verifiable Credential Presentations, DID Keys, Self Sovereign Identity and Decentralised Identifiers

IMPORTANT!

  • This is a minimum viable product suite with limited functionality.
  • Do not use this for productionise code or for an end product
  • Please view Limitations

Architecture

TrackBack Agent

Architecture

Limitations

The following features are not available in this minimum viable SDK

  • Zero Knowledge Proofs
  • Batch insert / update of DIDs
  • DID revocation - the DID document will be available on IPFS without DID meta information
  • Support for JSON-LD
  • Single Sign On (using Self Sovereign Identity)
  • Saving a cryptographical print of a verifiable credential on chain
  • Multiple authentication
  • DID delegation is incomplete , only the nominated parties can modify a DID document
  • DID delegation functionality over a verifiable credential will be delivered after MVP stage

Miscellaneous

  • You may see warning messages when creating DIDs
  • Only works with already created accounts on chain

Issue and Verify credentials

Requirements

  • Install nodejs 14.0.0 or above.
  • Install follwoing dependencies.

    sudo npm i -g ts-node
    npm install -g typescript
    nvm use 14
    npm install @trackback/agent

    Constructing SSI Elements

    <summary>Create an Issuer</summary>

    `javascript import {CredentialIssuer,Connector, createAccount, TrackBackAgent} from '@trackback/agent';

async function createAnIssuer() { // Create a Connector object. const connector = new Connector();

// Initialise the `TrackBackAgent` with a connector instance.
const agent = new TrackBackAgent(connector);

// An Issuer needs an active account on TrackBack Blockchain
// Please use the default account for this MVP release
// Functionality will be added to create ad use your own objects in future releases.
const account = await connector.getDefaultAccount();

// A valid context is required to persist an object to the chain 
const context = {
    agent,
    account: account
}

// Creates an issuer
const issuer = await CredentialIssuer.build();

// Saves a DID Document
await issuer.save(context, {"didDocumentMetadata": "docMeta"}, {"didResolutionMetadata": "resolutionMeta"});

let resolevedDIDDocument = await agent.procedure.resolve(issuer.toDidDocument().id);
/**  resolevedDIDDocument
 * {
        did_resolution_metadata: { hello: 'resolutionMeta' },
        did_document_metadata: { hello: 'docMeta' },
        block_number: 218812,
        block_time_stamp: 1635477636,
        updated_timestamp: 1635477636,
        did_ref: 'https://ipfs.trackback.dev:8080/ipfs/QmdH3JyxJ1A45goKAt18ja3TX67ea4Vz2NTyLkLXEQYTk8',
        sender_account_id: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
        public_keys: [ '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY' ],
        did_document: {
            '@context': [ 'https://www.w3.org/ns/did/v1' ],
            id: 'did:trackback:e97aaebd-c221-44d6-925f-f73493eec3dd',
            verificationMethod: [ [Object] ]
        }
        }
        {
        header: {
            alg: 'EdDSA',
            typ: 'JWT',
            kid: 'did:trackback:key:JsonWebKey2020:ZpM9EIlXv2Yj9F1IaIS-S1-BkSrXIq8ad2rpAffDDlg#ZpM9EIlXv2Yj9F1IaIS-S1-BkSrXIq8ad2rpAffDDlg'
        },
        payload: {
            nbf: 1635477651,
            iss: 'did:trackback:e97aaebd-c221-44d6-925f-f73493eec3dd',
            vp: {
            '@context': [Array],
            type: [Array],
            verifiableCredential: [Array]
            }
        },
        signature: 'PdPWI_J88vokw68_APAFh3BU7Go6grabOGj3SAtFbfOwpJCz0yyAh7xR7rdZIw7lhCHwPfB6-25QFYsUEehACw'
        }
 * */

}

</details>

<details>
  <summary>Create a <b>Verifiable Credential</b> and a <b>Verifiable Credential Presentation</b></summary>

  ```javascript
import {CredentialIssuer,Connector, createAccount, TrackBackAgent} from '@trackback/agent';

async function verifiableCredential(credentialData: any) {


    const connector = new Connector();
    const agent = new TrackBackAgent(connector);

    const account = await connector.getDefaultAccount();

    const context = {
        agent,
        account: account
        }
    const issuer = await CredentialIssuer.build();
    await issuer.save(context, {"hello": "docMeta"}, {"hello": "resolutionMeta"});

    /*
    Ppopulate Credential subject with data
    Reference :- https://www.w3.org/TR/vc-data-model/#example-1-a-simple-example-of-a-verifiable-credential
    "credentialSubject": {

        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",

        "alumniOf": {
        "id": "did:example:c276e12ec21ebfeb1f712ebc6f1",
        "name": [{
            "value": "Example University",
            "lang": "en"
        }, {
            "value": "Exemple d'Université",
            "lang": "fr"
        }]
        }
    },

    */
    const credential = {
        '@context': ['https://www.w3.org/2018/credentials/v1'],
        type: ['VerifiableCredential'],
        issuanceDate: '2010-01-01T19:23:24Z',
        credentialSubject: credentialData, // default {}
        issuer: issuer.id,
    };

    // Creates a JWT
    const jwt = await issuer.createVerifiableCredentials(credential);

    // Creates a JWT presentation
    const jwtPresentation = await issuer.createVerifiablePresentation([jwt], issuer.keypair);

    let decode = CredentialVerifier.decodeJWT(jwtPresentation);

    // Prints decoded JWT presentation
    console.log(decode);
}
<summary>Verification Process</summary>
/*
IssuerA Creates a Credential
*/
async function createCredentials() {

    // Creates a connector object
    const connector = new Connector();
    // Creates the TrackBack Agent
    const agent = new TrackBackAgent(connector);

    // Creates the defualt account for the issuer
    // `Alice` if there's no mnemonic
    // The passing mnemonic must be a valid account on TrackBack
    // For the MVP please use either Alice or Bob since we are finalising our token
    // economic and account model
    const account = await connector.getDefaultAccount();

    // Creates the issuer's context
    const context = {
        agent,
        account: account
    }

    // Create Issuer's keypair
    const IsserA = await CredentialIssuer.build();
    // Saves the Issuer's DID
    // This needs to be done only once per issuer
    // Do not create new issuers per credentials
    await IsserA.save(context, {"hello": "docMeta"}, {"hello": "resolutionMeta"});

    // Issuer creates a credential
    // Pass teh required data as JSON to `credentialSubject: {},`
    const credential = {
        '@context': ['https://www.w3.org/2018/credentials/v1'],
        type: ['VerifiableCredential'],
        issuanceDate: '2010-01-01T19:23:24Z',
        credentialSubject: {},
        issuer: IsserA.id,
    };
    const jwt = await IsserA.createVerifiableCredentials(credential);

    // Issuer creates a verifiable credential presentation 
    const jwtPresentation = await IsserA.createVerifiablePresentation([jwt], IsserA.keypair);

    // The above jwtPresentation can reside on a wallet / website or in a database

A verifier verifies the JWT

  async function verify(jwtPresentation) {
    // Creates a connector object
    const connector = new Connector();
    // Creates the TrackBack Agent
    const agent = new TrackBackAgent(connector);
     // Create a verifier
    let verifier = new CredentialVerifier();

    // For the MVP please use an Account available on TrackBack Chain.
    const accountB = await connector.getDefaultAccount("Bob");
    const verifierContext = {
        agent,
        account: accountB
    }

    const r = await verifier.verifyPresentation(jwtPresentation, verifierContext);
    console.log(r); // True | False
}

Usage

Installation

npm install @trackback/agent

## or yarn 
yarn add @trackback/agent

Importing

ES Modules import


import { TrackBackAgent } from '@trackback/agent'

CommonJS import


const { TrackBackAgent } = require('@trackback/agent');

DID Operations

Create a DID

  • The DID Document must be saved on IPFS `javascript /*
  • saveToDistributedStorage returns thecid`
  • Please Include this value as the didRef when calling the constructDIDDocument and updateDIDDocument methods. / agent = new TrackBackAgent(new Connection()); let result = await agent.procedure.saveToDistributedStorage(desDIDStructure, null); javascript /
  • Returns Promise<ExtrinsicResults>
  • ExtrinsicResults export type ExtrinsicResults = {

} | null; */ let agent = new TrackBackAgent(new Connector()); await agent.procedure.constructDIDDocument( account, didDocument, didDocumentMetadata, didResolutionMetadata, didRef, publicKeys );

#### Resolve a DID
```javascript
let did_uri = "did:0xfac17a:0x68b5d6033f8958558cc0bb48328bb9ba0651078b3f69eee533a2dfdba75965f2"
let agent = new TrackBackAgent(new Connector());
await agent.procedure.resolve(did_uri);

Revoke a DID

/*
* Returns Promise<ExtrinsicResults>
* ExtrinsicResults 
export type ExtrinsicResults = {
  [key: string]: any;
} | null;
*/
let did_uri = "did:0xfac17a:0x68b5d6033f8958558cc0bb48328bb9ba0651078b3f69eee533a2dfdba75965f2"
let agent = new TrackBackAgent(new Connector());
await agent.procedure.revoke(
    account,
    did_uri
);

Update a DID

  • To update a DID Document, you need to grab the DID information and meta data from resove method
let did_uri = "did:0xfac17a:0x68b5d6033f8958558cc0bb48328bb9ba0651078b3f69eee533a2dfdba75965f2"
let agent = new TrackBackAgent(new Connector());
await agent.procedure.resolve(did_uri);
/*
* Returns Promise<ExtrinsicResults>
* ExtrinsicResults 
export type ExtrinsicResults = {
  [key: string]: any;
} | null;
*/
let agent = new TrackBackAgent(new Connector());
await agent.procedure.updateDIDDocument(
    account,
    didDocument,
    didDocumentMetadata,
    didResolutionMetadata,
    didRef,
    publicKeys
);

Create W3C Verifiable Credentials

Following steups to create and sign W3C credential as jwt

Sign credentials


import { CredentialIssuer } from '@trackback/agent'
import { createAccount } from '@trackback/agent/account'

const connector = new Connector();
// initialize the agent
const agent = new TrackBackAgent(connector);

const account = connector.getAccount(mnemonic)

// create context
const context = {
  agent,
  account
}


//initialize credential issuer
const issuer = await CredentialIssuer.build();

// save did document to ipfs
issuer.save(context)

const credential = {
              '@context': ['https://www.w3.org/2018/credentials/v1'],
              type: ['VerifiableCredential'],
              issuanceDate: '2010-01-01T19:23:24Z',
              credentialSubject: {},
              issuer: issuer.id,
          };

const jwtCredential = await issuer.createVerifiableCredentials(credential)

// jwt

Verify credentials


const connector = new Connector();
// initialize the agent
const agent = new TrackBackAgent(connector);

const account = connector.getAccount(mnemonic)

// create context
const context = {
  agent,
  account
}

const verifier = new CredentialVerifier();

// ... create jwtCredential


 const r = await verifier.verifyCredentials(jwtCredential, context);


 // true/false

Create W3C Verifiable Presentation

Sign presentation

Following steups to create and sign W3C Presentation as jwt


import { CredentialIssuer } from '@trackback/agent'
import { createAccount } from '@trackback/agent/account'


//initialize credential issuer
const issuer = await CredentialIssuer.build();

const keyPair = issuer.keypair

const jwtPresentaion = await issuer.createVerifiablePresentation([
  jwtCredential
], keyPair)

// jwt

Verify presentation

Context is require to retrive verification for credentials


const connector = new Connector();
// initialize the agent
const agent = new TrackBackAgent(connector);

const account = connector.getAccount(mnemonic)

// create context
const context = {
  agent,
  account
}

const verifier = new CredentialVerifier();

// ... create jwtPresentation


 const r = await verifier.verifyPresentation(jwtPresentation, context, issuer.keypair)

 // true/false

With custom chain settings

You can use custom url with sdk.

More info on options : https://polkadot.js.org/docs/api/start/rpc.custom


const { DefaultOptions } = require('@trackback/agent')
const options = {
  url: 'ws://custom.node.example.com', // custom node url ws[s]://custom.node.example.com[:9944]
  options: {...DefaultOptions.options} // using trackback defaults
}

const agent = new TrackBackAgent(new Connector(options));

Creates a new Account



// CREATE NEW ACCOUNT

const connector = new Connector();
const account = connector.createAccount({name:"TrackBack"});

// {
//     keyPair:... ,
//     mnemonic: ... // Your secret key
// }

// use polka js wallet to send credit to your account
// Creates the new account by using the mnemonic generated for the new account
// You can use a design implementation of your own to store the mnemonic
// https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Falpha-node.trackback.dev#/accounts

// initialize the agent
const agent = new TrackBackAgent(connector);

// load your account back
const importedAccount = connector.getAccount(account.mnemonic)

// create context
const context = {
  agent,
  account: importedAccount
}


// Creates an Issuer
const issuer = await CredentialIssuer.build();

const metada = { "content-type": "application/json" }
const resMetada = { "content-type": "application/json" }

// Creates a Transaction based on the new account 
const result = await issuer.save(context, metada, resMetada);

changelog

Change Log

All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.

0.0.1-alpha.48 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.47 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.46 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.45 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.44 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.43 (2021-11-25)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.42 (2021-11-24)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.41 (2021-11-24)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.40 (2021-11-24)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.39 (2021-11-24)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.38 (2021-11-24)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.37 (2021-11-23)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.36 (2021-11-23)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.35 (2021-11-21)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.34 (2021-11-18)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.33 (2021-11-18)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.32 (2021-11-18)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.31 (2021-11-18)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.30 (2021-11-18)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.29 (2021-11-17)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.28 (2021-11-17)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.27 (2021-11-17)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.26 (2021-11-16)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.25 (2021-11-15)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.24 (2021-11-11)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.23 (2021-11-09)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.22 (2021-11-08)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.21 (2021-11-08)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.20 (2021-11-01)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.19 (2021-11-01)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.18 (2021-10-29)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.17 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.16 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.15 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.14 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.13 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.12 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.11 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.10 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.9 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.8 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.7 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.6 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.5 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.4 (2021-10-28)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.3 (2021-10-26)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.2 (2021-10-26)

Note: Version bump only for package @trackback/agent

0.0.1-alpha.1 (2021-10-26)

Note: Version bump only for package @trackback/agent