mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
SEL-56: Setup Yarn Workspaces (#584)
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,json,yml}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
4
sdk/common/.gitattributes
vendored
4
sdk/common/.gitattributes
vendored
@@ -1,4 +0,0 @@
|
||||
/.yarn/** linguist-vendored
|
||||
/.yarn/releases/* binary
|
||||
/.yarn/plugins/**/* binary
|
||||
/.pnp.* binary linguist-generated
|
||||
13
sdk/common/.gitignore
vendored
13
sdk/common/.gitignore
vendored
@@ -1,13 +0,0 @@
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# Swap the comments on the following lines if you wish to use zero-installs
|
||||
# In that case, don't forget to run `yarn config set enableGlobalCache false`!
|
||||
# Documentation here: https://yarnpkg.com/features/caching#zero-installs
|
||||
|
||||
#!.yarn/cache
|
||||
.pnp.*
|
||||
@@ -1 +0,0 @@
|
||||
# common
|
||||
@@ -1,9 +0,0 @@
|
||||
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA } from "../../common/src/utils/certificate_parsing/dataStructure";
|
||||
import { parseCertificate } from "../../common/src/utils/certificate_parsing/parseCertificate";
|
||||
import { parseCertificateSimple } from "../../common/src/utils/certificate_parsing/parseCertificateSimple";
|
||||
import { findStartPubKeyIndex } from "../../common/src/utils/passports/passport";
|
||||
import { parseDscCertificateData } from "../../common/src/utils/passports/passport_parsing/parseDscCertificateData";
|
||||
import { getLeafCscaTree, getLeafDscTree } from "../../common/src/utils/trees";
|
||||
import { genMockIdDoc } from "../../common/src/utils/passports/genMockIdDoc";
|
||||
|
||||
export { CertificateData, findStartPubKeyIndex, getLeafCscaTree, getLeafDscTree, parseCertificate, parseCertificateSimple, parseDscCertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA, genMockIdDoc };
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"name": "@openpassport/common",
|
||||
"version": "0.0.11",
|
||||
"packageManager": "yarn@4.5.0",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "dist/sdk/common/index.js",
|
||||
"types": "dist/sdk/common/index.d.ts",
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"build:ts": "tsc -b",
|
||||
"copy-certs": "mkdir -p dist && cp -R ../../common/src/mock_certificates ./dist/",
|
||||
"build": "yarn clean && yarn build:ts && yarn copy-certs",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.4",
|
||||
"@openpassport/zk-kit-imt": "^0.0.5",
|
||||
"@openpassport/zk-kit-lean-imt": "^0.0.6",
|
||||
"@openpassport/zk-kit-smt": "^0.0.1",
|
||||
"asn1.js": "^5.4.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
"buffer": "^6.0.3",
|
||||
"chai": "^4.3.8",
|
||||
"country-emoji": "^1.5.6",
|
||||
"country-iso-3-to-2": "^1.1.1",
|
||||
"elliptic": "^6.5.5",
|
||||
"fs": "^0.0.1-security",
|
||||
"i18n-iso-countries": "^7.13.0",
|
||||
"js-sha1": "^0.7.0",
|
||||
"js-sha256": "^0.11.0",
|
||||
"js-sha512": "^0.9.0",
|
||||
"json-to-ts": "^2.1.0",
|
||||
"jsrsasign": "^11.1.0",
|
||||
"mocha": "^10.7.3",
|
||||
"node-forge": "https://github.com/remicolin/forge",
|
||||
"path": "^0.12.7",
|
||||
"pkijs": "^3.2.4",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"snarkjs": "^0.7.5",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"typescript-parser": "^2.6.1",
|
||||
"uuid": "^11.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node-forge": "^1.3.10",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"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",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@common/*": ["../../common/src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"src/**/*",
|
||||
"../../common/src/**/*",
|
||||
"circuits/**/*",
|
||||
"circuits/**/*.json",
|
||||
"utils/utils.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "**/__tests__/*", "dist", "common/src/utils/csca.ts"]
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { SelfBackendVerifier } from './src/SelfBackendVerifier';
|
||||
import { getUserIdentifier } from './src/utils/utils';
|
||||
import { countryCodes } from '../../common/src/constants/constants';
|
||||
import { SelfApp, getUniversalLink, SelfAppBuilder } from '../../common/src/utils/appType';
|
||||
import { countries } from '../../common/src/constants/countries';
|
||||
import { hashEndpointWithScope } from '../../common/src/utils/scope';
|
||||
import { getPackedForbiddenCountries } from '../../common/src/utils/contracts/forbiddenCountries';
|
||||
import { countryCodes } from '@selfxyz/common/constants/constants';
|
||||
import { SelfApp, getUniversalLink, SelfAppBuilder } from '@selfxyz/common/utils/appType';
|
||||
import { countries } from '@selfxyz/common';
|
||||
import { hashEndpointWithScope } from '@selfxyz/common/utils/scope';
|
||||
import { getPackedForbiddenCountries } from '@selfxyz/common/utils/contracts/forbiddenCountries';
|
||||
|
||||
export {
|
||||
SelfBackendVerifier,
|
||||
@@ -15,5 +15,5 @@ export {
|
||||
countries,
|
||||
hashEndpointWithScope,
|
||||
SelfAppBuilder,
|
||||
getPackedForbiddenCountries
|
||||
getPackedForbiddenCountries,
|
||||
};
|
||||
|
||||
@@ -15,23 +15,23 @@
|
||||
"circuits/**/*.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build": "tsc -build",
|
||||
"build:deps": "yarn workspaces foreach --from @selfxyz/core --topological-dev --recursive run build",
|
||||
"types": "yarn build",
|
||||
"copy-abi": "bash scripts/copyAbi.sh",
|
||||
"format": "prettier --write .",
|
||||
"install-sdk": "cd ../common && yarn && cd ../sdk && yarn",
|
||||
"install-sdk": "yarn workspaces focus @selfxyz/core",
|
||||
"lint": "prettier --check .",
|
||||
"prepublishOnly": "npm run build",
|
||||
"publish": "npm publish --access public"
|
||||
"publish": "yarn npm publish --access public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@selfxyz/common": "workspace:^",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"ethers": "^6.13.5",
|
||||
"js-sha1": "^0.7.0",
|
||||
"js-sha256": "^0.11.0",
|
||||
"js-sha512": "^0.9.0",
|
||||
"next": "^14.2.8",
|
||||
"node-forge": "^1.3.1",
|
||||
"poseidon-lite": "^0.3.0",
|
||||
"snarkjs": "^0.7.4",
|
||||
@@ -53,9 +53,6 @@
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
|
||||
@@ -8,19 +8,19 @@ import {
|
||||
} from './constants/contractAddresses';
|
||||
import { ethers } from 'ethers';
|
||||
import { PublicSignals } from 'snarkjs';
|
||||
import type { SelfVerificationResult } from '../../../common/src/utils/selfAttestation';
|
||||
import type { SelfVerificationResult } from '@selfxyz/common/utils/selfAttestation';
|
||||
import { castToUserIdentifier, UserIdType } from '@selfxyz/common/utils/circuits/uuid';
|
||||
import {
|
||||
castToScope,
|
||||
castToUserIdentifier,
|
||||
UserIdType,
|
||||
} from '../../../common/src/utils/circuits/uuid';
|
||||
import { CIRCUIT_CONSTANTS, revealedDataTypes } from '../../../common/src/constants/constants';
|
||||
import { packForbiddenCountriesList } from '../../../common/src/utils/contracts/formatCallData';
|
||||
import { Country3LetterCode, commonNames } from '../../../common/src/constants/countries';
|
||||
import { hashEndpointWithScope } from '../../../common/src/utils/scope';
|
||||
CIRCUIT_CONSTANTS,
|
||||
revealedDataTypes,
|
||||
Country3LetterCode,
|
||||
commonNames,
|
||||
} from '@selfxyz/common';
|
||||
import { packForbiddenCountriesList } from '@selfxyz/common/utils/contracts/formatCallData';
|
||||
import { hashEndpointWithScope } from '@selfxyz/common/utils/scope';
|
||||
|
||||
const CELO_MAINNET_RPC_URL = "https://forno.celo.org";
|
||||
const CELO_TESTNET_RPC_URL = "https://alfajores-forno.celo-testnet.org";
|
||||
const CELO_MAINNET_RPC_URL = 'https://forno.celo.org';
|
||||
const CELO_TESTNET_RPC_URL = 'https://alfajores-forno.celo-testnet.org';
|
||||
|
||||
export class SelfBackendVerifier {
|
||||
protected scope: string;
|
||||
@@ -35,9 +35,9 @@ export class SelfBackendVerifier {
|
||||
enabled: boolean;
|
||||
value: Country3LetterCode;
|
||||
} = {
|
||||
enabled: false,
|
||||
value: '' as Country3LetterCode,
|
||||
};
|
||||
enabled: false,
|
||||
value: '' as Country3LetterCode,
|
||||
};
|
||||
protected minimumAge: { enabled: boolean; value: string } = {
|
||||
enabled: false,
|
||||
value: '18',
|
||||
@@ -46,9 +46,9 @@ export class SelfBackendVerifier {
|
||||
enabled: boolean;
|
||||
value: Country3LetterCode[];
|
||||
} = {
|
||||
enabled: false,
|
||||
value: [],
|
||||
};
|
||||
enabled: false,
|
||||
value: [],
|
||||
};
|
||||
protected passportNoOfac: boolean = false;
|
||||
protected nameAndDobOfac: boolean = false;
|
||||
protected nameAndYobOfac: boolean = false;
|
||||
@@ -140,9 +140,14 @@ export class SelfBackendVerifier {
|
||||
result = await this.verifyAllContract.verifyAll(timestamp, vcAndDiscloseHubProof, types);
|
||||
} catch (error: any) {
|
||||
let errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
|
||||
if (error && typeof error === 'object' && error.message && error.message.includes('INVALID_FORBIDDEN_COUNTRIES')) {
|
||||
errorMessage = 'The forbidden countries list in the backend does not match the list provided in the frontend SDK. Please ensure both lists are identical.';
|
||||
if (
|
||||
error &&
|
||||
typeof error === 'object' &&
|
||||
error.message &&
|
||||
error.message.includes('INVALID_FORBIDDEN_COUNTRIES')
|
||||
) {
|
||||
errorMessage =
|
||||
'The forbidden countries list in the backend does not match the list provided in the frontend SDK. Please ensure both lists are identical.';
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -233,7 +238,7 @@ export class SelfBackendVerifier {
|
||||
/**
|
||||
* Sets the list of countries to be excluded in the verification.
|
||||
* This list must exactly match the list configured in the backend.
|
||||
*
|
||||
*
|
||||
* @param countries Array of 3-letter country codes to exclude
|
||||
* @returns This instance for method chaining
|
||||
* @throws Error if more than 40 countries are provided or if any country code is invalid
|
||||
@@ -242,23 +247,23 @@ export class SelfBackendVerifier {
|
||||
if (countries.length > 40) {
|
||||
throw new Error('Number of excluded countries cannot exceed 40');
|
||||
}
|
||||
|
||||
// Validate country codes
|
||||
for (const country of countries) {
|
||||
if (!country || country.length !== 3) {
|
||||
throw new Error(`Invalid country code: "${country}". Country codes must be exactly 3 characters long.`);
|
||||
throw new Error(
|
||||
`Invalid country code: "${country}". Country codes must be exactly 3 characters long.`
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the country code exists in the list of valid codes (additional check)
|
||||
const isValidCountry = Object.values(commonNames).some(
|
||||
name => name === country || country in commonNames
|
||||
(name) => name === country || country in commonNames
|
||||
);
|
||||
|
||||
if (!isValidCountry) {
|
||||
throw new Error(`Unknown country code: "${country}". Please use valid 3-letter ISO country codes.`);
|
||||
throw new Error(
|
||||
`Unknown country code: "${country}". Please use valid 3-letter ISO country codes.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.excludedCountries = { enabled: true, value: countries };
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CIRCUIT_CONSTANTS } from '../../../../common/src/constants/constants';
|
||||
import { castToUserIdentifier, UserIdType } from '../../../../common/src/utils/circuits/uuid';
|
||||
import { CIRCUIT_CONSTANTS } from '@selfxyz/common';
|
||||
import { castToUserIdentifier, UserIdType } from '@selfxyz/common/utils/circuits/uuid';
|
||||
import { BigNumberish } from 'ethers';
|
||||
import { PublicSignals } from 'snarkjs';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"module": "NodeNext",
|
||||
"declaration": true,
|
||||
"declarationDir": "./dist",
|
||||
"outDir": "./dist",
|
||||
@@ -10,20 +10,9 @@
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"jsx": "react",
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@common/*": ["../../common/src/*"]
|
||||
}
|
||||
"moduleResolution": "node16",
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"src/**/*",
|
||||
"../../common/src/**/*",
|
||||
"circuits/**/*",
|
||||
"circuits/**/*.json",
|
||||
"utils/utils.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "**/__tests__/*", "dist", "common/src/utils/csca.ts"]
|
||||
"include": ["index.ts", "src/**/*", "circuits/**/*", "circuits/**/*.json", "utils/utils.ts"],
|
||||
"exclude": ["node_modules", "**/__tests__/*", "dist"]
|
||||
}
|
||||
|
||||
6
sdk/qrcode/.prettierignore
Normal file
6
sdk/qrcode/.prettierignore
Normal file
@@ -0,0 +1,6 @@
|
||||
dist
|
||||
node_modules
|
||||
.yarn/**
|
||||
|
||||
|
||||
*.json
|
||||
11
sdk/qrcode/.prettierrc
Normal file
11
sdk/qrcode/.prettierrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": false,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
26
sdk/qrcode/.size-limit.json
Normal file
26
sdk/qrcode/.size-limit.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"path": "./dist/index.js",
|
||||
"name": "import SelfQRcodeWrapper from '@selfxyz/qrcode'",
|
||||
"import": "{ default }",
|
||||
"limit": "800 ms"
|
||||
},
|
||||
{
|
||||
"path": "./dist/index.js",
|
||||
"name": "import { SelfAppBuilder } from '@selfxyz/qrcode'",
|
||||
"import": "{ SelfAppBuilder }",
|
||||
"limit": "800 ms"
|
||||
},
|
||||
{
|
||||
"path": "./dist/index.js",
|
||||
"name": "import { SelfQRcode } from '@selfxyz/qrcode'",
|
||||
"import": "{ SelfQRcode }",
|
||||
"limit": "800 ms"
|
||||
},
|
||||
{
|
||||
"path": "./dist/index.js",
|
||||
"name": "import { countries } from '@selfxyz/qrcode'",
|
||||
"import": "{ countries }",
|
||||
"limit": "800 ms"
|
||||
}
|
||||
]
|
||||
@@ -27,10 +27,10 @@ const userId = uuidv4();
|
||||
|
||||
// Create a SelfApp instance using the builder pattern
|
||||
const selfApp = new SelfAppBuilder({
|
||||
appName: "My App",
|
||||
scope: "my-app-scope",
|
||||
endpoint: "https://myapp.com/api/verify",
|
||||
logoBase64: "base64EncodedLogo", // Optional
|
||||
appName: 'My App',
|
||||
scope: 'my-app-scope',
|
||||
endpoint: 'https://myapp.com/api/verify',
|
||||
logoBase64: 'base64EncodedLogo', // Optional
|
||||
userId,
|
||||
// Optional disclosure requirements
|
||||
disclosures: {
|
||||
@@ -44,7 +44,7 @@ const selfApp = new SelfAppBuilder({
|
||||
expiry_date: true,
|
||||
// Custom verification rules
|
||||
minimumAge: 18,
|
||||
excludedCountries: ["IRN", "PRK"],
|
||||
excludedCountries: ['IRN', 'PRK'],
|
||||
ofac: true,
|
||||
},
|
||||
}).build();
|
||||
@@ -74,44 +74,44 @@ function MyComponent() {
|
||||
|
||||
The `SelfAppBuilder` allows you to configure your application's verification requirements:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `appName` | string | Yes | The name of your application |
|
||||
| `scope` | string | Yes | A unique identifier for your application |
|
||||
| `endpoint` | string | Yes | The endpoint that will verify the proof |
|
||||
| `logoBase64` | string | No | Base64-encoded logo to display in the Self app |
|
||||
| `userId` | string | Yes | Unique identifier for the user |
|
||||
| `disclosures` | object | No | Disclosure and verification requirements |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ---------------------------------------------- |
|
||||
| `appName` | string | Yes | The name of your application |
|
||||
| `scope` | string | Yes | A unique identifier for your application |
|
||||
| `endpoint` | string | Yes | The endpoint that will verify the proof |
|
||||
| `logoBase64` | string | No | Base64-encoded logo to display in the Self app |
|
||||
| `userId` | string | Yes | Unique identifier for the user |
|
||||
| `disclosures` | object | No | Disclosure and verification requirements |
|
||||
|
||||
### Disclosure Options
|
||||
|
||||
The `disclosures` object can include the following options:
|
||||
|
||||
| Option | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `issuing_state` | boolean | Request disclosure of passport issuing state |
|
||||
| `name` | boolean | Request disclosure of the user's name |
|
||||
| `nationality` | boolean | Request disclosure of nationality |
|
||||
| `date_of_birth` | boolean | Request disclosure of birth date |
|
||||
| `passport_number` | boolean | Request disclosure of passport number |
|
||||
| `gender` | boolean | Request disclosure of gender |
|
||||
| `expiry_date` | boolean | Request disclosure of passport expiry date |
|
||||
| `minimumAge` | number | Verify the user is at least this age |
|
||||
| `excludedCountries` | string[] | Array of country codes to exclude |
|
||||
| `ofac` | boolean | Enable OFAC compliance check |
|
||||
| Option | Type | Description |
|
||||
| ------------------- | -------- | -------------------------------------------- |
|
||||
| `issuing_state` | boolean | Request disclosure of passport issuing state |
|
||||
| `name` | boolean | Request disclosure of the user's name |
|
||||
| `nationality` | boolean | Request disclosure of nationality |
|
||||
| `date_of_birth` | boolean | Request disclosure of birth date |
|
||||
| `passport_number` | boolean | Request disclosure of passport number |
|
||||
| `gender` | boolean | Request disclosure of gender |
|
||||
| `expiry_date` | boolean | Request disclosure of passport expiry date |
|
||||
| `minimumAge` | number | Verify the user is at least this age |
|
||||
| `excludedCountries` | string[] | Array of country codes to exclude |
|
||||
| `ofac` | boolean | Enable OFAC compliance check |
|
||||
|
||||
## Component Props
|
||||
|
||||
The `SelfQRcodeWrapper` component accepts the following props:
|
||||
|
||||
| Prop | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `selfApp` | SelfApp | Yes | - | The SelfApp configuration object |
|
||||
| `onSuccess` | () => void | Yes | - | Callback function executed on successful verification |
|
||||
| `websocketUrl` | string | No | WS_DB_RELAYER | Custom WebSocket URL for verification |
|
||||
| `size` | number | No | 300 | QR code size in pixels |
|
||||
| `darkMode` | boolean | No | false | Enable dark mode styling |
|
||||
| `children` | React.ReactNode | No | - | Custom children to render |
|
||||
| Prop | Type | Required | Default | Description |
|
||||
| -------------- | --------------- | -------- | ------------- | ----------------------------------------------------- |
|
||||
| `selfApp` | SelfApp | Yes | - | The SelfApp configuration object |
|
||||
| `onSuccess` | () => void | Yes | - | Callback function executed on successful verification |
|
||||
| `websocketUrl` | string | No | WS_DB_RELAYER | Custom WebSocket URL for verification |
|
||||
| `size` | number | No | 300 | QR code size in pixels |
|
||||
| `darkMode` | boolean | No | false | Enable dark mode styling |
|
||||
| `children` | React.ReactNode | No | - | Custom children to render |
|
||||
|
||||
## Complete Example
|
||||
|
||||
@@ -136,19 +136,19 @@ function VerificationPage() {
|
||||
|
||||
// Create the SelfApp configuration
|
||||
const selfApp = new SelfAppBuilder({
|
||||
appName: "My Application",
|
||||
scope: "my-application-scope",
|
||||
endpoint: "https://myapp.com/api/verify",
|
||||
appName: 'My Application',
|
||||
scope: 'my-application-scope',
|
||||
endpoint: 'https://myapp.com/api/verify',
|
||||
userId,
|
||||
disclosures: {
|
||||
// Request passport information
|
||||
name: true,
|
||||
nationality: true,
|
||||
date_of_birth: true,
|
||||
|
||||
|
||||
// Set verification rules
|
||||
minimumAge: 18,
|
||||
excludedCountries: ["IRN", "PRK", "RUS"],
|
||||
excludedCountries: ['IRN', 'PRK', 'RUS'],
|
||||
ofac: true,
|
||||
},
|
||||
}).build();
|
||||
@@ -157,17 +157,17 @@ function VerificationPage() {
|
||||
<div className="verification-container">
|
||||
<h1>Verify Your Identity</h1>
|
||||
<p>Scan this QR code with the Self app to verify your identity</p>
|
||||
|
||||
|
||||
<SelfQRcodeWrapper
|
||||
selfApp={selfApp}
|
||||
onSuccess={() => {
|
||||
// Handle successful verification
|
||||
console.log("Verification successful!");
|
||||
console.log('Verification successful!');
|
||||
// Redirect or update UI
|
||||
}}
|
||||
size={350}
|
||||
/>
|
||||
|
||||
|
||||
<p className="text-sm text-gray-500">
|
||||
User ID: {userId.substring(0, 8)}...
|
||||
</p>
|
||||
@@ -190,4 +190,4 @@ For a more comprehensive and interactive example, please refer to the [playgroun
|
||||
4. The proof is generated and sent to your verification endpoint
|
||||
5. Upon successful verification, the `onSuccess` callback is triggered
|
||||
|
||||
The QR code component displays the current verification status with an LED indicator and changes its appearance based on the verification state.
|
||||
The QR code component displays the current verification status with an LED indicator and changes its appearance based on the verification state.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { QRcodeSteps } from '../utils/utils';
|
||||
import { QRcodeSteps } from '../utils/utils.js';
|
||||
interface LEDProps {
|
||||
size?: number;
|
||||
connectionStatus?: number;
|
||||
@@ -9,7 +9,10 @@ const green = '#31F040';
|
||||
const blue = '#424AD8';
|
||||
const gray = '#95a5a6';
|
||||
|
||||
const LED: React.FC<LEDProps> = ({ size = 8, connectionStatus = QRcodeSteps.DISCONNECTED }) => {
|
||||
const LED: React.FC<LEDProps> = ({
|
||||
size = 8,
|
||||
connectionStatus = QRcodeSteps.DISCONNECTED,
|
||||
}) => {
|
||||
const getColor = () => {
|
||||
if (connectionStatus >= QRcodeSteps.MOBILE_CONNECTED) {
|
||||
return green;
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
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 { REDIRECT_URL, WS_DB_RELAYER } from '../../common/src/constants/constants';
|
||||
import CHECK_ANIMATION from '../animations/check_animation.json';
|
||||
import X_ANIMATION from '../animations/x_animation.json';
|
||||
import LED from './LED.js';
|
||||
import {
|
||||
REDIRECT_URL,
|
||||
WS_DB_RELAYER,
|
||||
} from '@selfxyz/common/constants/constants';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { QRcodeSteps } from './utils/utils';
|
||||
import { containerStyle, ledContainerStyle, qrContainerStyle } from './utils/styles';
|
||||
import { QRcodeSteps } from '../utils/utils.js';
|
||||
import {
|
||||
containerStyle,
|
||||
ledContainerStyle,
|
||||
qrContainerStyle,
|
||||
} from '../utils/styles.js';
|
||||
import { QRCodeSVG } from 'qrcode.react';
|
||||
import { initWebSocket } from './utils/websocket';
|
||||
import { getUniversalLink, SelfApp, SelfAppBuilder } from '../../common/src/utils/appType';
|
||||
|
||||
import { initWebSocket } from '../utils/websocket.js';
|
||||
import {
|
||||
getUniversalLink,
|
||||
SelfApp,
|
||||
SelfAppBuilder,
|
||||
} from '@selfxyz/common/utils/appType';
|
||||
interface SelfQRcodeProps {
|
||||
selfApp: SelfApp;
|
||||
onSuccess: () => void;
|
||||
onError: (data: {error_code?: string, reason?: string}) => void;
|
||||
onError: (data: { error_code?: string; reason?: string }) => void;
|
||||
type?: 'websocket' | 'deeplink';
|
||||
websocketUrl?: string;
|
||||
size?: number;
|
||||
@@ -60,7 +70,7 @@ const SelfQRcode = ({
|
||||
websocketUrl,
|
||||
{
|
||||
...selfApp,
|
||||
sessionId: sessionId
|
||||
sessionId: sessionId,
|
||||
},
|
||||
type,
|
||||
setProofStep,
|
||||
@@ -95,7 +105,7 @@ const SelfQRcode = ({
|
||||
return <BounceLoader loading={true} size={200} color="#94FBAB" />;
|
||||
case QRcodeSteps.PROOF_GENERATION_FAILED:
|
||||
return (
|
||||
<Lottie
|
||||
<Lottie.default
|
||||
animationData={X_ANIMATION}
|
||||
style={{ width: 200, height: 200 }}
|
||||
onComplete={() => {
|
||||
@@ -106,7 +116,7 @@ const SelfQRcode = ({
|
||||
);
|
||||
case QRcodeSteps.PROOF_VERIFIED:
|
||||
return (
|
||||
<Lottie
|
||||
<Lottie.default
|
||||
animationData={CHECK_ANIMATION}
|
||||
style={{ width: 200, height: 200 }}
|
||||
onComplete={() => {
|
||||
@@ -118,10 +128,14 @@ const SelfQRcode = ({
|
||||
default:
|
||||
return (
|
||||
<QRCodeSVG
|
||||
value={type === 'websocket' ? `${REDIRECT_URL}?sessionId=${sessionId}` : getUniversalLink({
|
||||
...selfApp,
|
||||
sessionId: sessionId
|
||||
})}
|
||||
value={
|
||||
type === 'websocket'
|
||||
? `${REDIRECT_URL}?sessionId=${sessionId}`
|
||||
: getUniversalLink({
|
||||
...selfApp,
|
||||
sessionId: sessionId,
|
||||
})
|
||||
}
|
||||
size={size}
|
||||
bgColor={darkMode ? '#000000' : '#ffffff'}
|
||||
fgColor={darkMode ? '#ffffff' : '#000000'}
|
||||
@@ -139,4 +153,4 @@ const SelfQRcode = ({
|
||||
export default SelfQRcodeWrapper;
|
||||
|
||||
// Also export other components/types that might be needed
|
||||
export { SelfQRcode, SelfApp, SelfAppBuilder };
|
||||
export { SelfQRcode, SelfApp, SelfAppBuilder };
|
||||
@@ -1,8 +1,12 @@
|
||||
import SelfQRcodeWrapper, { SelfQRcode, SelfApp, SelfAppBuilder } from './SelfQRcode';
|
||||
import { WebAppInfo } from './utils/websocket';
|
||||
import { countries } from '../../common/src/constants/countries';
|
||||
import SelfQRcodeWrapper, {
|
||||
SelfQRcode,
|
||||
SelfApp,
|
||||
SelfAppBuilder,
|
||||
} from './components/SelfQRcode.js';
|
||||
import { WebAppInfo } from './utils/websocket.js';
|
||||
import { countries } from '@selfxyz/common/constants/countries';
|
||||
|
||||
export default SelfQRcodeWrapper;
|
||||
export { SelfQRcode, SelfApp, SelfAppBuilder, countries };
|
||||
export { SelfQRcodeWrapper, SelfQRcode, SelfApp, SelfAppBuilder, countries };
|
||||
|
||||
export type { WebAppInfo };
|
||||
|
||||
@@ -7,46 +7,51 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "turnoffthiscomputer",
|
||||
"main": "dist/sdk/qrcode/index.js",
|
||||
"types": "dist/sdk/qrcode/index.d.ts",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./dist/index.js"
|
||||
},
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"common",
|
||||
"circuits/**/*.json",
|
||||
"src/QRcode"
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build": "tsc --build",
|
||||
"build:deps": "yarn workspaces foreach --from @selfxyz/qrcode --topological-dev --recursive run build",
|
||||
"types": "yarn build",
|
||||
"format": "prettier --write .",
|
||||
"install-sdk": "cd ../common && yarn && cd ../sdk && yarn",
|
||||
"install-sdk": "yarn workspace focus @selfxyz/qrcode",
|
||||
"lint": "prettier --check .",
|
||||
"prepublishOnly": "npm run build",
|
||||
"test": "yarn ts-mocha -p ./tsconfig.json tests/openPassportVerifier.test.ts --exit",
|
||||
"publish": "npm publish --access public"
|
||||
"prepublishOnly": "yarn build",
|
||||
"test": "echo 'no tests found'",
|
||||
"publish": "yarn npm publish --access public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@selfxyz/common": "workspace:^",
|
||||
"js-sha1": "^0.7.0",
|
||||
"js-sha256": "^0.11.0",
|
||||
"js-sha512": "^0.9.0",
|
||||
"lottie-react": "^2.4.0",
|
||||
"next": "^14.2.8",
|
||||
"node-forge": "^1.3.1",
|
||||
"poseidon-lite": "^0.3.0",
|
||||
"qrcode.react": "^4.1.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-spinners": "^0.14.1",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@size-limit/preset-big-lib": "^11.2.0",
|
||||
"@types/node": "^20.11.19",
|
||||
"@types/node-forge": "^1",
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"mocha": "^10.3.0",
|
||||
"prettier": "^3.3.3",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"size-limit": "^11.2.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"ts-node": "^10.9.2",
|
||||
@@ -60,4 +65,4 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"module": "Node16",
|
||||
"declaration": true,
|
||||
"declarationDir": "./dist",
|
||||
"outDir": "./dist",
|
||||
@@ -11,22 +11,17 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"jsx": "react",
|
||||
"moduleResolution": "node"
|
||||
"moduleResolution": "node16"
|
||||
},
|
||||
"include": [
|
||||
"animations",
|
||||
"index.ts",
|
||||
"src/**/*",
|
||||
"SelfQRcode.tsx",
|
||||
"common/**/*",
|
||||
"circuits/**/*",
|
||||
"circuits/**/*.json",
|
||||
"utils/utils.ts",
|
||||
"../../common/src/utils/openPassportAttestation.ts"
|
||||
"components/**.tsx",
|
||||
"utils/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/__tests__/*",
|
||||
"dist",
|
||||
"common/src/utils/csca.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import io, { Socket } from 'socket.io-client';
|
||||
import { QRcodeSteps } from './utils';
|
||||
import { SelfApp } from '../../../common/src/utils/appType';
|
||||
import { QRcodeSteps } from './utils.js';
|
||||
import { SelfApp } from '@selfxyz/common/utils/appType';
|
||||
|
||||
export interface WebAppInfo {
|
||||
appName: string;
|
||||
userId: string;
|
||||
logoBase64: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Log once when this module loads
|
||||
console.log('[WebSocket] Initializing websocket module.');
|
||||
|
||||
const newSocket = (websocketUrl: string, sessionId: string) => {
|
||||
const fullUrl = `${websocketUrl}/websocket`;
|
||||
console.log(`[WebSocket] Creating new socket. URL: ${fullUrl}, sessionId: ${sessionId}`);
|
||||
console.log(
|
||||
`[WebSocket] Creating new socket. URL: ${fullUrl}, sessionId: ${sessionId}`,
|
||||
);
|
||||
return io(fullUrl, {
|
||||
path: '/',
|
||||
query: { sessionId, clientType: 'web' },
|
||||
@@ -29,46 +31,54 @@ const handleWebSocketMessage =
|
||||
type: 'websocket' | 'deeplink',
|
||||
setProofStep: (step: number) => void,
|
||||
onSuccess: () => void,
|
||||
onError: (data: {error_code?: string, reason?: string}) => void
|
||||
onError: (data: { error_code?: string; reason?: string }) => void,
|
||||
) =>
|
||||
async (data: any) => {
|
||||
console.log('[WebSocket] Received mobile status:', data.status, 'for session:', sessionId);
|
||||
switch (data.status) {
|
||||
case 'mobile_connected':
|
||||
console.log('[WebSocket] Mobile device connected. Emitting self_app event with payload:', selfApp);
|
||||
setProofStep(QRcodeSteps.MOBILE_CONNECTED);
|
||||
if (type === 'websocket') {
|
||||
socket.emit('self_app', { ...selfApp, sessionId });
|
||||
}
|
||||
break;
|
||||
case 'mobile_disconnected':
|
||||
console.log('[WebSocket] Mobile device disconnected.');
|
||||
setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
|
||||
break;
|
||||
case 'proof_generation_started':
|
||||
console.log('[WebSocket] Proof generation started.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_STARTED);
|
||||
break;
|
||||
case 'proof_generated':
|
||||
console.log('[WebSocket] Proof generated.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATED);
|
||||
break;
|
||||
case 'proof_generation_failed':
|
||||
console.log('[WebSocket] Proof generation failed.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_FAILED);
|
||||
onError(data);
|
||||
break;
|
||||
case 'proof_verified':
|
||||
console.log('[WebSocket] Proof verified.');
|
||||
console.log('ws data', data);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
onSuccess();
|
||||
break;
|
||||
default:
|
||||
console.log('[WebSocket] Unhandled mobile status:', data.status);
|
||||
break;
|
||||
}
|
||||
};
|
||||
async (data: any) => {
|
||||
console.log(
|
||||
'[WebSocket] Received mobile status:',
|
||||
data.status,
|
||||
'for session:',
|
||||
sessionId,
|
||||
);
|
||||
switch (data.status) {
|
||||
case 'mobile_connected':
|
||||
console.log(
|
||||
'[WebSocket] Mobile device connected. Emitting self_app event with payload:',
|
||||
selfApp,
|
||||
);
|
||||
setProofStep(QRcodeSteps.MOBILE_CONNECTED);
|
||||
if (type === 'websocket') {
|
||||
socket.emit('self_app', { ...selfApp, sessionId });
|
||||
}
|
||||
break;
|
||||
case 'mobile_disconnected':
|
||||
console.log('[WebSocket] Mobile device disconnected.');
|
||||
setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
|
||||
break;
|
||||
case 'proof_generation_started':
|
||||
console.log('[WebSocket] Proof generation started.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_STARTED);
|
||||
break;
|
||||
case 'proof_generated':
|
||||
console.log('[WebSocket] Proof generated.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATED);
|
||||
break;
|
||||
case 'proof_generation_failed':
|
||||
console.log('[WebSocket] Proof generation failed.');
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_FAILED);
|
||||
onError(data);
|
||||
break;
|
||||
case 'proof_verified':
|
||||
console.log('[WebSocket] Proof verified.');
|
||||
console.log('ws data', data);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
onSuccess();
|
||||
break;
|
||||
default:
|
||||
console.log('[WebSocket] Unhandled mobile status:', data.status);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
export function initWebSocket(
|
||||
websocketUrl: string,
|
||||
@@ -76,21 +86,25 @@ export function initWebSocket(
|
||||
type: 'websocket' | 'deeplink',
|
||||
setProofStep: (step: number) => void,
|
||||
onSuccess: () => void,
|
||||
onError: (data: {error_code?: string, reason?: string}) => void,
|
||||
onError: (data: { error_code?: string; reason?: string }) => void,
|
||||
) {
|
||||
const sessionId = selfApp.sessionId;
|
||||
console.log(`[WebSocket] Initializing WebSocket connection for sessionId: ${sessionId}`);
|
||||
console.log(
|
||||
`[WebSocket] Initializing WebSocket connection for sessionId: ${sessionId}`,
|
||||
);
|
||||
const socket = newSocket(websocketUrl, sessionId);
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log(`[WebSocket] Connected with id: ${socket.id}, transport: ${socket.io.engine.transport.name}`);
|
||||
console.log(
|
||||
`[WebSocket] Connected with id: ${socket.id}, transport: ${socket.io.engine.transport.name}`,
|
||||
);
|
||||
});
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
socket.on('connect_error', error => {
|
||||
console.error('[WebSocket] Connection error:', error);
|
||||
});
|
||||
|
||||
socket.on('mobile_status', (data) => {
|
||||
socket.on('mobile_status', data => {
|
||||
console.log('[WebSocket] Raw mobile_status event received:', data);
|
||||
handleWebSocketMessage(
|
||||
socket,
|
||||
@@ -99,16 +113,20 @@ export function initWebSocket(
|
||||
type,
|
||||
setProofStep,
|
||||
onSuccess,
|
||||
onError
|
||||
onError,
|
||||
)(data);
|
||||
});
|
||||
|
||||
socket.on('disconnect', (reason: string) => {
|
||||
console.log(`[WebSocket] Disconnected. Reason: ${reason}, Last transport: ${socket.io.engine.transport?.name}`);
|
||||
console.log(
|
||||
`[WebSocket] Disconnected. Reason: ${reason}, Last transport: ${socket.io.engine.transport?.name}`,
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log(`[WebSocket] Cleaning up connection for sessionId: ${sessionId}`);
|
||||
console.log(
|
||||
`[WebSocket] Cleaning up connection for sessionId: ${sessionId}`,
|
||||
);
|
||||
if (socket) {
|
||||
socket.disconnect();
|
||||
}
|
||||
|
||||
2289
sdk/qrcode/yarn.lock
2289
sdk/qrcode/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,16 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"dev": "bun run --watch src/app.ts",
|
||||
"types": "tsc --noEmit",
|
||||
"init": "bash scripts/copy_abi.sh && bash scripts/copy_deployedAddress.sh",
|
||||
"start:daemon": "bun run src/app.ts > app.log 2>&1 &",
|
||||
"stop:daemon": "pkill -f 'bun run src/app.ts'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/swagger": "^1.2.0",
|
||||
"@selfxyz/core": "^0.0.3",
|
||||
"@openpassport/zk-kit-imt": "^0.0.5",
|
||||
"@openpassport/zk-kit-lean-imt": "^0.0.6",
|
||||
"@selfxyz/core": "^0.0.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"elysia": "latest",
|
||||
"logixlysia": "^4.1.1",
|
||||
@@ -24,7 +25,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/pg": "^8.11.11",
|
||||
"bun-types": "latest"
|
||||
"bun-types": "latest",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"module": "index.ts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Elysia, { t } from 'elysia';
|
||||
// import { SelfBackendVerifier } from "@selfxyz/core";
|
||||
import { SelfBackendVerifier } from "../../../../../core/src/SelfBackendVerifier";
|
||||
import { SelfBackendVerifier } from "@selfxyz/core";
|
||||
|
||||
export const ContractsController = new Elysia()
|
||||
.post(
|
||||
@@ -51,4 +50,3 @@ export const ContractsController = new Elysia()
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2021",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "node",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "nodenext",
|
||||
"types": [
|
||||
"bun-types"
|
||||
],
|
||||
@@ -12,4 +12,4 @@
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import { expect } from 'chai';
|
||||
import { describe, it } from 'mocha';
|
||||
import { groth16 } from 'snarkjs';
|
||||
import { genAndInitMockPassportData } from '../../common/src/utils/genMockPassportData';
|
||||
import {
|
||||
buildAttestation,
|
||||
OpenPassportDynamicAttestation,
|
||||
} from '../../common/src/utils/openPassportAttestation';
|
||||
import { OpenPassportVerifier } from '../src/OpenPassportVerifier';
|
||||
import { OpenPassportVerifierReport } from '../src/OpenPassportVerifierReport';
|
||||
import { generateCircuitInputsInSdk } from './utils/generateInputsInSdk';
|
||||
import {
|
||||
alphaCode,
|
||||
dateOfBirth,
|
||||
dateOfExpiry,
|
||||
getCountryName,
|
||||
majority,
|
||||
scope,
|
||||
TestCase,
|
||||
testCases,
|
||||
} from './utils/testCases';
|
||||
|
||||
const runTest = async (testCase: TestCase) => {
|
||||
const { circuitType, algorithm, wasmPath, zkeyPath } = testCase;
|
||||
const passportData = genAndInitMockPassportData(algorithm, alphaCode, dateOfBirth, dateOfExpiry);
|
||||
const inputs = generateCircuitInputsInSdk(passportData, circuitType);
|
||||
const { proof, publicSignals } = await groth16.fullProve(inputs, wasmPath, zkeyPath);
|
||||
const openPassportVerifier = new OpenPassportVerifier({
|
||||
scope: scope,
|
||||
olderThan: majority,
|
||||
nationality: getCountryName(),
|
||||
dev_mode: true,
|
||||
circuit: circuitType,
|
||||
});
|
||||
|
||||
const attestation = buildAttestation({
|
||||
proof: proof as any,
|
||||
publicSignals: publicSignals,
|
||||
dsc: passportData.dsc as string,
|
||||
});
|
||||
console.log('\x1b[34mattestation: \x1b[0m', attestation);
|
||||
|
||||
const result = await openPassportVerifier.verify(attestation);
|
||||
return { result, attestation };
|
||||
};
|
||||
|
||||
const verifyResult = (
|
||||
result: OpenPassportVerifierReport,
|
||||
attestation: OpenPassportDynamicAttestation
|
||||
) => {
|
||||
if (!result.valid) {
|
||||
console.log(result);
|
||||
}
|
||||
console.log('\x1b[34mnullifier: \x1b[0m', attestation.getNullifier());
|
||||
expect(result.valid).to.be.true;
|
||||
};
|
||||
|
||||
describe('\x1b[35mOpenPassportVerifier\x1b[0m', function () {
|
||||
this.timeout(0);
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
const { circuitType, algorithm } = testCase;
|
||||
it(`${circuitType} - ${algorithm}`, async function () {
|
||||
const { result, attestation } = await runTest(testCase);
|
||||
verifyResult(result, attestation);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import { CircuitName } from '../../../common/src/utils/appType';
|
||||
import { k_dsc, n_dsc, PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
import { generateCircuitInputsProve } from '../../../common/src/utils/generateInputs';
|
||||
import { majority, scope } from './testCases';
|
||||
|
||||
|
||||
export const generateCircuitInputsInSdk = (
|
||||
passportData: PassportData,
|
||||
circuit: CircuitName
|
||||
): any => {
|
||||
switch (circuit) {
|
||||
case 'prove':
|
||||
const selector_dg1 = Array(88).fill('1');
|
||||
const selector_older_than = 1;
|
||||
const selector_mode = 0;
|
||||
const secret = 0;
|
||||
const dsc_secret = 0;
|
||||
// import missing
|
||||
const user_identifier = crypto.randomUUID();
|
||||
return generateCircuitInputsProve(
|
||||
selector_mode,
|
||||
secret,
|
||||
dsc_secret,
|
||||
passportData,
|
||||
scope,
|
||||
selector_dg1,
|
||||
selector_older_than,
|
||||
majority,
|
||||
user_identifier
|
||||
);
|
||||
default:
|
||||
throw new Error('Invalid circuit');
|
||||
}
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import { countryCodes, DEFAULT_MAJORITY } from '../../../common/src/constants/constants';
|
||||
|
||||
type CircuitType = 'prove';
|
||||
type AlgorithmType = 'rsa_sha256' | 'rsa_sha1' | 'rsapss_sha256';
|
||||
|
||||
export const scope = '@spaceShips';
|
||||
export const majority = DEFAULT_MAJORITY;
|
||||
export const alphaCode = 'FRA';
|
||||
export const dateOfBirth = '000101';
|
||||
export const dateOfExpiry = '300101';
|
||||
export const getCountryName = () => {
|
||||
const countryName = countryCodes[alphaCode as keyof typeof countryCodes];
|
||||
if (!countryName) {
|
||||
throw new Error(`Country name not found for alpha code: ${alphaCode}`);
|
||||
}
|
||||
return countryName;
|
||||
};
|
||||
|
||||
export interface TestCase {
|
||||
circuitType: CircuitType;
|
||||
algorithm: AlgorithmType;
|
||||
wasmPath: string;
|
||||
zkeyPath: string;
|
||||
}
|
||||
|
||||
export const testCases: TestCase[] = [
|
||||
{
|
||||
circuitType: 'prove',
|
||||
algorithm: 'rsa_sha256',
|
||||
wasmPath: '../circuits/build/fromAWS/prove_rsa_65537_sha256.wasm',
|
||||
zkeyPath: '../circuits/build/fromAWS/prove_rsa_65537_sha256.zkey',
|
||||
},
|
||||
{
|
||||
circuitType: 'prove',
|
||||
algorithm: 'rsa_sha1',
|
||||
wasmPath: '../circuits/build/fromAWS/prove_rsa_65537_sha1.wasm',
|
||||
zkeyPath: '../circuits/build/fromAWS/prove_rsa_65537_sha1.zkey',
|
||||
},
|
||||
{
|
||||
circuitType: 'prove',
|
||||
algorithm: 'rsapss_sha256',
|
||||
wasmPath: '../circuits/build/fromAWS/prove_rsapss_65537_sha256.wasm',
|
||||
zkeyPath: '../circuits/build/fromAWS/prove_rsapss_65537_sha256.zkey',
|
||||
},
|
||||
];
|
||||
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"name": "web-app",
|
||||
"name": "test-web-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"types": "yarn build",
|
||||
"dev": "next dev",
|
||||
"lint": "next lint",
|
||||
"start": "next start"
|
||||
@@ -12,6 +14,8 @@
|
||||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@mui/material": "^6.0.2",
|
||||
"@selfxyz/common": "workspace:^",
|
||||
"@selfxyz/qrcode": "workspace:^",
|
||||
"axios": "^1.7.7",
|
||||
"next": "14.2.8",
|
||||
"react": "^18",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SelfBackendVerifier } from '../../../../../../core';
|
||||
import { SelfBackendVerifier } from '@selfxyz/core';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { countries } from '../../../../../../../common/src/constants/countries';
|
||||
import { count } from 'console';
|
||||
import { countries } from '@selfxyz/common/constants/countries';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
@@ -19,7 +18,6 @@ export async function POST(request: Request) {
|
||||
'https://forno.celo.org',
|
||||
"self-workshop",
|
||||
'uuid',
|
||||
false
|
||||
)
|
||||
.setMinimumAge(18)
|
||||
.excludeCountries(
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import { SelfAppBuilder } from '../../../../../qrcode/SelfQRcode';
|
||||
import SelfQRcodeWrapper from '../../../../../qrcode/SelfQRcode';
|
||||
import SelfQRcodeWrapper, { SelfAppBuilder } from '@selfxyz/qrcode';
|
||||
import { v4 } from 'uuid';
|
||||
import {logo} from './logo';
|
||||
|
||||
export default function Prove() {
|
||||
const userId = v4();
|
||||
|
||||
|
||||
const selfApp = new SelfAppBuilder({
|
||||
appName: "Mock App2",
|
||||
scope: "test-scope",
|
||||
@@ -36,6 +35,7 @@ export default function Prove() {
|
||||
onSuccess={() => {
|
||||
window.location.href = '/success';
|
||||
}}
|
||||
onError={console.error}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { SelfAppBuilder } from '../../../../qrcode/SelfQRcode';
|
||||
import SelfQRcodeWrapper from '../../../../qrcode/SelfQRcode';
|
||||
import { countries } from '../../../../../common/src/constants/countries';
|
||||
import SelfQRcodeWrapper, { SelfAppBuilder, countries } from '@selfxyz/qrcode';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export default function Home() {
|
||||
@@ -36,6 +34,7 @@ export default function Home() {
|
||||
onSuccess={() => {
|
||||
window.location.href = '/verified';
|
||||
}}
|
||||
onError={console.error}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"include": ["next-env.d.ts", "./src/**/*.ts", "./src/**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user