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

@trackback/agent

v0.0.1-alpha.48

Published

TrackBack agent SDK

Downloads

51

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

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'
          }
   * */
}
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);
}
/*
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

  • Reference :- https://www.w3.org/TR/did-core/

Create a DID

  • The DID Document must be saved on IPFS
/*
* `saveToDistributedStorage returns the `cid`
* 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);
/*
* Returns Promise<ExtrinsicResults>
* ExtrinsicResults 
export type ExtrinsicResults = {
  [key: string]: any;
} | null;
*/
let agent = new TrackBackAgent(new Connector());
await agent.procedure.constructDIDDocument(
    account,
    didDocument,
    didDocumentMetadata,
    didResolutionMetadata,
    didRef,
    publicKeys
);

Resolve a DID

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);