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 🙏

© 2025 – Pkg Stats / Ryan Hefner

certificate-app

v1.0.0

Published

## Setup

Readme

Certificate CLI tool

Setup

yarn

Generate Sample Certificates

Generates a number of sample certificates based on the specification by open badge v2 with our extension.

./index.js generate <dir> --count <CertificatesToGenerate> --contract-address <CertificateStoreContractAddress>

Example:

./index.js generate certificates/raw-certificates --count 50 --contract-address 0x345ca3e014aaf5dca488057592ee47305d9b3e10

========================== Generating random certificate ==========================

Generated 50 certificates.

===================================================================================

Batching Certificates

This command process all certificates in the input directory and issue all of them in a single batch. It will then add the signature to the individual certificates.

./index.js batch <PathToUnsignedCertificates> <PathToSignedCertificates>

Example:

./index.js batch ./certificates/raw-certificates/ ./certificates/processed-certificates/

============================== Batching certificates ==============================

Batch Certificate Root:
458a80232eda8a816972be8ac731feb50727149aff6287d70142821ae160caf7

===================================================================================

Certificate privacy filter

This allows certificate holders to generate valid certificates which hides certain evidences. Useful for hiding grades lol.

./index.js filter <inputCertificatePath> <outputCertificatePath> [filters...]

Example:

./index.js filter ./certificates/processed-certificates/urn\:uuid\:060b3c1b-0689-4558-b946-862963641eba.json ./certificates/processed-certificates/urn\:uuid\:060b3c1b-0689-4558-b946-862963641eba.out.json transcript.0.grade transcript.1.grade transcript.2.grade

============================== Filtered Certificate ==============================

{
  "id": "urn:uuid:060b3c1b-0689-4558-b946-862963641eba",
  "type": "Assertion",
  "issuedOn": "2018-02-19T09:12:20.051Z",
  "@context": [
    "https://openbadgespec.org/v2/context.json",
    "https://govtechsg.github.io/certificate-schema/schema/1.0/context.json"
  ],
  "badge": {
    "name": "pibbwa4x2x7fo0a68v18dr4bn",
    "criteria": "1woyqebh30rpkvrnps7j0h8m8tnun0zmmlo46f1d5eo2ctc962g61pmaq1nu7ayxp24nudlwn7x1277r",
    "issuer": {
      "id": "urn:uuid:599fd698-5095-4e4b-8469-ea30a994b420",
      "url": "http://jeffry.name",
      "email": "[email protected]"
    },
    "type": "BadgeClass",
    "evidencePrivacyFilter": {
      "type": "SaltedProof",
      "saltLength": "10"
    },
    "evidence": {
      "transcript": [
        {
          "name": "rxavnnnqwx:d6whoa8c2bryr6w",
          "courseCode": "58ezfx0pgl:1f79g",
          "courseCredit": "8j3qiv8smt:447"
        },
        {
          "name": "3vvhp01ayb:qnk3zhkldkyqa0e",
          "courseCode": "j5xnkor9n6:3hmlm",
          "courseCredit": "xgcqoui543:bsx"
        },
        {
          "name": "e54t99btvq:ogp6zzbb21en9kb",
          "courseCode": "nuj4oj52ow:y9j6j",
          "courseCredit": "jofurno8f6:3pf"
        }
      ]
    },
    "privateEvidence": [
      "17359b28df891116c1c5dbe610f60fb647f0977e803f16b9142c6bda3d0a4b9d",
      "f7261d891a828f8f6dcf5c0455d0dd69700f0e1c6ac7d752d9c39a26d57d33ab",
      "b5db6261eac1c096f3dbc5ecae00262625fad91a6387379d113d74619481bcfc"
    ]
  },
  "verification": {
    "type": "ETHStoreProof",
    "contractAddress": "0x0"
  },
  "profile": [
    {
      "type": "email",
      "identity": "[email protected]",
      "hashed": false
    },
    {
      "type": "did",
      "identity": "sha256$471ef07fbe24fb98520ee75a14581154b19bd62f2b9e1a42fded71fc9183b8be",
      "salt": "2e6sb2v56c",
      "hashed": true
    },
    {
      "type": "url",
      "identity": "sha256$2f4ddbfae9af670d9e4792c8b02484151a1d47a59ef71861131bb098dea9fb8a",
      "salt": "k25y6u7ewh",
      "hashed": true
    }
  ],
  "signature": {
    "type": "SHA3MerkleProof",
    "targetHash": "5550fbc3fa29ff4def2ac59b09e827cce80e937c1489a39096215b8564ac6313",
    "proof": [
      "598e8ca0a2763be8227a0be2ea2441616cc36602db7c8d55e9e69589cf5b3739",
      "71f8b42b995465067d4953bed91f936a3e8a11d6007d0b2aae9ae1193c696d71",
      "0b9d1ef301795d9ce61d06057b6e5afeeb3470aa562a54eae772338a47d8c29d",
      "b25717b934a5aaba8c589b502ee26a5a25d6c246b5be89f8a789c56ac919cbc3",
      "7f817789145683a2652dd5956d21098ba159d0243a77af99f4d793e9376615e0",
      "77f61d9e9f571718745e8120fdddf42dfe48e0b6f366e56d82068395277793ab"
    ],
    "merkleRoot": "64fda71b939cb33d4e437f832b64f24b772e192f60b7ecd60af2ab9173a03aef"
  }
}

