{"id":25944960,"url":"https://github.com/path-check/shc-sdk.js","last_synced_at":"2025-03-04T08:20:20.762Z","repository":{"id":57135333,"uuid":"372982671","full_name":"Path-Check/shc-sdk.js","owner":"Path-Check","description":"Verifiable QR SDK for Smart Health Cards","archived":false,"fork":false,"pushed_at":"2022-01-18T20:57:38.000Z","size":754,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-02-07T13:32:59.941Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Path-Check.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-01T23:09:39.000Z","updated_at":"2024-06-08T16:35:41.000Z","dependencies_parsed_at":"2022-09-03T12:22:05.350Z","dependency_job_id":null,"html_url":"https://github.com/Path-Check/shc-sdk.js","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Path-Check%2Fshc-sdk.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Path-Check%2Fshc-sdk.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Path-Check%2Fshc-sdk.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Path-Check%2Fshc-sdk.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Path-Check","download_url":"https://codeload.github.com/Path-Check/shc-sdk.js/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241810043,"owners_count":20023885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-04T08:20:20.029Z","updated_at":"2025-03-04T08:20:20.729Z","avatar_url":"https://github.com/Path-Check.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Verifiable QR SDK for Smart Health Cards\n\nJavaScript Implementation of [Smart Health Cards](https://smarthealth.cards), a JSON/JOSE-based Verifiable QR Credentials. \n\n# Install\n\n```sh\nnpm install @pathcheck/shc-sdk --save\n```\n\n# Usage\n\n## 1. Generating Keys\n\nGenerate private and public keys with the provided script: \n\n```js\nnpm explore @pathcheck/shc-sdk -- npm run-script keys\n```\n\nThe script generates an EC key pair (no certificate) and 3-cert ECDSA chain (root -\u003e CA -\u003e issuer). \n\nSee the available Private and Public keys by opening the generated `/jwks.private.json` file. \n\n```json\n{\n  \"keys\": [\n    {\n      \"kty\": \"EC\",\n      \"kid\": \"PJm-qzYQDnnsa_0IZBcPahQrpwWBfs0lzkgudTgqF9Y\",\n      \"use\": \"sig\",\n      \"alg\": \"ES256\",\n      \"x5c\": [],\n      \"crv\": \"P-256\",\n      \"x\": \"gvaE0Z5GM87K2WM56cSj_bNyYCO6U3cLdlHXpMCaeIQ\",\n      \"y\": \"7vXhWfGecAUGnpNRt-kFp723XSI89IgVL_AzcPdQZzw\",\n      \"d\": \"eXpiDTZbFjFb4n2AQTm1Tsbdj5ILxAsrLtYA9sXk-JA\"\n    },\n    {\n      \"kty\": \"EC\",\n      \"kid\": \"a4dzPoSaJ9s30gZbqgGpz4powoYMJL_DXxIjTOyWRUs\",\n      \"use\": \"sig\",\n      \"alg\": \"ES256\",\n      \"x5c\": [\n        \"MIIB6TCCAW+gAwIBAgIUIfkpVEmIRehr9Bua9ao3y/3QQ1wwCgYIKoZIzj0EAwMwJzElMCMGA1UEAwwcU01BUlQgSGVhbHRoIENhcmQgRXhhbXBsZSBDQTAeFw0yMTA2MDEyMjU5MThaFw0yMjA2MDEyMjU5MThaMCsxKTAnBgNVBAMMIFNNQVJUIEhlYWx0aCBDYXJkIEV4YW1wbGUgSXNzdWVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENV2gZVNVDkG1qPG1DxHLuGzISkQUK8+CcOdWmDirDePVrKtgUE2GMYka/FnXNLqVs3H5D3S9bHWjj4fcX/4j+qN1MHMwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwGQYDVR0RBBIwEIYOaHR0cHM6Ly9wY2YucHcwHQYDVR0OBBYEFO6gnOvFUSWQXytiJIj1mR6MUL1YMB8GA1UdIwQYMBaAFFMXIHxLZDFxAzN9eApYWBwVyxdjMAoGCCqGSM49BAMDA2gAMGUCMQDkBiYNzepGKRjFKhGXrL0aHZBfri9k6BYeWZwpz5Y09fCu1kf2LogGBGqOafaecOQCMBMG1S7ac6yw3aLQ9KeifOzkurtagXOUGczFhlll9n1zZcuu1MeGwXZj3eFezMGUmQ==\",\n        \"MIICBzCCAWigAwIBAgIUCQZvKTZp6jcZ6DFfwYb63NxFWPswCgYIKoZIzj0EAwQwLDEqMCgGA1UEAwwhU01BUlQgSGVhbHRoIENhcmQgRXhhbXBsZSBSb290IENBMB4XDTIxMDYwMTIyNTkxOFoXDTI2MDUzMTIyNTkxOFowJzElMCMGA1UEAwwcU01BUlQgSGVhbHRoIENhcmQgRXhhbXBsZSBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABASj/I+8PPOMmQGpi5mH0cUloMID+MIToZTlI8oSaaAPmbahL8ZYgyJSyuDt/CaWWhMe7aNRq4yKXkVe6X5QMDSs0A7kXx6qQHKz5IG/V3g64k45vb7K27ZbFffBbYX0EaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUUxcgfEtkMXEDM314ClhYHBXLF2MwHwYDVR0jBBgwFoAUINVfr3PhYTvWsDPrqXsT4WIKa7wwCgYIKoZIzj0EAwQDgYwAMIGIAkIB863ot/E1X6L6gcBIiL+wSn6987RhUrlBTmXuvgi4LimWL8/atmoZwj/d/wiNyIP3FuXmrEz/DKVyw0OsKfJfX5kCQgHhcVHpbtMUenMt60q6ArwMGEzOyG/VMFkN4ADitF1+VnsYHPukRhcGIBXTYsReSlb/jC0cPRWUKkeQbJhNbFmRdA==\",\n        \"MIICMjCCAZOgAwIBAgIUcxMn01BGtMf7V+dhd9OB8KXC2gowCgYIKoZIzj0EAwQwLDEqMCgGA1UEAwwhU01BUlQgSGVhbHRoIENhcmQgRXhhbXBsZSBSb290IENBMB4XDTIxMDYwMTIyNTkxOFoXDTMxMDUzMDIyNTkxOFowLDEqMCgGA1UEAwwhU01BUlQgSGVhbHRoIENhcmQgRXhhbXBsZSBSb290IENBMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBnkZLt90ELScic3KVnhxEK8MH2XYRDiqp3ojjO60IiNtmGBQ5umDH/EIkelht2KEe0sqUGfm4g8EDewJ59OWy2eEA8pdsRh5Vi6cirRvHxLfs1WLFEz6bdntA86InPEWk54Km2HYt9c41uAhhjeUd3KBZBIzjc+tQfQXgAmxftqTR6majUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFCDVX69z4WE71rAz66l7E+FiCmu8MB8GA1UdIwQYMBaAFCDVX69z4WE71rAz66l7E+FiCmu8MAoGCCqGSM49BAMEA4GMADCBiAJCALrG/MF5ptDk2EpkSGh4eBXuRxtE487MImqu7Kx7bblK1o0TwZJdm1LaEx88lMwBKEqhYGLqLvDKwGiVqJHzXKIHAkIB4gn5wo4cr02SXWFQtIVpGnfGM7/R4+czmhTS+PxidtHyPHAQv2hRwqUduoVozHvrrEuJmtSwJCwlTT/LpqO94NQ=\"\n      ],\n      \"crv\": \"P-256\",\n      \"x\": \"NV2gZVNVDkG1qPG1DxHLuGzISkQUK8-CcOdWmDirDeM\",\n      \"y\": \"1ayrYFBNhjGJGvxZ1zS6lbNx-Q90vWx1o4-H3F_-I_o\",\n      \"d\": \"JtIEB3GAOypZMc-T0lHIRFbSGgIdgEvGeB_MzpUXzNw\"\n    }\n  ]\n}\n```\n\n## 2. Uploading Public Keys to a Resolvable Address\n\nCopy the newly created `jwks.json` to your `domain.com/.well-known/`\n\nThis file is the same as the previous file, but without the `d` parameter, which holds the private key. \n\n```json\n{\n  \"keys\": [\n    {\n      \"kty\": \"EC\",\n      \"kid\": \"PJm-qzYQDnnsa_0IZBcPahQrpwWBfs0lzkgudTgqF9Y\",\n      \"use\": \"sig\",\n      \"alg\": \"ES256\",\n      \"x5c\": [],\n      \"crv\": \"P-256\",\n      \"x\": \"gvaE0Z5GM87K2WM56cSj_bNyYCO6U3cLdlHXpMCaeIQ\",\n      \"y\": \"7vXhWfGecAUGnpNRt-kFp723XSI89IgVL_AzcPdQZzw\"\n    },\n    {\n      \"kty\": \"EC\",\n      \"kid\": \"a4dzPoSaJ9s30gZbqgGpz4powoYMJL_DXxIjTOyWRUs\",\n      \"use\": \"sig\",\n      \"alg\": \"ES256\",\n      \"x5c\": [\n        \"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\"\n      ],\n      \"crv\": \"P-256\",\n      \"x\": \"NV2gZVNVDkG1qPG1DxHLuGzISkQUK8-CcOdWmDirDeM\",\n      \"y\": \"1ayrYFBNhjGJGvxZ1zS6lbNx-Q90vWx1o4-H3F_-I_o\"\n    }\n  ]\n}\n```\n\nThe verifier will point to that address (e.g. [`http://pcf.pw/.well-known/jwks.json`](http://pcf.pw/.well-known/jwks.json)) to download your public keys and verify the package. \n\n## 3. Preparing to Sign\n\nWith one of the keys: \n\n```js\nconst keyPair = {\n    \"kty\": \"EC\",\n    \"kid\": \"PJm-qzYQDnnsa_0IZBcPahQrpwWBfs0lzkgudTgqF9Y\",\n    \"use\": \"sig\",\n    \"alg\": \"ES256\",\n    \"x5c\": [],\n    \"crv\": \"P-256\",\n    \"x\": \"gvaE0Z5GM87K2WM56cSj_bNyYCO6U3cLdlHXpMCaeIQ\",\n    \"y\": \"7vXhWfGecAUGnpNRt-kFp723XSI89IgVL_AzcPdQZzw\",\n    \"d\": \"eXpiDTZbFjFb4n2AQTm1Tsbdj5ILxAsrLtYA9sXk-JA\"\n  }\n```\n\nAnd a JSON Payload\n\n```js\nconst TEST_PAYLOAD = {\n    \"type\": [\n      \"https://smarthealth.cards#health-card\",\n      \"https://smarthealth.cards#immunization\",\n      \"https://smarthealth.cards#covid19\"\n    ],\n    \"credentialSubject\": {\n      \"fhirVersion\": \"4.0.1\",\n      \"fhirBundle\": {\n        \"resourceType\": \"Bundle\",\n        \"type\": \"collection\",\n        \"entry\": [\n          {\n            \"fullUrl\": \"resource:0\",\n            \"resource\": {\n              \"resourceType\": \"Patient\",\n              \"name\": [\n                {\n                  \"family\": \"Anyperson\",\n                  \"given\": [\n                    \"John\",\n                    \"B.\"\n                  ]\n                }\n              ],\n              \"birthDate\": \"1951-01-20\"\n            }\n          },\n          {\n            \"fullUrl\": \"resource:1\",\n            \"resource\": {\n              \"resourceType\": \"Immunization\",\n              \"status\": \"completed\",\n              \"vaccineCode\": {\n                \"coding\": [\n                  {\n                    \"system\": \"http://hl7.org/fhir/sid/cvx\",\n                    \"code\": \"207\"\n                  }\n                ]\n              },\n              \"patient\": {\n                \"reference\": \"resource:0\"\n              },\n              \"occurrenceDateTime\": \"2021-01-01\",\n              \"performer\": [\n                {\n                  \"actor\": {\n                    \"display\": \"ABC General Hospital\"\n                  }\n                }\n              ],\n              \"lotNumber\": \"0000001\"\n            }\n          },\n          {\n            \"fullUrl\": \"resource:2\",\n            \"resource\": {\n              \"resourceType\": \"Immunization\",\n              \"status\": \"completed\",\n              \"vaccineCode\": {\n                \"coding\": [\n                  {\n                    \"system\": \"http://hl7.org/fhir/sid/cvx\",\n                    \"code\": \"207\"\n                  }\n                ]\n              },\n              \"patient\": {\n                \"reference\": \"resource:0\"\n              },\n              \"occurrenceDateTime\": \"2021-01-29\",\n              \"performer\": [\n                {\n                  \"actor\": {\n                    \"display\": \"ABC General Hospital\"\n                  }\n                }\n              ],\n              \"lotNumber\": \"0000007\"\n            }\n          }\n        ]\n      }\n    }\n  };\n```\n\nMake a JWT and call the `signAndPack` function to create the URI for the QR Code: \n\n```js\nconst {signAndPack, unpackAndVerify} = require('@pathcheck/shc-sdk');\n\n// parameters are: payload, months to expire, issuer address to download the public key\nconst jwt = await makeJWT(TEST_PAYLOAD, 48, \"https://pcf.pw\")\nconst qrUri = await signAndPack(jwt, keyPair);\n```\n\nAnd call the unpack and verify to convert the URI into the payload: \n\n```js\nconst jsonld = await unpackAndVerify(qrUri);\n```\n\n# Development\n\n```sh\nnpm install\n``` \n\n# Test\n\n```sh\nnpm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpath-check%2Fshc-sdk.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpath-check%2Fshc-sdk.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpath-check%2Fshc-sdk.js/lists"}