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

@digitalcredentials/sign-and-verify-core

v3.0.0

Published

DCC's VC signing and verification libraries

Downloads

101

Readme

sign-and-verify-core

Signing and verification of Verifiable Credentials and Verifiable Presentations using an unlocked DID Document.

Usage

Install the npm package:

npm i @digitalcredentials/sign-and-verify-core
OR
yarn add @digitalcredentials/sign-and-verify-core

and then use that issuer...

Generating a new key pair

You can use the sample keypair that comes with sign-and-verify (unlockedDID), but eventually you'll want to generate your own key pair, which you can do thusly:

const {Ed25519VerificationKey2020} = require('@digitalbazaar/ed25519-verification-key-2020');
const generate = async function() {
    const edKeyPair = await Ed25519VerificationKey2020.generate({controller: 'did:web:credentials.mcmaster.ca'})
    const keys = await edKeyPair.export({publicKey: true, privateKey: true});
    console.log(JSON.stringify(keys, null, 2))
}
generate()

You can run this on the command line in an npm package with the @digitalbazaar/ed25519-verification-key-2020 library installed.

This produces a key pair, which should look something like this:

{
  id: 'did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp',
  type: 'Ed25519VerificationKey2020',
  controller: 'did:web:credentials.mcmaster.ca',
  publicKeyMultibase: 'z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp',
  privateKeyMultibase: 'zruzggrR7q9cHFrzVmk7kHvDwo9vdtCQtXoUebGBDYYz3A6CdnLub4CYYMaKLB6X6LQTCix7m2tEJbYbUWjTN5yX8ZY'
}

Put it into the DID document to get something like this:

{
	"@context": [
		"https://www.w3.org/ns/did/v1",
		"https://w3id.org/security/suites/ed25519-2020/v1"
	],
	"id": "did:web:digitalcredentials.mcmaster.ca",
	"assertionMethod": [{
  		"id": "did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
  		"type": "Ed25519VerificationKey2020",
  		"controller": "did:web:credentials.mcmaster.ca",
  		"publicKeyMultibase": "z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
  		"privateKeyMultibase": "zruzggrR7q9cHFrzVmk7kHvDwo9vdtCQtXoUebGBDYYz3A6CdnLub4CYYMaKLB6X6LQTCix7m2tEJbYbUWjTN5yX8ZY"
	}]
}

Save this somewhere. The Examples section explains how to use it.