===================================================================================

Verifying Signed Certificate

This command verifies that the certificate (and all it's evidence) is valid and is part of the certificate batch. However, it does not verify that the batch's merkle root is stored on the blockchain. User will need to verify that the certificate has indeed been issued by checking with the issuer's smart contract.

./index.js verify <PathToCertificate>

Example:

./index.js verify ./certificates/processed-certificates/urn:uuid:08b1f10a-6bf0-46c8-bbfd-64750b0d73ef.json

============================== Verifying certificate ==============================

Certificate's signature is valid!

Warning: Please verify this certificate on the blockchain with the issuer's certificate store.

===================================================================================

Deploy Certificate Store

This command deploys a copy of the current version of certificate store on the blockchain. The name of the organisation and verification url is needed to initialise the store.

./index.js deploy <issuerAddress> <storeName>

Example:

./index.js deploy 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 "GovTech DLT"

info: Contract deployed at 0x8b784948EbC49E4C3f29765a2401464A3FEe5032.
0x8b784948EbC49E4C3f29765a2401464A3FEe5032

Commit Certificate Batch on Certificate Store

This command issues the certificate batch on the blockchain using the given certificate store.

./index.js commit <merkleRoot> <issuerAddress> <storeAddress>

Example:

./index.js commit 0x63f83f3f70bf6605f9a7490cff77824a53d91a31f524665729aea614ea0a16e4 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 0x345ca3e014aaf5dca488057592ee47305d9b3e10

info: Certificate batch issued: 0x63f83f3f70bf6605f9a7490cff77824a53d91a31f524665729aea614ea0a16e4
by 0xab5223dbfccb98e48cf2f5e526a35f135232f0a5 at certificate store 0x8b784948EbC49E4C3f29765a2401464A3FEe5032

0x9bc3b8772a2c61b95971a13994dcc6768a66f214e5c7a60dd29802ea15db35ee

Transferring Ownership of Contract Store

./index.js transfer <originalOwner> <newOwner> <contractAddress>

Example:

./index.js transfer 0xf17f52151EbEF6C7334FAD080c5704D77216b732 0x627306090abaB3A6e1400e9345bC60c78a8BEf57  0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0

info: Contract at 0x8b784948EbC49E4C3f29765a2401464A3FEe5032 transfered from 0xab5223dbfccb98e48cf2f5e526a35f135232f0a5 to 0x627306090abaB3A6e1400e9345bC60c78a8BEf57
0xc491b9b1ffc456859706d5aff913cfc663e93ed31815ace3e3decdf5de70b1a0

Smart Contract Sample Interaction

This script automatically deploys a certificate store and runs all the functions available in the smart contract.

Before running the script be sure to connect to ganache cli/ui with the following mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

node examples/sample.js

TBD

  • Test for functions in index.js
  • Checks for certificate structure when issuing certificate

Test

yarn test