From ba280998480a4abf174dfe7ed8738d4a03acf06a Mon Sep 17 00:00:00 2001 From: turnoffthiscomputer <98749896+remicolin@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:16:03 +0100 Subject: [PATCH 1/3] Revert "Update/openpassport zk kit" --- common/package.json | 5 ++--- common/src/utils/csca.ts | 2 +- common/src/utils/generateInputs.ts | 7 +++---- common/src/utils/pubkeyTree.ts | 25 ++++++++--------------- common/src/utils/smtTree.ts | 4 ++-- common/src/utils/utils.ts | 6 +++--- common/yarn.lock | 32 +++++++----------------------- 7 files changed, 26 insertions(+), 55 deletions(-) diff --git a/common/package.json b/common/package.json index 1692191f..da86d975 100644 --- a/common/package.json +++ b/common/package.json @@ -9,10 +9,9 @@ "lint": "prettier --check ." }, "dependencies": { + "@ashpect/smt": "https://github.com/ashpect/smt#main", "@babel/runtime": "^7.23.4", - "@openpassport/zk-kit-imt": "^0.0.1", - "@openpassport/zk-kit-lean-imt": "^0.0.1", - "@openpassport/zk-kit-smt": "^0.0.1", + "@zk-kit/imt": "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675", "asn1.js": "^5.4.1", "asn1js": "^3.0.5", "axios": "^1.7.2", diff --git a/common/src/utils/csca.ts b/common/src/utils/csca.ts index e885e937..d394b753 100644 --- a/common/src/utils/csca.ts +++ b/common/src/utils/csca.ts @@ -3,7 +3,7 @@ import * as forge from "node-forge"; import { bytesToBigDecimal, extractRSFromSignature, getNAndK, getNAndKCSCA, hexToDecimal, splitToWords } from "./utils"; import { CSCA_TREE_DEPTH, MODAL_SERVER_ADDRESS } from "../constants/constants"; import { poseidon2 } from "poseidon-lite"; -import { IMT } from "@openpassport/zk-kit-imt"; +import { IMT } from "@zk-kit/imt"; import serialized_csca_tree from "../../pubkeys/serialized_csca_tree.json" import axios from "axios"; import { parseCertificate } from "./certificates/handleCertificate"; diff --git a/common/src/utils/generateInputs.ts b/common/src/utils/generateInputs.ts index 5a73d588..37c0487e 100644 --- a/common/src/utils/generateInputs.ts +++ b/common/src/utils/generateInputs.ts @@ -21,11 +21,10 @@ import { formatCountriesList, } from './utils'; import { generateCommitment, getLeaf } from "./pubkeyTree"; -// import { LeanIMT } from "@zk-kit/imt"; -import { LeanIMT } from "@openpassport/zk-kit-lean-imt"; +import { LeanIMT } from "@zk-kit/imt"; import { getCountryLeaf, getNameLeaf, getNameDobLeaf, getPassportNumberLeaf } from "./smtTree"; import { packBytes } from "../utils/utils"; -import { SMT } from "@openpassport/zk-kit-smt" +import { SMT } from "@ashpect/smt" import { parseCertificate } from './certificates/handleCertificate'; export function generateCircuitInputsDisclose( @@ -269,4 +268,4 @@ export function formatInput(input: any) { } else { return [BigInt(input).toString()]; } -} \ No newline at end of file +} diff --git a/common/src/utils/pubkeyTree.ts b/common/src/utils/pubkeyTree.ts index bdd44bea..84814068 100644 --- a/common/src/utils/pubkeyTree.ts +++ b/common/src/utils/pubkeyTree.ts @@ -1,5 +1,5 @@ import { PUBKEY_TREE_DEPTH, COMMITMENT_TREE_TRACKER_URL, SignatureAlgorithmIndex } from "../constants/constants"; -import { LeanIMT } from "@openpassport/zk-kit-lean-imt"; +import { LeanIMT } from '@zk-kit/imt' import axios from "axios"; import { poseidon16, poseidon2, poseidon6, poseidon7 } from 'poseidon-lite'; import { formatDg2Hash, getNAndK, getNAndKCSCA, hexToDecimal, splitToWords } from './utils'; @@ -65,18 +65,13 @@ export function getLeafCSCA(dsc: string): string { return customHasher([sigAlgIndex, ...pubkeyChunked]); } } - export async function getTreeFromTracker(): Promise { const response = await axios.get(COMMITMENT_TREE_TRACKER_URL) - - const parsedResponse: string[][] = JSON.parse(response.data); - const commitmentTreeData: string = JSON.stringify(parsedResponse); - - const imt = LeanIMT.import( + const imt = new LeanIMT( (a: bigint, b: bigint) => poseidon2([a, b]), - commitmentTreeData, - (value: string) => BigInt(value) - ); + [] + ); + imt.import(response.data) return imt } @@ -100,13 +95,9 @@ export async function fetchTreeFromUrl(url: string): Promise { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - const commitmentMerkleTree = await response.json(); console.log("\x1b[90m%s\x1b[0m", "commitment merkle tree: ", commitmentMerkleTree); - const tree = LeanIMT.import( - (a: bigint, b: bigint) => poseidon2([a, b]), - commitmentMerkleTree, - (value: string) => BigInt(value) - ); + const tree = new LeanIMT((a, b) => poseidon2([a, b])); + tree.import(commitmentMerkleTree); return tree; -} \ No newline at end of file +} diff --git a/common/src/utils/smtTree.ts b/common/src/utils/smtTree.ts index ee300ebe..4f3d9d21 100644 --- a/common/src/utils/smtTree.ts +++ b/common/src/utils/smtTree.ts @@ -1,6 +1,6 @@ import { poseidon9, poseidon3, poseidon2, poseidon6, poseidon13 } from "poseidon-lite" import { stringToAsciiBigIntArray } from "./utils"; -import { SMT, ChildNodes } from "@openpassport/zk-kit-smt"; +import { ChildNodes, SMT } from "@ashpect/smt" // SMT trees for 3 levels : // 1. Passport tree : level 3 (Absolute Match) @@ -197,4 +197,4 @@ export function getDobLeaf(dobMrz: (bigint | number)[], i?: number): bigint { } catch (err) { console.log('err : Dob', err, i, dobMrz) } -} \ No newline at end of file +} diff --git a/common/src/utils/utils.ts b/common/src/utils/utils.ts index 3a37e0dd..4a2fc688 100644 --- a/common/src/utils/utils.ts +++ b/common/src/utils/utils.ts @@ -1,8 +1,8 @@ -import { LeanIMT } from '@openpassport/zk-kit-lean-imt'; +import { LeanIMT } from '@zk-kit/imt'; import { sha256 } from 'js-sha256'; import { sha1 } from 'js-sha1'; import { sha384, sha512_256 } from 'js-sha512'; -import { SMT } from '@openpassport/zk-kit-smt'; +import { SMT } from '@ashpect/smt'; import forge from 'node-forge'; import { n_dsc, k_dsc, n_dsc_ecdsa, k_dsc_ecdsa, n_csca, k_csca, attributeToPosition } from '../constants/constants'; import { unpackReveal } from './revealBitmap'; @@ -583,4 +583,4 @@ export function getOlderThanFromCircuitOutput(olderThan: string[]): number { const ageString = olderThan.map(code => String.fromCharCode(parseInt(code))).join(''); const age = parseInt(ageString, 10); return isNaN(age) ? 0 : age; -} \ No newline at end of file +} diff --git a/common/yarn.lock b/common/yarn.lock index f31d85a8..275694c2 100644 --- a/common/yarn.lock +++ b/common/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@ashpect/smt@https://github.com/ashpect/smt#main": + version "1.0.0" + resolved "https://github.com/ashpect/smt#4f73fd24adb06a7f8efd6fd2d3ed58e9e2f2691a" + "@babel/runtime@^7.23.4": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.9.tgz#65884fd6dc255a775402cc1d9811082918f4bf00" @@ -14,25 +18,6 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== -"@openpassport/zk-kit-imt@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@openpassport/zk-kit-imt/-/zk-kit-imt-0.0.1.tgz#4f68810fcd38f300054d8b8b4814f02a6534136b" - integrity sha512-wz4ApTvOYd2+XArOMsZgNKXfMVb/s1K3JRYJ6FcqU8duk6R3Sd90kfBgpf6wi+YZ92TrJtEO41jFWlkFX0YRGw== - dependencies: - "@zk-kit/utils" "1.2.1" - -"@openpassport/zk-kit-lean-imt@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@openpassport/zk-kit-lean-imt/-/zk-kit-lean-imt-0.0.1.tgz#6fbd3e6207c621dfb947e9ea17e67326aaf3292a" - integrity sha512-6CeUEX951hbELDYfadFS5bRQyEbxAt/vPBoCeyRcPkwPmQj/2ys8D7XlGFulicdsNYHjW3V9oZ/CFLCr93shJA== - dependencies: - "@zk-kit/utils" "1.2.1" - -"@openpassport/zk-kit-smt@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@openpassport/zk-kit-smt/-/zk-kit-smt-0.0.1.tgz#d447ed24e7b57146d5dee8d7458ac3886346b4d2" - integrity sha512-P7Hkd5fD8JxGbqJ48lUq6gGKmZTaVzCB5I8FsOSUmljqf7VMeZmbyqo2ZmXt/lk6ltPXrmcrQ+QNhHXKZNcWhg== - "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -52,12 +37,9 @@ dependencies: undici-types "~6.19.2" -"@zk-kit/utils@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-1.2.1.tgz#6cb38120535c73ab68cd0f09684882af148f256d" - integrity sha512-H2nTsyWdicVOyvqC5AjgU7tsTgmR6PDrruFJNmlmdhKp7RxEia/E1B1swMZjaasYa2QMp4Zc6oB7cWchty7B2Q== - dependencies: - buffer "^6.0.3" +"@zk-kit/imt@https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675": + version "2.0.0-beta.1" + resolved "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675#38244ea6eef75dc1ad7fff3ff2a22dd5f1a2593a" ansi-colors@^4.1.3: version "4.1.3" From a093f3bb8487d1363457e06cd12cdf7235f2caf6 Mon Sep 17 00:00:00 2001 From: turnoffthiscomputer Date: Sun, 27 Oct 2024 22:38:51 +0100 Subject: [PATCH 2/3] handle when users come from deeplink without registering before --- app/src/utils/qrCode.ts | 47 ++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/utils/qrCode.ts b/app/src/utils/qrCode.ts index 2229897c..0786c06f 100644 --- a/app/src/utils/qrCode.ts +++ b/app/src/utils/qrCode.ts @@ -88,28 +88,37 @@ export const scanQRCode = () => { const handleQRCodeScan = (result: string, toast: any, setSelectedApp: any, setSelectedTab: any) => { try { - const decodedResult = atob(result); - const uint8Array = new Uint8Array(decodedResult.split('').map(char => char.charCodeAt(0))); - const decompressedData = pako.inflate(uint8Array); - const unpackedData = msgpack.decode(decompressedData); - const openPassportApp: OpenPassportApp = unpackedData; - setSelectedApp(openPassportApp); + const dsc = useUserStore.getState().passportData?.dsc; + if (dsc) { - const dsc = useUserStore.getState().passportData.dsc; - const sigAlgName = parseDSC(dsc!); + const decodedResult = atob(result); + const uint8Array = new Uint8Array(decodedResult.split('').map(char => char.charCodeAt(0))); + const decompressedData = pako.inflate(uint8Array); + const unpackedData = msgpack.decode(decompressedData); + const openPassportApp: OpenPassportApp = unpackedData; + setSelectedApp(openPassportApp); - const circuitName = openPassportApp.mode === 'vc_and_disclose' - ? 'vc_and_disclose' - : getCircuitName("prove" as Mode, sigAlgName.signatureAlgorithm, sigAlgName.hashFunction); - downloadZkey(circuitName as any); + const sigAlgName = parseDSC(dsc); - setSelectedTab("prove"); - toast.show('✅', { - message: "QR code scanned", - customData: { - type: "success", - }, - }); + const circuitName = openPassportApp.mode === 'vc_and_disclose' + ? 'vc_and_disclose' + : getCircuitName("prove" as Mode, sigAlgName.signatureAlgorithm, sigAlgName.hashFunction); + downloadZkey(circuitName as any); + + setSelectedTab("prove"); + toast.show('✅', { + message: "QR code scanned", + customData: { + type: "success", + }, + }); + } + else { + toast.show('Welcome', { + message: 'Please register your passport first', + type: 'info', + }); + } } catch (error) { console.error('Error parsing QR code result:', error); toast.show('Try again', { From 3c7eb5e1b52cfff2d81a0b3f1ef5c85eb9f875ea Mon Sep 17 00:00:00 2001 From: turnoffthiscomputer Date: Sun, 27 Oct 2024 22:39:06 +0100 Subject: [PATCH 3/3] divide web-sdk in two parts --- sdk/{ => core}/.gitignore | 0 sdk/{ => core}/.prettierrc | 0 sdk/{ => core}/README.md | 0 sdk/core/index.ts | 14 ++ sdk/core/package.json | 79 +++++++++++ sdk/{ => core}/src/AttestationVerifier.ts | 16 +-- sdk/{ => core}/src/OpenPassportVerifier.ts | 9 +- .../src/OpenPassportVerifierReport.ts | 0 sdk/{ => core}/tsconfig.json | 13 +- sdk/{ => core}/utils/skiPem.ts | 0 sdk/{ => core}/utils/utils.ts | 24 ++-- .../QRcode => qrcode}/OpenPassportQRcode.d.ts | 4 +- .../QRcode => qrcode}/OpenPassportQRcode.tsx | 28 +++- sdk/qrcode/README.md | 127 ++++++++++++++++++ .../animations/check_animation.json | 0 .../animations/x_animation.json | 0 sdk/{src/QRcode => qrcode}/components/LED.tsx | 0 sdk/qrcode/index.ts | 4 + sdk/{ => qrcode}/package.json | 13 +- sdk/qrcode/tsconfig.json | 32 +++++ sdk/{ => qrcode}/tsconfig.react.json | 0 sdk/{src/QRcode => qrcode}/utils/styles.ts | 0 sdk/{src/QRcode => qrcode}/utils/utils.ts | 0 sdk/{src/QRcode => qrcode}/utils/websocket.ts | 4 +- sdk/src/index.ts | 25 ---- sdk/tests/web-app/src/app/prove/page.tsx | 6 +- 26 files changed, 324 insertions(+), 74 deletions(-) rename sdk/{ => core}/.gitignore (100%) rename sdk/{ => core}/.prettierrc (100%) rename sdk/{ => core}/README.md (100%) create mode 100644 sdk/core/index.ts create mode 100644 sdk/core/package.json rename sdk/{ => core}/src/AttestationVerifier.ts (95%) rename sdk/{ => core}/src/OpenPassportVerifier.ts (94%) rename sdk/{ => core}/src/OpenPassportVerifierReport.ts (100%) rename sdk/{ => core}/tsconfig.json (74%) rename sdk/{ => core}/utils/skiPem.ts (100%) rename sdk/{ => core}/utils/utils.ts (83%) rename sdk/{src/QRcode => qrcode}/OpenPassportQRcode.d.ts (73%) rename sdk/{src/QRcode => qrcode}/OpenPassportQRcode.tsx (81%) create mode 100644 sdk/qrcode/README.md rename sdk/{src/QRcode => qrcode}/animations/check_animation.json (100%) rename sdk/{src/QRcode => qrcode}/animations/x_animation.json (100%) rename sdk/{src/QRcode => qrcode}/components/LED.tsx (100%) create mode 100644 sdk/qrcode/index.ts rename sdk/{ => qrcode}/package.json (90%) create mode 100644 sdk/qrcode/tsconfig.json rename sdk/{ => qrcode}/tsconfig.react.json (100%) rename sdk/{src/QRcode => qrcode}/utils/styles.ts (100%) rename sdk/{src/QRcode => qrcode}/utils/utils.ts (100%) rename sdk/{src/QRcode => qrcode}/utils/websocket.ts (94%) delete mode 100644 sdk/src/index.ts diff --git a/sdk/.gitignore b/sdk/core/.gitignore similarity index 100% rename from sdk/.gitignore rename to sdk/core/.gitignore diff --git a/sdk/.prettierrc b/sdk/core/.prettierrc similarity index 100% rename from sdk/.prettierrc rename to sdk/core/.prettierrc diff --git a/sdk/README.md b/sdk/core/README.md similarity index 100% rename from sdk/README.md rename to sdk/core/README.md diff --git a/sdk/core/index.ts b/sdk/core/index.ts new file mode 100644 index 00000000..40a229e0 --- /dev/null +++ b/sdk/core/index.ts @@ -0,0 +1,14 @@ +import { OpenPassportVerifierReport } from './src/OpenPassportVerifierReport'; +import { OpenPassportVerifier } from './src/OpenPassportVerifier'; +import { countryCodes } from '../../common/src/constants/constants'; +import { + OpenPassportAttestation, + OpenPassportDynamicAttestation, +} from '../../common/src/utils/openPassportAttestation'; +export { + OpenPassportVerifier, + OpenPassportAttestation, + OpenPassportDynamicAttestation, + OpenPassportVerifierReport, + countryCodes, +}; diff --git a/sdk/core/package.json b/sdk/core/package.json new file mode 100644 index 00000000..29da7cfc --- /dev/null +++ b/sdk/core/package.json @@ -0,0 +1,79 @@ +{ + "name": "@openpassport/core", + "version": "0.0.4", + "main": "dist/sdk/core/index.js", + "types": "dist/sdk/core/index.d.ts", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/zk-passport/openpassport" + }, + "author": "turnoffthiscomputer", + "dependencies": { + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@types/uuid": "^10.0.0", + "elliptic": "^6.5.7", + "fs": "^0.0.1-security", + "js-sha1": "^0.7.0", + "js-sha256": "^0.11.0", + "js-sha512": "^0.9.0", + "lottie-react": "^2.4.0", + "msgpack-lite": "^0.1.26", + "next": "^14.2.8", + "node-forge": "https://github.com/remicolin/forge", + "pako": "^2.1.0", + "pkijs": "^3.2.4", + "poseidon-lite": "^0.2.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "snarkjs": "^0.7.4", + "uuid": "^10.0.0", + "zlib": "^1.0.5", + "@zk-kit/imt": "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675" + }, + "devDependencies": { + "@types/chai": "^4.3.6", + "@types/chai-as-promised": "^7.1.8", + "@types/circomlibjs": "^0.1.6", + "@types/expect": "^24.3.0", + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.19", + "@types/node-forge": "^1.3.5", + "@types/pako": "^2.0.3", + "@types/snarkjs": "^0.7.8", + "asn1js": "^3.0.5", + "axios": "^1.7.2", + "chai": "^4.3.8", + "chai-as-promised": "^7.1.1", + "dotenv": "^16.4.5", + "mocha": "^10.3.0", + "prettier": "^3.3.3", + "ts-loader": "^9.5.1", + "ts-mocha": "^10.0.0", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" + }, + "scripts": { + "build": "tsc", + "prepublishOnly": "npm run build", + "test": "yarn ts-mocha -p ./tsconfig.json tests/openPassportVerifier.test.ts --exit", + "install-sdk": "cd ../common && yarn && cd ../sdk && yarn", + "download-circuits": "cd ../circuits && ./scripts/download_circuits_from_aws.sh && cd ../sdk", + "format": "prettier --write .", + "lint": "prettier --check ." + }, + "files": [ + "dist", + "common", + "circuits/**/*.json" + ], + "publishConfig": { + "access": "public" + }, + "peerDependencies": { + "lottie-react": "^2.4.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } +} \ No newline at end of file diff --git a/sdk/src/AttestationVerifier.ts b/sdk/core/src/AttestationVerifier.ts similarity index 95% rename from sdk/src/AttestationVerifier.ts rename to sdk/core/src/AttestationVerifier.ts index 8a24d048..57d60def 100644 --- a/sdk/src/AttestationVerifier.ts +++ b/sdk/core/src/AttestationVerifier.ts @@ -6,7 +6,7 @@ import { k_dsc_ecdsa, countryNames, countryCodes, -} from '../../common/src/constants/constants'; +} from '../../../common/src/constants/constants'; import { areArraysEqual, getCurrentDateFormatted, @@ -16,25 +16,23 @@ import { import { OpenPassportAttestation, parsePublicSignalsDisclose, -} from '../../common/src/utils/openPassportAttestation'; -import { parsePublicSignalsDsc, parsePublicSignalsProve, -} from '../../common/src/utils/openPassportAttestation'; +} from '../../../common/src/utils/openPassportAttestation'; import { Mode } from 'fs'; import forge from 'node-forge'; -import { parseCertificate } from '../../common/src/utils/certificates/handleCertificate'; +import { parseCertificate } from '../../../common/src/utils/certificates/handleCertificate'; import { castToScope, formatForbiddenCountriesListFromCircuitOutput, getAttributeFromUnpackedReveal, getOlderThanFromCircuitOutput, splitToWords, -} from '../../common/src/utils/utils'; -import { unpackReveal } from '../../common/src/utils/revealBitmap'; -import { getCSCAModulusMerkleTree } from '../../common/src/utils/csca'; +} from '../../../common/src/utils/utils'; +import { unpackReveal } from '../../../common/src/utils/revealBitmap'; +import { getCSCAModulusMerkleTree } from '../../../common/src/utils/csca'; import { OpenPassportVerifierReport } from './OpenPassportVerifierReport'; -import { fetchTreeFromUrl } from '../../common/src/utils/pubkeyTree'; +import { fetchTreeFromUrl } from '../../../common/src/utils/pubkeyTree'; export class AttestationVerifier { protected devMode: boolean; diff --git a/sdk/src/OpenPassportVerifier.ts b/sdk/core/src/OpenPassportVerifier.ts similarity index 94% rename from sdk/src/OpenPassportVerifier.ts rename to sdk/core/src/OpenPassportVerifier.ts index b975aec5..5b012661 100644 --- a/sdk/src/OpenPassportVerifier.ts +++ b/sdk/core/src/OpenPassportVerifier.ts @@ -5,18 +5,17 @@ import { ArgumentsRegister, Mode, OpenPassportAppPartial, -} from '../../common/src/utils/appType'; + OpenPassportApp +} from '../../../common/src/utils/appType'; import { DEFAULT_RPC_URL, MODAL_SERVER_ADDRESS, WEBSOCKET_URL, countryNames, -} from '../../common/src/constants/constants'; -import { OpenPassportApp } from '../../common/src/utils/appType'; -import { UserIdType } from '../../common/src/utils/utils'; +} from '../../../common/src/constants/constants'; +import { UserIdType } from '../../../common/src/utils/utils'; import * as pako from 'pako'; import msgpack from 'msgpack-lite'; -import { OpenPassportAttestation } from '.'; import { AttestationVerifier } from './AttestationVerifier'; export class OpenPassportVerifier extends AttestationVerifier { private mode: Mode; diff --git a/sdk/src/OpenPassportVerifierReport.ts b/sdk/core/src/OpenPassportVerifierReport.ts similarity index 100% rename from sdk/src/OpenPassportVerifierReport.ts rename to sdk/core/src/OpenPassportVerifierReport.ts diff --git a/sdk/tsconfig.json b/sdk/core/tsconfig.json similarity index 74% rename from sdk/tsconfig.json rename to sdk/core/tsconfig.json index 88dfeace..b0979c01 100644 --- a/sdk/tsconfig.json +++ b/sdk/core/tsconfig.json @@ -14,14 +14,19 @@ "moduleResolution": "node" }, "include": [ - "src/index.ts", + "index.ts", "src/index.node.ts", "src/**/*", "common/**/*", "circuits/**/*", "circuits/**/*.json", "utils/utils.ts", - "../common/src/utils/openPassportAttestation.ts" + "../../common/src/utils/openPassportAttestation.ts" ], - "exclude": ["node_modules", "**/__tests__/*", "dist", "common/src/utils/csca.ts"] -} + "exclude": [ + "node_modules", + "**/__tests__/*", + "dist", + "common/src/utils/csca.ts" + ] +} \ No newline at end of file diff --git a/sdk/utils/skiPem.ts b/sdk/core/utils/skiPem.ts similarity index 100% rename from sdk/utils/skiPem.ts rename to sdk/core/utils/skiPem.ts diff --git a/sdk/utils/utils.ts b/sdk/core/utils/utils.ts similarity index 83% rename from sdk/utils/utils.ts rename to sdk/core/utils/utils.ts index d6e8b4b7..fe258abe 100644 --- a/sdk/utils/utils.ts +++ b/sdk/core/utils/utils.ts @@ -1,12 +1,12 @@ -import { ethers } from 'ethers'; -import { getCurrentDateYYMMDD } from '../../common/src/utils/utils'; +// import { ethers } from 'ethers'; +import { getCurrentDateYYMMDD } from '../../../common/src/utils/utils'; import { attributeToPosition, circuitNameFromMode, REGISTER_ABI, REGISTER_CONTRACT_ADDRESS, -} from '../../common/src/constants/constants'; -import { derToBytes } from '../../common/src/utils/csca'; +} from '../../../common/src/constants/constants'; +import { derToBytes } from '../../../common/src/utils/csca'; import forge from 'node-forge'; import { SKI_PEM, SKI_PEM_DEV } from './skiPem'; import { @@ -17,8 +17,8 @@ import { vkey_dsc_rsa_65537_sha256, vkey_dsc_rsapss_65537_sha256, vkey_vc_and_disclose, -} from '../../common/src/constants/vkey'; -import { getCircuitName } from '../../common/src/utils/certificates/handleCertificate'; +} from '../../../common/src/constants/vkey'; +import { getCircuitName } from '../../../common/src/utils/certificates/handleCertificate'; import { Mode } from 'fs'; export function getCurrentDateFormatted() { @@ -58,12 +58,12 @@ export function getVkeyFromArtifacts( } } -// OpenPassport2Step -export async function checkMerkleRoot(rpcUrl: string, merkleRoot: number) { - const provider = new ethers.JsonRpcProvider(rpcUrl); - const contract = new ethers.Contract(REGISTER_CONTRACT_ADDRESS, REGISTER_ABI, provider); - return await contract.checkRoot(merkleRoot); -} +// // OpenPassport2Step +// export async function checkMerkleRoot(rpcUrl: string, merkleRoot: number) { +// const provider = new ethers.JsonRpcProvider(rpcUrl); +// const contract = new ethers.Contract(REGISTER_CONTRACT_ADDRESS, REGISTER_ABI, provider); +// return await contract.checkRoot(merkleRoot); +// } // OpenPassport1Step function getCSCAPem(formattedValueAdjusted: string, dev_mode: boolean): string { diff --git a/sdk/src/QRcode/OpenPassportQRcode.d.ts b/sdk/qrcode/OpenPassportQRcode.d.ts similarity index 73% rename from sdk/src/QRcode/OpenPassportQRcode.d.ts rename to sdk/qrcode/OpenPassportQRcode.d.ts index 65f74187..89c9910f 100644 --- a/sdk/src/QRcode/OpenPassportQRcode.d.ts +++ b/sdk/qrcode/OpenPassportQRcode.d.ts @@ -1,6 +1,6 @@ import React from 'react'; -import { OpenPassportAttestation, OpenPassportVerifier } from '..'; -import { UserIdType } from '../../../common/src/utils/utils'; +import { OpenPassportAttestation, OpenPassportVerifier } from '@openpassport/core'; +import { UserIdType } from '../../common/src/utils/utils'; interface OpenPassportQRcodeProps { appName: string; diff --git a/sdk/src/QRcode/OpenPassportQRcode.tsx b/sdk/qrcode/OpenPassportQRcode.tsx similarity index 81% rename from sdk/src/QRcode/OpenPassportQRcode.tsx rename to sdk/qrcode/OpenPassportQRcode.tsx index 8cdaa7eb..3a89f6e7 100644 --- a/sdk/src/QRcode/OpenPassportQRcode.tsx +++ b/sdk/qrcode/OpenPassportQRcode.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; -import { OpenPassportAttestation } from '../../../common/src/utils/openPassportAttestation'; -import { OpenPassportVerifier } from '../OpenPassportVerifier'; +import { OpenPassportAttestation } from '../../common/src/utils/openPassportAttestation'; +import { OpenPassportVerifier } from '@openpassport/core'; import { BounceLoader } from 'react-spinners'; import Lottie from 'lottie-react'; import CHECK_ANIMATION from './animations/check_animation.json'; import X_ANIMATION from './animations/x_animation.json'; import LED from './components/LED'; -import { WEBSOCKET_URL } from '../../../common/src/constants/constants'; -import { UserIdType } from '../../../common/src/utils/utils'; +import { WEBSOCKET_URL } from '../../common/src/constants/constants'; +import { UserIdType } from '../../common/src/utils/utils'; import { v4 as uuidv4 } from 'uuid'; import { QRcodeSteps } from './utils/utils'; import { containerStyle, ledContainerStyle, qrContainerStyle } from './utils/styles'; @@ -27,6 +27,22 @@ interface OpenPassportQRcodeProps { size?: number; } +// Create a wrapper component that handles client-side rendering +const OpenPassportQRcodeWrapper: React.FC = (props) => { + const [isClient, setIsClient] = useState(false); + + useEffect(() => { + setIsClient(true); + }, []); + + if (!isClient) { + return null; + } + + return ; +}; + +// Your existing OpenPassportQRcode component const OpenPassportQRcode: React.FC = ({ appName, userId, @@ -37,7 +53,7 @@ const OpenPassportQRcode: React.FC = ({ size = 300, }) => { const [proofStep, setProofStep] = useState(QRcodeSteps.WAITING_FOR_MOBILE); - const [proofVerified, setProofVerified] = useState(null); + const [proofVerified, setProofVerified] = useState(false); const [sessionId, setSessionId] = useState(uuidv4()); useEffect(() => { @@ -109,4 +125,4 @@ const OpenPassportQRcode: React.FC = ({ return
{renderProofStatus()}
; }; -export { OpenPassportQRcode }; +export default OpenPassportQRcodeWrapper; diff --git a/sdk/qrcode/README.md b/sdk/qrcode/README.md new file mode 100644 index 00000000..6b16df20 --- /dev/null +++ b/sdk/qrcode/README.md @@ -0,0 +1,127 @@ +# Installation + +```bash +yarn add @openpassport/sdk +``` + +# Generate a QR code + +### Create an AppType type object: + +```typescript +import { AppType } from '@openpassport/sdk'; +const appName = '🤠 Cowboy App'; +const scope = 'cowboyApp'; +const userID = 'user1234'; +const sessionID = uuidv4(); + +const cowboyApp: AppType = { + name: appName, + scope, + userId: userID, + sessionId: sessionID, + circuit: 'prove', + arguments: { + disclosureOptions: { older_than: '18', nationality: 'France' }, + }, +}; +``` + +| Parameter | Optional | Description | +| ----------- | -------- | ------------------------------------------------------------- | +| `scope` | M | The scope of your application, is unique for each application | +| `name` | M | Name of the application | +| `userId` | M | User ID | +| `sessionId` | M | Session ID | +| `circuit` | M | Circuit to use, only `prove` is available for now | +| `arguments` | O | Optional disclosure options, based on passport attributes | + +### Display the QR code + +Use the appType object defined above to generate a QR code. +The generated QR code is an `HTML element` that you can display in your app. + +```typescript +import { QRCodeGenerator } from '@openpassport/sdk'; + +// [...] define cowboyApp as described above + +const qrCode: HTMLElement = await QRCodeGenerator.generateQRCode(cowboyApp); +``` + +# Verify the proof + +## 1 Step flow + +To use the `OpenPassportVerifier`, import and initialize it as follows: + +```typescript +import { OpenPassportVerifier } from '@openpassport/sdk'; +const verifier = new OpenPassportVerifier({ + scope: 'cowboyApp', + requirements: [ + ['older_than', '18'], + ['nationality', 'France'], + ], +}); +``` + +### Parameters for `OpenPassportVerifier` + +| Parameter | Optional | Description | +| --------------- | -------- | --------------------------------------------------------------------------------- | +| `scope` | M | The scope of your application, is unique for each application. | +| `attestationId` | O | The ID of the attestation, defaults to `PASSPORT_ATTESTATION_ID`. | +| `requirements` | O | An array of requirements, each an array with an attribute and its expected value. | +| `rpcUrl` | O | The RPC URL to connect to the blockchain, defaults to `DEFAULT_RPC_URL`. | +| `dev_mode` | O | Allow users with generated passport to pass the verification. | + +### Verify the proof + +The function fired from the OpenPassport app will send an `OpenPassportVerifierInputs` object. + +```typescript +const result: OpenPassportVerifierReport = await verifier.verify(openPassportVerifierInputs); +``` + +From the `result` object, you can inspect the validity of any submitted attribute. +To check the overall validity of the proof, you can inspect the `valid` attribute. + +```typescript +require(result.valid); +``` + +Nullifier and user identifier are accessible from the `result` object. + +```typescript +const nullifier: number = result.nullifier; +const user_identifier: number = result.user_identifier; +``` + +## 2 Steps flow + +### 🚧 Work in progress 🚧 + +# Development + +Install the dependencies + +```bash +yarn install-sdk +``` + +## Tests + +To run the tests, you need to download the circuits and the zkey files from the AWS s3 bucket. +This script will also compile the circuits to generate the wasm files. +Make sure that the circuits in the circuits folder are up to date with the AWS zkey files. + +```bash +yarn download-circuits +``` + +Then run the tests with the following command: + +```bash +yarn test +``` diff --git a/sdk/src/QRcode/animations/check_animation.json b/sdk/qrcode/animations/check_animation.json similarity index 100% rename from sdk/src/QRcode/animations/check_animation.json rename to sdk/qrcode/animations/check_animation.json diff --git a/sdk/src/QRcode/animations/x_animation.json b/sdk/qrcode/animations/x_animation.json similarity index 100% rename from sdk/src/QRcode/animations/x_animation.json rename to sdk/qrcode/animations/x_animation.json diff --git a/sdk/src/QRcode/components/LED.tsx b/sdk/qrcode/components/LED.tsx similarity index 100% rename from sdk/src/QRcode/components/LED.tsx rename to sdk/qrcode/components/LED.tsx diff --git a/sdk/qrcode/index.ts b/sdk/qrcode/index.ts new file mode 100644 index 00000000..73fe159c --- /dev/null +++ b/sdk/qrcode/index.ts @@ -0,0 +1,4 @@ +import OpenPassportQRcode from './OpenPassportQRcode'; + +export { OpenPassportQRcode }; + diff --git a/sdk/package.json b/sdk/qrcode/package.json similarity index 90% rename from sdk/package.json rename to sdk/qrcode/package.json index 416a6540..a51823d6 100644 --- a/sdk/package.json +++ b/sdk/qrcode/package.json @@ -1,8 +1,8 @@ { - "name": "@proofofpassport/sdk", - "version": "0.3.9", - "main": "dist/sdk/src/index.js", - "types": "dist/sdk/src/index.d.ts", + "name": "@openpassport/qrcode", + "version": "0.0.5", + "main": "dist/sdk/qrcode/index.js", + "types": "dist/sdk/qrcode/index.d.ts", "license": "MIT", "repository": { "type": "git", @@ -10,6 +10,7 @@ }, "author": "turnoffthiscomputer", "dependencies": { + "@openpassport/core": "0.0.4", "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "@types/uuid": "^10.0.0", @@ -25,12 +26,12 @@ "pako": "^2.1.0", "pkijs": "^3.2.4", "poseidon-lite": "^0.2.0", - "qrcode.react": "^4.0.1", + "qrcode.react": "^4.1.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-spinners": "^0.14.1", "snarkjs": "^0.7.4", - "socket.io-client": "^4.7.5", + "socket.io-client": "^4.8.1", "uuid": "^10.0.0", "zlib": "^1.0.5" }, diff --git a/sdk/qrcode/tsconfig.json b/sdk/qrcode/tsconfig.json new file mode 100644 index 00000000..2ec7f3cb --- /dev/null +++ b/sdk/qrcode/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "declaration": true, + "declarationDir": "./dist", + "outDir": "./dist", + "strict": false, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "jsx": "react", + "moduleResolution": "node" + }, + "include": [ + "index.ts", + "src/**/*", + "OpenPassportQRcode.tsx", + "common/**/*", + "circuits/**/*", + "circuits/**/*.json", + "utils/utils.ts", + "../../common/src/utils/openPassportAttestation.ts" + ], + "exclude": [ + "node_modules", + "**/__tests__/*", + "dist", + "common/src/utils/csca.ts" + ] +} \ No newline at end of file diff --git a/sdk/tsconfig.react.json b/sdk/qrcode/tsconfig.react.json similarity index 100% rename from sdk/tsconfig.react.json rename to sdk/qrcode/tsconfig.react.json diff --git a/sdk/src/QRcode/utils/styles.ts b/sdk/qrcode/utils/styles.ts similarity index 100% rename from sdk/src/QRcode/utils/styles.ts rename to sdk/qrcode/utils/styles.ts diff --git a/sdk/src/QRcode/utils/utils.ts b/sdk/qrcode/utils/utils.ts similarity index 100% rename from sdk/src/QRcode/utils/utils.ts rename to sdk/qrcode/utils/utils.ts diff --git a/sdk/src/QRcode/utils/websocket.ts b/sdk/qrcode/utils/websocket.ts similarity index 94% rename from sdk/src/QRcode/utils/websocket.ts rename to sdk/qrcode/utils/websocket.ts index 632e2854..29ca0349 100644 --- a/sdk/src/QRcode/utils/websocket.ts +++ b/sdk/qrcode/utils/websocket.ts @@ -1,7 +1,7 @@ import io, { Socket } from 'socket.io-client'; import { QRcodeSteps } from './utils'; -import { OpenPassportVerifier } from '../../OpenPassportVerifier'; -import { OpenPassportAttestation } from '../../../../common/src/utils/openPassportAttestation'; +import { OpenPassportVerifier } from '@openpassport/core'; +import { OpenPassportAttestation } from '@openpassport/core'; const newSocket = (websocketUrl: string, sessionId: string) => io(websocketUrl, { diff --git a/sdk/src/index.ts b/sdk/src/index.ts deleted file mode 100644 index 8426962b..00000000 --- a/sdk/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OpenPassportVerifierReport } from './OpenPassportVerifierReport'; -import { countryCodes } from '../../common/src/constants/constants'; -import { OpenPassportVerifier } from './OpenPassportVerifier'; -import { - OpenPassportAttestation, - OpenPassportDynamicAttestation, -} from '../../common/src/utils/openPassportAttestation'; - -function isBrowser() { - return typeof window !== 'undefined' && typeof window.document !== 'undefined'; -} - -let OpenPassportQRcode; -if (isBrowser()) { - OpenPassportQRcode = require('./QRcode/OpenPassportQRcode').OpenPassportQRcode; -} - -export { - OpenPassportVerifier, - OpenPassportAttestation, - OpenPassportDynamicAttestation, - OpenPassportVerifierReport, - countryCodes, - OpenPassportQRcode, -}; diff --git a/sdk/tests/web-app/src/app/prove/page.tsx b/sdk/tests/web-app/src/app/prove/page.tsx index 27ba7c1d..590f8517 100644 --- a/sdk/tests/web-app/src/app/prove/page.tsx +++ b/sdk/tests/web-app/src/app/prove/page.tsx @@ -1,13 +1,13 @@ 'use client'; -import { OpenPassportQRcode } from '../../../../../src/QRcode/OpenPassportQRcode'; +import OpenPassportQRcode from '../../../../../qrcode/OpenPassportQRcode'; import { v4 as uuidv4 } from 'uuid'; -import { OpenPassportVerifier } from '../../../../../src/OpenPassportVerifier'; +import { OpenPassportVerifier } from '@openpassport/core'; export default function Prove() { const userId = uuidv4(); const scope = 'scope'; - const openPassportVerifier = new OpenPassportVerifier('prove_offchain', scope) + const openPassportVerifier: OpenPassportVerifier = new OpenPassportVerifier('prove_offchain', scope) .excludeCountries('Finland', 'Norway') .allowMockPassports() .setMinimumAge(12);