divide web-sdk in two parts

This commit is contained in:
turnoffthiscomputer
2024-10-27 22:39:06 +01:00
parent a093f3bb84
commit 3c7eb5e1b5
26 changed files with 324 additions and 74 deletions

14
sdk/core/index.ts Normal file
View File

@@ -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,
};

79
sdk/core/package.json Normal file
View File

@@ -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"
}
}

View File

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

View File

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

View File

@@ -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"
]
}

View File

@@ -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 {

View File

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

View File

@@ -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<OpenPassportQRcodeProps> = (props) => {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
if (!isClient) {
return null;
}
return <OpenPassportQRcode {...props} />;
};
// Your existing OpenPassportQRcode component
const OpenPassportQRcode: React.FC<OpenPassportQRcodeProps> = ({
appName,
userId,
@@ -37,7 +53,7 @@ const OpenPassportQRcode: React.FC<OpenPassportQRcodeProps> = ({
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<OpenPassportQRcodeProps> = ({
return <div style={containerStyle}>{renderProofStatus()}</div>;
};
export { OpenPassportQRcode };
export default OpenPassportQRcodeWrapper;

127
sdk/qrcode/README.md Normal file
View File

@@ -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
```

4
sdk/qrcode/index.ts Normal file
View File

@@ -0,0 +1,4 @@
import OpenPassportQRcode from './OpenPassportQRcode';
export { OpenPassportQRcode };

View File

@@ -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"
},

32
sdk/qrcode/tsconfig.json Normal file
View File

@@ -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"
]
}

View File

@@ -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, {

View File

@@ -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,
};

View File

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