NOTE: IMPORTANT! IMPORTANT! This DID Document contains the private key and so should NEVER be posted publicly (and should be kept secure as appropriate for your security requirements.) This so-called 'unlocked' DID Document is only meant to be used locally with this library (because the library needs the private key to sign with). If you do end up wanting to post the DID publicly (like at the DID:WEB .well-known URI, e.g., http://credentials.mcmaster.ca/.well-known/did.json), first remove the private key, and post the rest:

{
	"@context": [
		"https://www.w3.org/ns/did/v1",
		"https://w3id.org/security/suites/ed25519-2020/v1"
	],
	"id": "did:web:digitalcredentials.mcmaster.ca",
	"assertionMethod": [{
  		"id": "did:web:credentials.mcmaster.ca#z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp",
  		"type": "Ed25519VerificationKey2020",
  		"controller": "did:web:credentials.mcmaster.ca",
  		"publicKeyMultibase": "z6MkfcpjR3X7xJja2atED1E6meTTUjjTmKf7E2Kq2JFHK1Xp"
	}]
}

Examples

You can see a lot of this in tests - we just reproduce/re-organize it here to make it easier to understand if you are new to javascript, or to testing, or really just want to see the important parts without distractions.

NOTE: where we say 'presentation', we mean a Verifiable Presentation

NOTE: where we say 'credential', we mean a Verifiable Credential

You'll need an unlocked DID document with which to sign (like this one: unlockedDID or generate your own as explained above).

import {createIssuer} from sign-and-verify-core;

// Load your unlocked DID from wherever you like.  For example, from the file system (if say you copied 
// data/unlocked-did:key.json from this repo to your project):

const unlockedDidDocument = JSON.parse(readFileSync("data/unlocked-did:key.json").toString("ascii"));

// create the issuer, passing in the unlocked DID document
const { sign, requestDemoCredential, verify, signPresentation, createAndSignPresentation, verifyPresentation } = createIssuer(unlockedDidDocument)

const sampleUnsignedCredential = {
	"@context": [
    "https://www.w3.org/2018/credentials/v1", 
    "https://www.w3.org/2018/credentials/examples/v1", 
    "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
  ],
	"id": "http://example.gov/credentials/3732",
	"type": ["VerifiableCredential", "UniversityDegreeCredential"],
	"issuer": "did:web:digitalcredentials.github.io",
	"issuanceDate": "2020-03-10T04:24:12.164Z",
	"credentialSubject": {
		"id": "did:example:abcdef",
		"degree": {
			"type": "BachelorDegree",
			"name": "Bachelor of Science and Arts"
		}
	}
} 

const sampleSignedCredential = {
	"@context": [
    "https://www.w3.org/2018/credentials/v1", 
    "https://www.w3.org/2018/credentials/examples/v1", 
    "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
  ],
	"id": "http://example.gov/credentials/3732",
	"type": ["VerifiableCredential", "UniversityDegreeCredential"],
	"issuer": "did:web:digitalcredentials.github.io",
	"issuanceDate": "2020-03-10T04:24:12.164Z",
	"credentialSubject": {
		"id": "did:example:me",
		"degree": {
			"type": "BachelorDegree",
			"name": "Bachelor of Science and Arts"
		}
	},
	"proof": {
		"type": "JsonWebSignature2020",
		"created": "2020-11-12T23:56:27.928Z",
		"jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2DppQ4Euf9PUX6NrFPyJwHKPmeAqNWAC6UH8kiFNbsoiinebPpwdortHe-bLzDOQ_W7MQD5nqOnNN8JIVGarAA",
		"proofPurpose": "assertionMethod",
		"verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs"
	}
}

const sampleUnsignedPresentation = {
  '@context': [
    'https://www.w3.org/2018/credentials/v1',
    'https://www.w3.org/2018/credentials/examples/v1',
    'https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json'
  ],
  type: [ 'VerifiablePresentation' ],
  id: '456',
  holder: 'did:web:digitalcredentials.github.io'
}


const sampleSignedPresentation = {
	"@context": [
    "https://www.w3.org/2018/credentials/v1", 
    "https://www.w3.org/2018/credentials/examples/v1", 
    "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json"
  ],
	"type": ["VerifiablePresentation"],
	"id": "456",
	"holder": "did:web:digitalcredentials.github.io",
	"proof": {
		"type": "JsonWebSignature2020",
		"created": "2020-11-12T22:00:33.393Z",
		"challenge": "123",
		"jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..nuQE1vdLcf0YJSI_ojCdOpkQ53Amf4admAfA1eds9ONz9iskp5NBHqoz_YpzyRPxRvj4zblDDAhR524Dn4BtBA",
		"proofPurpose": "authentication",
		"verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs"
	}
}

// NOTE that the property passed in through credentialOptions is called the verificationMethod, 
// but for this demo, which uses an [unlockedDID](data/unlocked-did:key.json) 
// it also identifies the signing key with which to sign credentials, I think just because the 
// the private key is packaged in together with the public key
const credentialOptions = {
  "verificationMethod": "did:web:digitalcredentials.github.io#96K4BSIWAkhcclKssb8yTWMQSz4QzPWBy-JsAFlwoIs",
}
// same as above for credentials, but also with a 'challenge':
const presentationOptions = {...credentialOptions, "challenge": "123"}

/* CREDENTIAL EXAMPLES */

// sign a credential
const result = sign(sampleUnsignedCredential, credentialOptions)

// verify a credential
const result = verify(sampleSignedCredential, credentialOptions)

// Request a demo credential, providing a signed presentation to prove DID ownership (control)
const result = requestDemoCredential(sampleSignedPresentation)


// Request a demo credential - without providing a full presentation to prove DID ownership.
// Instead, simply provide an object with a holder property where we'd expect one in a presentation,
// so kind of like a presentation stripped down to just the holder property.
const minimalPresentation = { holder: "did:example:me" }
const shouldSkipVerification = true
const result = requestDemoCredential(minimalPresentation, shouldSkipVerification)

/* PRESENTATION EXAMPLES */

// sign a provided but as yet unsigned presentation
const result = signPresentation(sampleUnsignedPresentation, presentationOptions)

// verify a presentation
// Note:  for fun and profit, you could also verify the signed presentation returned 
// from the 'signPresentation' step above
const result = verifyPresentation(sampleSignedPresentation, presentationOptions)

const presentationId = '456'
const holderDID = 'did:example:me';
// construct and sign a presentation that wraps a given signed credential
const result = createAndSignPresentation(sampleSignedCredential, presentationId, holderDID, presentationOptions);

// construct and sign a presentation, without providing an associated credential (hence the null argument)
const result = createAndSignPresentation(null, presentationId, holderDID, presentationOptions);

References

You should be familiar with the W3C Verifiable Credentials Data Model. Two key concepts are:

Development

To make changes to the package:

Install

npm run install

Build

npm run build

Test

npm run test

Publish to NPM

npm publish --access public

Before publishing, do make sure you are logged into npm on the command line, e.g., with

npm adduser

Note that npm publish --access public will trigger the prepublishOnly script to first run the build