6
.github/workflows/action.yml
vendored
@@ -53,8 +53,4 @@ jobs:
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: ./circuits
|
||||
run: yarn test
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: ./circuits
|
||||
run: yarn test
|
||||
run: yarn test
|
||||
14
app/App.tsx
@@ -9,28 +9,36 @@ import useNavigationStore from './src/stores/navigationStore';
|
||||
import { AMPLITUDE_KEY } from '@env';
|
||||
import * as amplitude from '@amplitude/analytics-react-native';
|
||||
import useUserStore from './src/stores/userStore';
|
||||
import { bgWhite } from './src/utils/colors';
|
||||
global.Buffer = Buffer;
|
||||
|
||||
function App(): JSX.Element {
|
||||
const toast = useToastController();
|
||||
const setToast = useNavigationStore((state) => state.setToast);
|
||||
const initUserStore = useUserStore((state) => state.initUserStore);
|
||||
const setSelectedTab = useNavigationStore((state) => state.setSelectedTab);
|
||||
|
||||
useEffect(() => {
|
||||
initUserStore();
|
||||
}, [initUserStore]);
|
||||
|
||||
useEffect(() => {
|
||||
setToast(toast);
|
||||
}, [toast, setToast]);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedTab('splash');
|
||||
}, [setSelectedTab]);
|
||||
useEffect(() => {
|
||||
if (AMPLITUDE_KEY) {
|
||||
amplitude.init(AMPLITUDE_KEY);
|
||||
}
|
||||
initUserStore();
|
||||
//initUserStore();
|
||||
}, []);
|
||||
|
||||
// TODO: when passportData already stored, retrieve and jump to main screen
|
||||
|
||||
return (
|
||||
<YStack f={1} bc="#161616" h="100%" w="100%">
|
||||
<YStack f={1} bc={bgWhite} h="100%" w="100%">
|
||||
<YStack h="100%" w="100%">
|
||||
<MainScreen />
|
||||
</YStack>
|
||||
|
||||
@@ -140,6 +140,8 @@ dependencies {
|
||||
implementation project(':passportreader')
|
||||
implementation 'org.jmrtd:jmrtd:0.7.18'
|
||||
|
||||
implementation 'com.github.blikoon:QRCodeScanner:0.1.2'
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.tradle.nfc.RNPassportReaderPackage;
|
||||
import java.util.List;
|
||||
import com.proofofpassport.prover.ProverPackage;
|
||||
import com.rnfs.RNFSPackage;
|
||||
import com.proofofpassport.QRCodeScannerPackage;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
@@ -32,6 +33,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
// Add the custom package here
|
||||
packages.add(new CameraActivityPackage());
|
||||
packages.add(new ProverPackage());
|
||||
packages.add(new QRCodeScannerPackage());
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.proofofpassport;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.facebook.react.bridge.ActivityEventListener;
|
||||
import com.facebook.react.bridge.BaseActivityEventListener;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.blikoon.qrcodescanner.QrCodeActivity;
|
||||
import android.Manifest;
|
||||
|
||||
public class QRCodeScannerModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final int REQUEST_CODE_QR_SCAN = 101;
|
||||
private static final int PERMISSION_REQUEST_CAMERA = 1;
|
||||
private Promise scanPromise;
|
||||
|
||||
private final ActivityEventListener activityEventListener = new BaseActivityEventListener() {
|
||||
@Override
|
||||
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == REQUEST_CODE_QR_SCAN) {
|
||||
if (scanPromise != null) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
String result = data.getStringExtra("com.blikoon.qrcodescanner.got_qr_scan_relult");
|
||||
scanPromise.resolve(result);
|
||||
} else {
|
||||
scanPromise.reject("SCAN_FAILED", "QR Code scanning failed or was cancelled");
|
||||
}
|
||||
scanPromise = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
QRCodeScannerModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
reactContext.addActivityEventListener(activityEventListener);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "QRCodeScanner";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void scanQRCode(Promise promise) {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
if (currentActivity == null) {
|
||||
promise.reject("ACTIVITY_DOES_NOT_EXIST", "Activity doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
scanPromise = promise;
|
||||
|
||||
if (ContextCompat.checkSelfPermission(currentActivity, Manifest.permission.CAMERA)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(currentActivity,
|
||||
new String[]{Manifest.permission.CAMERA},
|
||||
PERMISSION_REQUEST_CAMERA);
|
||||
} else {
|
||||
startQRScanner(currentActivity);
|
||||
}
|
||||
}
|
||||
|
||||
private void startQRScanner(Activity activity) {
|
||||
Intent intent = new Intent(activity, QrCodeActivity.class);
|
||||
activity.startActivityForResult(intent, REQUEST_CODE_QR_SCAN);
|
||||
}
|
||||
|
||||
// Add this method to handle permission result
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (requestCode == PERMISSION_REQUEST_CAMERA) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
if (currentActivity != null) {
|
||||
startQRScanner(currentActivity);
|
||||
}
|
||||
} else {
|
||||
if (scanPromise != null) {
|
||||
scanPromise.reject("PERMISSION_DENIED", "Camera permission was denied");
|
||||
scanPromise = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.proofofpassport;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class QRCodeScannerPackage implements ReactPackage {
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
modules.add(new QRCodeScannerModule(reactContext));
|
||||
return modules;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,11 @@
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||
<item name="android:statusBarColor">#F5F5F5</item>
|
||||
<item name="android:navigationBarColor">#F5F5F5</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<item name="android:windowLightNavigationBar">true</item>
|
||||
<item name="android:windowBackground">#F5F5F5</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"Deploy_Registry#Formatter": "0x15cAe49aFFD6C9f918BC454A255C05997A74F960",
|
||||
"Deploy_Registry#PoseidonT3": "0xdfAC8e1AECc55C4c8B8eC55D666A5a5BB8fbAE5c",
|
||||
"Deploy_Registry#Registry": "0xBabF700EdE592Aa69e14B5BAE1859ee4164C3323",
|
||||
"Deploy_Registry#Verifier_disclose": "0x36BDB37Ab78feB585B782A734C07D04C4c5A66B4",
|
||||
"Deploy_Registry#Verifier_dsc_4096": "0x97c7D14A52e1576dADf8a7CCDf92a246aeb0C493",
|
||||
"Deploy_Registry#Verifier_register_sha1WithRSAEncryption_65537": "0x8392b122Bcbf1eF99dFf1b183C5D4939EDf699A2",
|
||||
"Deploy_Registry#Verifier_register_sha256WithRSAEncryption_65537": "0x2f5505803a3FCa5322A70A6471C91C34545AEa5D",
|
||||
"Deploy_Registry#ProofOfPassportRegister": "0xEd7495516a957dD7d378d8A78846646461cFF25f",
|
||||
"Deploy_Registry#SBT": "0x601Fd54FD11C5E77DE84d877e55B829aff20f0A6"
|
||||
"Deploy_Registry#Formatter": "0xD73395ad7391a3285d2e2a2259031ED6Eb753a2c",
|
||||
"Deploy_Registry#PoseidonT3": "0xbc16D1BD4Be33Cff388Bcbd61285b08BDCdeb86C",
|
||||
"Deploy_Registry#Registry": "0xe2778F3b0302359d947531C2E668b46cFbE97206",
|
||||
"Deploy_Registry#Verifier_disclose": "0xE2e39e0b823c1290788303094cb75B474899EAf6",
|
||||
"Deploy_Registry#Verifier_dsc_sha256_rsa_4096": "0xFD3AFBb0E0565cc28E99d9e11629c4c20e1e517D",
|
||||
"Deploy_Registry#Verifier_register_sha1WithRSAEncryption_65537": "0x434547E86530A583137c9990ffb87682F0d5ca48",
|
||||
"Deploy_Registry#Verifier_register_sha256WithRSAEncryption_65537": "0xDc5e3E81b4b3bC22f79C3a90dbb57EBB9aEdAAfF",
|
||||
"Deploy_Registry#ProofOfPassportRegister": "0x3F346FFdC5d583e4126AF01A02Ac5b9CdB3f1909",
|
||||
"Deploy_Registry#SBT": "0x33f41D706587a7AC6c2061B1893e6eb29615822B"
|
||||
}
|
||||
41
app/ios/LottieView.swift
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// LottieView.swift
|
||||
// FreedomTools
|
||||
//
|
||||
// Created by Ivan Lele on 27.02.2024.
|
||||
//
|
||||
|
||||
import Lottie
|
||||
import SwiftUI
|
||||
|
||||
struct LottieView: UIViewRepresentable {
|
||||
var animationFileName: String
|
||||
let loopMode: LottieLoopMode
|
||||
|
||||
func updateUIView(_ uiView: UIViewType, context: Context) {}
|
||||
|
||||
func makeUIView(context: Context) -> some UIView {
|
||||
let view = UIView(frame: .zero)
|
||||
|
||||
let animationView = LottieAnimationView(name: animationFileName)
|
||||
animationView.loopMode = loopMode
|
||||
animationView.contentMode = .scaleAspectFit
|
||||
|
||||
animationView.play()
|
||||
|
||||
animationView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(animationView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
|
||||
animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
|
||||
])
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
LottieView(animationFileName: "passport", loopMode: .loop)
|
||||
.frame(width: 300)
|
||||
}
|
||||
@@ -28,6 +28,8 @@ class MRZScannerModule: NSObject, RCTBridgeModule {
|
||||
|
||||
var hostingController: UIHostingController<ScannerWithInstructions>? = nil
|
||||
var scannerView = QKMRZScannerViewRepresentable()
|
||||
let lottieView = LottieView(animationFileName: "passport", loopMode: .loop)
|
||||
|
||||
scannerView.onScanResult = { scanResult in
|
||||
let resultDict: [String: Any] = [
|
||||
"documentNumber": scanResult.documentNumber,
|
||||
@@ -41,7 +43,7 @@ class MRZScannerModule: NSObject, RCTBridgeModule {
|
||||
}
|
||||
|
||||
// Wrap the scanner view and instruction text in a new SwiftUI view
|
||||
let scannerWithInstructions = ScannerWithInstructions(scannerView: scannerView)
|
||||
let scannerWithInstructions = ScannerWithInstructions(scannerView: scannerView, lottieView: lottieView)
|
||||
hostingController = UIHostingController(rootView: scannerWithInstructions)
|
||||
rootViewController.present(hostingController!, animated: true, completion: nil)
|
||||
}
|
||||
@@ -55,14 +57,29 @@ class MRZScannerModule: NSObject, RCTBridgeModule {
|
||||
// Define a new SwiftUI view that includes the scanner and instruction text
|
||||
struct ScannerWithInstructions: View {
|
||||
var scannerView: QKMRZScannerViewRepresentable
|
||||
var lottieView: LottieView
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
scannerView
|
||||
Text("Avoid glare or reflections during scanning.")
|
||||
.font(.title3)
|
||||
.padding()
|
||||
.multilineTextAlignment(.center)
|
||||
ZStack {
|
||||
Color.white.ignoresSafeArea() // This creates a white background for the entire view
|
||||
|
||||
VStack {
|
||||
ZStack {
|
||||
scannerView
|
||||
.mask {
|
||||
RoundedRectangle(cornerRadius: 15)
|
||||
.frame(width: 370, height: 270)
|
||||
}
|
||||
lottieView.frame(width: 360, height: 230)
|
||||
}
|
||||
.frame(height: 320)
|
||||
Text("Hold your passport on a flat surface while scanning")
|
||||
.font(.custom("Inter-Regular", size: 20))
|
||||
.foregroundColor(.black)
|
||||
.multilineTextAlignment(.center)
|
||||
.frame(width: 300)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ target 'ProofOfPassport' do
|
||||
pod 'NFCPassportReader', git: 'https://github.com/0xturboblitz/NFCPassportReader.git', commit: '310ecb519655d9ed8b1afc5eb490b2f51a4d3595'
|
||||
pod 'QKMRZScanner'
|
||||
pod 'RNFS', :path => '../node_modules/react-native-fs'
|
||||
pod 'lottie-ios'
|
||||
pod 'SwiftQRScanner', :git => 'https://github.com/vinodiOS/SwiftQRScanner'
|
||||
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
@@ -79,4 +81,4 @@ target 'ProofOfPassport' do
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,6 +13,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/core (= 0.72.3)
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- lottie-ios (4.5.0)
|
||||
- NFCPassportReader (2.0.3):
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- OpenSSL-Universal (1.1.1100)
|
||||
@@ -291,10 +292,14 @@ PODS:
|
||||
- React-jsinspector (0.72.3)
|
||||
- React-logger (0.72.3):
|
||||
- glog
|
||||
- react-native-date-picker (5.0.4):
|
||||
- React-Core
|
||||
- react-native-get-random-values (1.11.0):
|
||||
- React-Core
|
||||
- react-native-netinfo (11.3.1):
|
||||
- React-Core
|
||||
- react-native-nfc-manager (3.15.1):
|
||||
- React-Core
|
||||
- React-NativeModulesApple (0.72.3):
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
@@ -419,6 +424,7 @@ PODS:
|
||||
- SSZipArchive (~> 2.2)
|
||||
- SocketRocket (0.6.1)
|
||||
- SSZipArchive (2.4.3)
|
||||
- SwiftQRScanner (1.1.6)
|
||||
- SwiftyTesseract (3.1.3)
|
||||
- Yoga (1.14.0)
|
||||
|
||||
@@ -429,6 +435,7 @@ DEPENDENCIES:
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- lottie-ios
|
||||
- NFCPassportReader (from `https://github.com/0xturboblitz/NFCPassportReader.git`, commit `310ecb519655d9ed8b1afc5eb490b2f51a4d3595`)
|
||||
- QKMRZScanner
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
@@ -447,8 +454,10 @@ DEPENDENCIES:
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- react-native-date-picker (from `../node_modules/react-native-date-picker`)
|
||||
- react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-nfc-manager (from `../node_modules/react-native-nfc-manager`)
|
||||
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
@@ -472,11 +481,13 @@ DEPENDENCIES:
|
||||
- RNKeychain (from `../node_modules/react-native-keychain`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNZipArchive (from `../node_modules/react-native-zip-archive`)
|
||||
- SwiftQRScanner (from `https://github.com/vinodiOS/SwiftQRScanner`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- fmt
|
||||
- lottie-ios
|
||||
- OpenSSL-Universal
|
||||
- QKMRZParser
|
||||
- QKMRZScanner
|
||||
@@ -530,10 +541,14 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-date-picker:
|
||||
:path: "../node_modules/react-native-date-picker"
|
||||
react-native-get-random-values:
|
||||
:path: "../node_modules/react-native-get-random-values"
|
||||
react-native-netinfo:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-nfc-manager:
|
||||
:path: "../node_modules/react-native-nfc-manager"
|
||||
React-NativeModulesApple:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
|
||||
React-perflogger:
|
||||
@@ -580,6 +595,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-svg"
|
||||
RNZipArchive:
|
||||
:path: "../node_modules/react-native-zip-archive"
|
||||
SwiftQRScanner:
|
||||
:git: https://github.com/vinodiOS/SwiftQRScanner
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
@@ -587,6 +604,9 @@ CHECKOUT OPTIONS:
|
||||
NFCPassportReader:
|
||||
:commit: 310ecb519655d9ed8b1afc5eb490b2f51a4d3595
|
||||
:git: https://github.com/0xturboblitz/NFCPassportReader.git
|
||||
SwiftQRScanner:
|
||||
:commit: fddcabcb431cd6110cea0394660082661dbafa7e
|
||||
:git: https://github.com/vinodiOS/SwiftQRScanner
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
amplitude-react-native: 43098dfcfe1dcd6f0e9426017258ba79289d7a21
|
||||
@@ -596,6 +616,7 @@ SPEC CHECKSUMS:
|
||||
FBReactNativeSpec: c6bd9e179757b3c0ecf815864fae8032377903ef
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
lottie-ios: a881093fab623c467d3bce374367755c272bdd59
|
||||
NFCPassportReader: a160b80e3df3b5325c13902f90405f5eef7520b3
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
QKMRZParser: 6b419b6f07d6bff6b50429b97de10846dc902c29
|
||||
@@ -609,15 +630,17 @@ SPEC CHECKSUMS:
|
||||
React-Core: 8293312ad137ea82fd2c29deb163dbc24aa4e00e
|
||||
React-CoreModules: 32fab1d62416849a3b6dac6feff9d54e5ddc2d1e
|
||||
React-cxxreact: 55d0f7cb6b4cc09ba9190797f1da87182d1a2fb6
|
||||
React-debug: 7e61555c8158126c6cd98c3154381ad3821aaaca
|
||||
React-debug: 2aafa5b6cea5ab76043c20d72663aa0204e49020
|
||||
React-jsc: 0db8e8cc2074d979c37ffa7b8d7c914833960497
|
||||
React-jsi: 58677ff4848ceb6aeb9118fe03448a843ea5e16a
|
||||
React-jsiexecutor: 2c15ba1bace70177492368d5180b564f165870fd
|
||||
React-jsinspector: b511447170f561157547bc0bef3f169663860be7
|
||||
React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95
|
||||
react-native-date-picker: 6891317e850deae5b53d51355226e07a495aba61
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-netinfo: bdb108d340cdb41875c9ced535977cac6d2ff321
|
||||
React-NativeModulesApple: 0438665fc7473be6edc496e823e6ea0b0537b46c
|
||||
react-native-nfc-manager: 3134770f9afcb586c0ae859e747fda3106ec1f76
|
||||
React-NativeModulesApple: 1d8e4abb2fc6d80bdd13dcf128ee548804eb4a24
|
||||
React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5
|
||||
React-RCTActionSheet: c0b62af44e610e69d9a2049a682f5dba4e9dff17
|
||||
React-RCTAnimation: fe7005136b58f58871cab2f70732343b6e330d30
|
||||
@@ -631,9 +654,9 @@ SPEC CHECKSUMS:
|
||||
React-RCTVibration: ea3a68a49873a54ced927c90923fc6932baf344a
|
||||
React-rncore: 9672a017af4a7da7495d911f0b690cbcae9dd18d
|
||||
React-runtimeexecutor: 369ae9bb3f83b65201c0c8f7d50b72280b5a1dbc
|
||||
React-runtimescheduler: ec1066a4f2d1152eb1bc3fb61d69376b3bc0dde0
|
||||
React-utils: d55ba834beb39f01b0b470ae43478c0a3a024abe
|
||||
ReactCommon: 68e3a815fbb69af3bb4196e04c6ae7abb306e7a8
|
||||
React-runtimescheduler: 053752ab29d2747602f81c76d1bd7ede9412ef69
|
||||
React-utils: d3799712bc7003f1ad6501a37189384bf87c25f1
|
||||
ReactCommon: e639ff94ef1db3d9dd184decec9b02a6fbcc638e
|
||||
RNCAsyncStorage: 826b603ae9c0f88b5ac4e956801f755109fa4d5c
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
@@ -642,9 +665,10 @@ SPEC CHECKSUMS:
|
||||
RNZipArchive: ef9451b849c45a29509bf44e65b788829ab07801
|
||||
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
SwiftQRScanner: e85a25f9b843e9231dab89a96e441472fe54a724
|
||||
SwiftyTesseract: 1f3d96668ae92dc2208d9842c8a59bea9fad2cbb
|
||||
Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce
|
||||
|
||||
PODFILE CHECKSUM: 2e0fb25883367cd333873ac29cbb9f28ba88c30f
|
||||
PODFILE CHECKSUM: ed2a230fe418418ecb7e6525cb769af59fc9dae2
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@@ -26,7 +26,12 @@
|
||||
165E76BD2B8DC4A00000FA90 /* MRZScannerModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 165E76BC2B8DC4A00000FA90 /* MRZScannerModule.swift */; };
|
||||
165E76BF2B8DC53A0000FA90 /* MRZScannerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 165E76BE2B8DC53A0000FA90 /* MRZScannerModule.m */; };
|
||||
165E76C32B8DC8370000FA90 /* ScannerHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 165E76C22B8DC8370000FA90 /* ScannerHostingController.swift */; };
|
||||
1686F0DC2C500F3800841CDE /* QRScannerBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1686F0DB2C500F3800841CDE /* QRScannerBridge.swift */; };
|
||||
1686F0DE2C500F4F00841CDE /* QRScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1686F0DD2C500F4F00841CDE /* QRScannerViewController.swift */; };
|
||||
1686F0E02C500FBD00841CDE /* QRScannerBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 1686F0DF2C500FBD00841CDE /* QRScannerBridge.m */; };
|
||||
16E0838A2C4E7AF100CE8DB2 /* LottieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16E083892C4E7AF100CE8DB2 /* LottieView.swift */; };
|
||||
16E6646E2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16E6646D2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift */; };
|
||||
16E884A52C5BD764003B7125 /* passport.json in Resources */ = {isa = PBXBuildFile; fileRef = 16E884A42C5BD764003B7125 /* passport.json */; };
|
||||
1BA25F26C91C45F697D55099 /* Inter-ExtraLight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 568162F4DC4B4CDC8B341853 /* Inter-ExtraLight.otf */; };
|
||||
1D2A11340C7041909B820A90 /* Inter-ExtraBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = D20EA8C94F544E14AB58E6EB /* Inter-ExtraBold.otf */; };
|
||||
2CD45EA0A0A94063935CE7D3 /* Inter-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = DF4EC58B331A46F098343757 /* Inter-Regular.otf */; };
|
||||
@@ -90,7 +95,12 @@
|
||||
165E76BC2B8DC4A00000FA90 /* MRZScannerModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MRZScannerModule.swift; sourceTree = "<group>"; };
|
||||
165E76BE2B8DC53A0000FA90 /* MRZScannerModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRZScannerModule.m; sourceTree = "<group>"; };
|
||||
165E76C22B8DC8370000FA90 /* ScannerHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannerHostingController.swift; sourceTree = "<group>"; };
|
||||
1686F0DB2C500F3800841CDE /* QRScannerBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRScannerBridge.swift; sourceTree = "<group>"; };
|
||||
1686F0DD2C500F4F00841CDE /* QRScannerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRScannerViewController.swift; sourceTree = "<group>"; };
|
||||
1686F0DF2C500FBD00841CDE /* QRScannerBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QRScannerBridge.m; sourceTree = "<group>"; };
|
||||
16E083892C4E7AF100CE8DB2 /* LottieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LottieView.swift; sourceTree = "<group>"; };
|
||||
16E6646D2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QKMRZScannerViewRepresentable.swift; sourceTree = "<group>"; };
|
||||
16E884A42C5BD764003B7125 /* passport.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = passport.json; sourceTree = "<group>"; };
|
||||
1CA9D245CD5A439D88F01D4F /* Inter-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-ThinItalic.otf"; path = "../node_modules/@tamagui/font-inter/otf/Inter-ThinItalic.otf"; sourceTree = "<group>"; };
|
||||
22FDF2ADA5789E09558ADB4E /* Pods-ProofOfPassport-ProofOfPassportTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ProofOfPassport-ProofOfPassportTests.release.xcconfig"; path = "Target Support Files/Pods-ProofOfPassport-ProofOfPassportTests/Pods-ProofOfPassport-ProofOfPassportTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
2B01EC4981C171CA304E6D2B /* Pods-ProofOfPassport.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ProofOfPassport.release.xcconfig"; path = "Target Support Files/Pods-ProofOfPassport/Pods-ProofOfPassport.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -156,6 +166,7 @@
|
||||
13B07FAE1A68108700A75B9A /* ProofOfPassport */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
16E884A42C5BD764003B7125 /* passport.json */,
|
||||
05EDEDC42B52D25D00AA51AD /* Prover.m */,
|
||||
05EDEDC52B52D25D00AA51AD /* Prover.swift */,
|
||||
905B700A2A72A5E900AFA232 /* masterList.pem */,
|
||||
@@ -173,9 +184,13 @@
|
||||
905B70032A72767800AFA232 /* ProofOfPassport-Bridging-Header.h */,
|
||||
165E76C22B8DC8370000FA90 /* ScannerHostingController.swift */,
|
||||
905B70062A72774000AFA232 /* PassportReader.m */,
|
||||
16E083892C4E7AF100CE8DB2 /* LottieView.swift */,
|
||||
165E76BC2B8DC4A00000FA90 /* MRZScannerModule.swift */,
|
||||
165E76BE2B8DC53A0000FA90 /* MRZScannerModule.m */,
|
||||
16E6646D2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift */,
|
||||
1686F0DB2C500F3800841CDE /* QRScannerBridge.swift */,
|
||||
1686F0DF2C500FBD00841CDE /* QRScannerBridge.m */,
|
||||
1686F0DD2C500F4F00841CDE /* QRScannerViewController.swift */,
|
||||
);
|
||||
name = ProofOfPassport;
|
||||
sourceTree = "<group>";
|
||||
@@ -383,6 +398,7 @@
|
||||
37AF1D1302824FFC83B6D1D2 /* Inter-ThinItalic.otf in Resources */,
|
||||
CC99B59A281C4B6497C14141 /* Luciole-Bold-Italic.ttf in Resources */,
|
||||
05E2174E2E7E48EB80B9C8D8 /* Luciole-Bold.ttf in Resources */,
|
||||
16E884A52C5BD764003B7125 /* passport.json in Resources */,
|
||||
6959CC40713D4D42AA56850D /* Luciole-Regular-Italic.ttf in Resources */,
|
||||
E4E0715B819049EFACAF2AEE /* Luciole-Regular.ttf in Resources */,
|
||||
98D6CE33FC02453794D8DB08 /* slkscr.ttf in Resources */,
|
||||
@@ -523,7 +539,10 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
||||
1686F0DE2C500F4F00841CDE /* QRScannerViewController.swift in Sources */,
|
||||
1686F0E02C500FBD00841CDE /* QRScannerBridge.m in Sources */,
|
||||
05EDEDC72B52D25D00AA51AD /* Prover.swift in Sources */,
|
||||
1686F0DC2C500F3800841CDE /* QRScannerBridge.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
905B70072A72774000AFA232 /* PassportReader.m in Sources */,
|
||||
16E6646E2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift in Sources */,
|
||||
@@ -531,6 +550,7 @@
|
||||
905B70052A72767900AFA232 /* PassportReader.swift in Sources */,
|
||||
165E76C32B8DC8370000FA90 /* ScannerHostingController.swift in Sources */,
|
||||
05EDEDC62B52D25D00AA51AD /* Prover.m in Sources */,
|
||||
16E0838A2C4E7AF100CE8DB2 /* LottieView.swift in Sources */,
|
||||
165E76BD2B8DC4A00000FA90 /* MRZScannerModule.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -609,7 +629,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 47;
|
||||
DEVELOPMENT_TEAM = 5B29R5LYHQ;
|
||||
DEVELOPMENT_TEAM = X53ZR86F22;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -708,6 +728,7 @@
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
INFOPLIST_FILE = ProofOfPassport/Info.plist;
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Needed only if you want to upload QRcodes";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -726,7 +747,7 @@
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.warroom.proofofpassport;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.warroom.proofofpassport-dev";
|
||||
PRODUCT_NAME = ProofOfPassport;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/ProofOfPassport-Bridging-Header.h";
|
||||
@@ -744,7 +765,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = ProofOfPassport/ProofOfPassport.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 47;
|
||||
DEVELOPMENT_TEAM = 5B29R5LYHQ;
|
||||
DEVELOPMENT_TEAM = X53ZR86F22;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"",
|
||||
@@ -842,6 +863,8 @@
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
INFOPLIST_FILE = ProofOfPassport/Info.plist;
|
||||
INFOPLIST_KEY_NSDocumentsFolderUsageDescription = "";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Needed only if you want to upload QRcodes";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -859,7 +882,7 @@
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.warroom.proofofpassport;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.warroom.proofofpassport-dev";
|
||||
PRODUCT_NAME = ProofOfPassport;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/ProofOfPassport-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@@ -23,4 +25,4 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -51,6 +51,8 @@
|
||||
<string></string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need access to your photo library to allow you to choose passport photos or save generated QR codes.</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Inter-Black.otf</string>
|
||||
|
||||
1134
app/ios/ProofOfPassport/passport.json
Normal file
15
app/ios/QRScannerBridge.m
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// QRScannerBridge.m
|
||||
// ProofOfPassport
|
||||
//
|
||||
// Created by Rémi Colin on 23/07/2024.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@interface RCT_EXTERN_MODULE(QRScannerBridge, NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(scanQRCode:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
@end
|
||||
30
app/ios/QRScannerBridge.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// QRScannerBridge.swift
|
||||
// ProofOfPassport
|
||||
//
|
||||
// Created by Rémi Colin on 23/07/2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftQRScanner
|
||||
import React
|
||||
|
||||
@objc(QRScannerBridge)
|
||||
class QRScannerBridge: NSObject {
|
||||
@objc
|
||||
static func requiresMainQueueSetup() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@objc
|
||||
func scanQRCode(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
DispatchQueue.main.async {
|
||||
let rootViewController = UIApplication.shared.keyWindow?.rootViewController
|
||||
let qrScannerViewController = QRScannerViewController()
|
||||
qrScannerViewController.completionHandler = { result in
|
||||
resolve(result)
|
||||
}
|
||||
rootViewController?.present(qrScannerViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
45
app/ios/QRScannerViewController.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// QRScannerViewController.swift
|
||||
// ProofOfPassport
|
||||
//
|
||||
// Created by Rémi Colin on 23/07/2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import SwiftQRScanner
|
||||
|
||||
class QRScannerViewController: UIViewController, QRScannerCodeDelegate {
|
||||
var completionHandler: ((String) -> Void)?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
var configuration = QRScannerConfiguration()
|
||||
configuration.cameraImage = UIImage(named: "camera")
|
||||
configuration.flashOnImage = UIImage(named: "flash-on")
|
||||
configuration.galleryImage = UIImage(named: "photos")
|
||||
|
||||
let scanner = QRCodeScannerController(qrScannerConfiguration: configuration)
|
||||
scanner.delegate = self
|
||||
|
||||
addChild(scanner)
|
||||
view.addSubview(scanner.view)
|
||||
scanner.view.frame = view.bounds
|
||||
scanner.didMove(toParent: self)
|
||||
}
|
||||
|
||||
func qrScanner(_ controller: UIViewController, didScanQRCodeWithResult result: String) {
|
||||
completionHandler?(result)
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func qrScanner(_ controller: UIViewController, didFailWithError error: QRCodeError) {
|
||||
print("QR Scanner Error: \(error.localizedDescription)")
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func qrScannerDidCancel(_ controller: UIViewController) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
1134
app/ios/passport.json
Normal file
@@ -14,15 +14,16 @@
|
||||
"@amplitude/analytics-react-native": "^1.4.7",
|
||||
"@babel/plugin-transform-private-methods": "^7.23.3",
|
||||
"@ethersproject/shims": "^5.7.0",
|
||||
"@proofofpassport/sdk": "^1.5.6",
|
||||
"@react-native-async-storage/async-storage": "^1.23.1",
|
||||
"@react-native-community/clipboard": "^1.5.1",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@tamagui/colors": "^1.94.3",
|
||||
"@tamagui/config": "^1.94.3",
|
||||
"@tamagui/core": "^1.94.3",
|
||||
"@tamagui/lucide-icons": "^1.94.3",
|
||||
"@tamagui/toast": "^1.94.3",
|
||||
"@tamagui/types": "^1.94.3",
|
||||
"@tamagui/colors": "^1.103.0",
|
||||
"@tamagui/config": "^1.103.0",
|
||||
"@tamagui/core": "^1.103.0",
|
||||
"@tamagui/lucide-icons": "^1.103.0",
|
||||
"@tamagui/toast": "^1.103.0",
|
||||
"@tamagui/types": "^1.103.0",
|
||||
"@zk-kit/imt": "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675",
|
||||
"axios": "^1.6.3",
|
||||
"body-parser": "^1.20.2",
|
||||
@@ -40,14 +41,18 @@
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.72.3",
|
||||
"react-native-canvas": "^0.1.39",
|
||||
"react-native-date-picker": "^5.0.4",
|
||||
"react-native-dialog": "^9.3.0",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-keychain": "^8.2.0",
|
||||
"react-native-nfc-manager": "^3.15.1",
|
||||
"react-native-passport-reader": "^1.0.3",
|
||||
"react-native-svg": "13.4.0",
|
||||
"react-native-zip-archive": "^6.1.0",
|
||||
"tamagui": "^1.94.3",
|
||||
"react-spinners": "^0.14.1",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"tamagui": "^1.103.0",
|
||||
"zustand": "^4.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -76,4 +81,4 @@
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppType } from "../utils/appType";
|
||||
import { AppType } from "../../../common/src/utils/appType";
|
||||
import { Text, YStack } from 'tamagui';
|
||||
import { Coins } from '@tamagui/lucide-icons';
|
||||
import GITCOIN from '../images/gitcoin.png';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppType } from "../utils/appType";
|
||||
import { AppType } from "../../../common/src/utils/appType";
|
||||
import { Flame } from '@tamagui/lucide-icons';
|
||||
import { Text, XStack, YStack } from 'tamagui';
|
||||
import { generateProof } from "../utils/prover";
|
||||
@@ -159,7 +159,7 @@ export const sbtApp: AppType = {
|
||||
|
||||
const end = Date.now();
|
||||
console.log('Total proof time from frontend:', end - start);
|
||||
amplitude.track('Proof generation successful, took ' + ((end - start) / 1000) + ' seconds');
|
||||
//amplitude.track('Proof generation successful, took ' + ((end - start) / 1000) + ' seconds');
|
||||
update({
|
||||
proof: proof,
|
||||
proofTime: end - start,
|
||||
@@ -174,7 +174,7 @@ export const sbtApp: AppType = {
|
||||
},
|
||||
})
|
||||
setStep(Steps.NEXT_SCREEN);
|
||||
amplitude.track(error.message);
|
||||
//amplitude.track(error.message);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -269,7 +269,7 @@ export const sbtApp: AppType = {
|
||||
console.log('Failed to parse blockchain error');
|
||||
}
|
||||
}
|
||||
amplitude.track(error.message);
|
||||
//amplitude.track(error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppType } from "../utils/appType";
|
||||
import { AppType } from "../../../common/src/utils/appType";
|
||||
import { Text, YStack } from 'tamagui';
|
||||
import { Ticket } from '@tamagui/lucide-icons';
|
||||
import ZUPASS from '../images/zupass.png';
|
||||
|
||||
116
app/src/components/Carousel.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import React, { useState } from 'react'
|
||||
import { AnimatePresence } from '@tamagui/animate-presence'
|
||||
import { ArrowLeft, ArrowRight, Nfc, ShieldCheck } from '@tamagui/lucide-icons'
|
||||
import { Button, Image, XStack, YStack, styled, Text } from 'tamagui'
|
||||
import { bgBlue, bgGreen, borderColor, textBlack, textColor1, textColor2 } from '../utils/colors'
|
||||
import CustomButton from './CustomButton'
|
||||
|
||||
const GalleryItem = styled(YStack, {
|
||||
zIndex: 1,
|
||||
x: 0,
|
||||
opacity: 1,
|
||||
fullscreen: true,
|
||||
|
||||
variants: {
|
||||
going: {
|
||||
':number': (going) => ({
|
||||
enterStyle: {
|
||||
x: going > 0 ? 1000 : -1000,
|
||||
opacity: 0,
|
||||
},
|
||||
exitStyle: {
|
||||
zIndex: 0,
|
||||
x: going < 0 ? 1000 : -1000,
|
||||
opacity: 0,
|
||||
},
|
||||
}),
|
||||
},
|
||||
} as const,
|
||||
})
|
||||
|
||||
const wrap = (min: number, max: number, v: number) => {
|
||||
const rangeSize = max - min
|
||||
return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min
|
||||
}
|
||||
|
||||
interface CarouselProps {
|
||||
images: string[];
|
||||
height?: number;
|
||||
onSlideChange?: (index: number) => void;
|
||||
handleNfcScan?: () => void;
|
||||
}
|
||||
|
||||
export function Carousel({ images, height = 300, onSlideChange, handleNfcScan }: CarouselProps) {
|
||||
const [[page, going], setPage] = useState([0, 0])
|
||||
|
||||
const imageIndex = wrap(0, images.length, page)
|
||||
const paginate = (going: number) => {
|
||||
const newPage = page + going
|
||||
setPage([newPage, going])
|
||||
onSlideChange?.(newPage)
|
||||
}
|
||||
|
||||
const isLastImage = imageIndex === images.length - 1
|
||||
const slideTexts = [
|
||||
{ header: "Follow this guide carefully", subtitle: "", acknowledgment: "I'm ready to start" },
|
||||
{ header: "Remove your phone case", subtitle: "If your phone does not have a case, you can skip this step.", acknowledgment: "I have removed my phone case" },
|
||||
{ header: "Open your passport to the last page", subtitle: "", acknowledgment: "I have opened my passport to the last page" },
|
||||
{ header: "Put your phone on the passport", subtitle: "Press your phone against the last page of the passport as in the image.", acknowledgment: "I have placed my phone on the passport" },
|
||||
{ header: "Start scanning", subtitle: "Press Start NFC Scan and follow the on-screen instructions.", acknowledgment: "Start scanning" },
|
||||
]
|
||||
|
||||
const currentSlide = slideTexts[imageIndex] || { header: "No header", subtitle: "No subtitle for this slide", acknowledgment: "Continue" }
|
||||
|
||||
return (
|
||||
<YStack f={1} >
|
||||
|
||||
<XStack
|
||||
overflow="hidden"
|
||||
backgroundColor="#000"
|
||||
position="relative"
|
||||
height={height}
|
||||
alignItems="center"
|
||||
borderRadius="$10"
|
||||
mt="$5"
|
||||
>
|
||||
<AnimatePresence initial={false} custom={{ going }}>
|
||||
<GalleryItem key={page} animation="medium" going={going}>
|
||||
<Image source={{ uri: images[imageIndex] }} height={height} resizeMode="contain" />
|
||||
</GalleryItem>
|
||||
</AnimatePresence>
|
||||
|
||||
|
||||
{imageIndex > 0 && (
|
||||
<Button
|
||||
icon={ArrowLeft}
|
||||
size="$5"
|
||||
position="absolute"
|
||||
left="$4"
|
||||
circular
|
||||
elevate
|
||||
onPress={() => paginate(-1)}
|
||||
zi={100}
|
||||
/>
|
||||
)}
|
||||
</XStack>
|
||||
|
||||
<YStack ml="$2">
|
||||
<Text fontSize="$8" mt="$4" color={textBlack} textAlign='center'>{currentSlide.header}</Text>
|
||||
<Text color={textBlack} fontSize="$5" mt="$2" textAlign='center' style={{ opacity: 0.7 }} fontStyle='italic'>{currentSlide.subtitle}</Text>
|
||||
</YStack>
|
||||
|
||||
<XStack justifyContent='center' alignItems='center' gap="$1.5" position="absolute" style={{ bottom: 120, left: 0, right: 0 }}>
|
||||
<ShieldCheck color={textBlack} size={14} />
|
||||
<Text color={textBlack} fontSize="$4" >private and secured</Text>
|
||||
</XStack>
|
||||
<XStack f={1} />
|
||||
|
||||
<CustomButton
|
||||
onPress={isLastImage ? () => handleNfcScan?.() : () => paginate(+1)}
|
||||
text={currentSlide.acknowledgment}
|
||||
Icon={isLastImage ? <Nfc /> : undefined}
|
||||
blueVariant={!isLastImage}
|
||||
/>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
32
app/src/components/CustomButton.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { Button, Text } from 'tamagui';
|
||||
import { bgBlue, bgGreen, textBlack } from '../utils/colors';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
|
||||
interface CustomButtonProps {
|
||||
text: string;
|
||||
onPress: () => void;
|
||||
Icon?: React.ReactNode;
|
||||
bgColor?: string;
|
||||
h?: string;
|
||||
isDisabled?: boolean;
|
||||
disabledOnPress?: () => void;
|
||||
blueVariant?: boolean;
|
||||
}
|
||||
|
||||
const CustomButton: React.FC<CustomButtonProps> = ({ text, onPress, Icon, bgColor, h, isDisabled, disabledOnPress, blueVariant }) => {
|
||||
const {
|
||||
toast,
|
||||
} = useNavigationStore();
|
||||
return (
|
||||
<Button bg={bgColor ? bgColor : blueVariant ? bgBlue : bgGreen} h={blueVariant ? "$8" : "$4.5"} borderRadius="$10" mx="$3" onPress={isDisabled ? disabledOnPress : onPress}>
|
||||
{Icon && <Button.Icon>{Icon}</Button.Icon>}
|
||||
<Text textAlign='center' fontSize={blueVariant ? "$6" : "$5"} fontWeight="bold" color={textBlack}>
|
||||
{text}
|
||||
</Text>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default CustomButton;
|
||||
20
app/src/components/StepOneStepTwo.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { XStack } from "tamagui";
|
||||
import { textBlack } from "../utils/colors";
|
||||
|
||||
interface StepOneStepTwoProps {
|
||||
variable: string;
|
||||
step1: string;
|
||||
step2: string;
|
||||
}
|
||||
const StepOneStepTwo = ({ variable, step1, step2 }: StepOneStepTwoProps) => {
|
||||
const isVisible = variable === step1 || variable === step2;
|
||||
|
||||
return (
|
||||
<XStack px="$4" mt="$4" gap="$3" style={{ opacity: isVisible ? 1 : 0 }}>
|
||||
<XStack h="$0.25" f={1} bg={textBlack} borderRadius={100} style={{ opacity: variable === step1 ? 1 : 0.2 }} />
|
||||
<XStack h="$0.25" f={1} bg={textBlack} borderRadius={100} style={{ opacity: variable === step2 ? 1 : 0.2 }} />
|
||||
</XStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default StepOneStepTwo;
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 24 KiB |
BIN
app/src/images/passport_lastpage_android.png
Normal file
|
After Width: | Height: | Size: 636 KiB |
BIN
app/src/images/passport_lastpage_graybg.png
Normal file
|
After Width: | Height: | Size: 779 KiB |
BIN
app/src/images/passport_lastpage_iphone.png
Normal file
|
After Width: | Height: | Size: 722 KiB |
BIN
app/src/images/phone_scanbutton.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
app/src/images/remove_case.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
app/src/images/us-passport.png
Normal file
|
After Width: | Height: | Size: 221 KiB |
55
app/src/screens/AppScreen copy.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import { ScrollView, YStack } from 'tamagui';
|
||||
import AppCard from '../components/AppCard';
|
||||
import { Steps } from '../utils/utils';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { AppType } from '../../../common/src/utils/appType';
|
||||
import sbtApp from '../apps/sbt';
|
||||
import zupassApp from '../apps/zupass';
|
||||
import gitcoinApp from '../apps/gitcoin';
|
||||
|
||||
const AppScreen: React.FC = () => {
|
||||
const {
|
||||
selectedApp,
|
||||
update
|
||||
} = useNavigationStore();
|
||||
|
||||
const handleCardSelect = (app: AppType) => {
|
||||
update({
|
||||
selectedTab: "prove",
|
||||
selectedApp: app,
|
||||
step: Steps.APP_SELECTED,
|
||||
})
|
||||
};
|
||||
|
||||
// add new apps here
|
||||
const cardsData = [
|
||||
sbtApp,
|
||||
zupassApp,
|
||||
gitcoinApp
|
||||
];
|
||||
|
||||
return (
|
||||
<ScrollView f={1}>
|
||||
<YStack my="$8" gap="$5" px="$5" jc="center" alignItems='center'>
|
||||
{
|
||||
cardsData.map(app => (
|
||||
<AppCard
|
||||
key={app.id}
|
||||
title={app.title}
|
||||
description={app.description}
|
||||
id={app.id}
|
||||
onTouchStart={() => handleCardSelect(app)}
|
||||
selected={selectedApp && selectedApp.id === app.id ? true : false}
|
||||
selectable={app.selectable}
|
||||
icon={app.icon}
|
||||
tags={app.tags}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppScreen;
|
||||
@@ -1,19 +1,41 @@
|
||||
import React from 'react';
|
||||
import { ScrollView, YStack } from 'tamagui';
|
||||
import { ScrollView, Text, YStack } from 'tamagui';
|
||||
import AppCard from '../components/AppCard';
|
||||
import { Steps } from '../utils/utils';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { AppType } from '../utils/appType';
|
||||
import { AppType, createAppType } from '../../../common/src/utils/appType';
|
||||
import sbtApp from '../apps/sbt';
|
||||
import zupassApp from '../apps/zupass';
|
||||
import gitcoinApp from '../apps/gitcoin';
|
||||
import { XStack } from 'tamagui';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import { BadgeCheck, Binary, LayoutGrid, List, LockKeyhole, QrCode, ShieldCheck, Smartphone, UserPlus } from '@tamagui/lucide-icons';
|
||||
import { bgBlue, bgGreen, separatorColor, textBlack } from '../utils/colors';
|
||||
import { orange } from '@tamagui/colors';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import { Platform } from 'react-native';
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
const AppScreen: React.FC = () => {
|
||||
interface AppScreenProps {
|
||||
setSheetAppListOpen: (value: boolean) => void;
|
||||
setSheetRegisterIsOpen: (value: boolean) => void;
|
||||
}
|
||||
|
||||
const AppScreen: React.FC<AppScreenProps> = ({ setSheetAppListOpen, setSheetRegisterIsOpen }) => {
|
||||
const {
|
||||
selectedApp,
|
||||
update
|
||||
setSelectedApp,
|
||||
update,
|
||||
selectedTab,
|
||||
setSelectedTab,
|
||||
toast
|
||||
} = useNavigationStore();
|
||||
|
||||
const {
|
||||
registered,
|
||||
setRegistered
|
||||
} = useUserStore();
|
||||
|
||||
const handleCardSelect = (app: AppType) => {
|
||||
update({
|
||||
selectedTab: "prove",
|
||||
@@ -22,16 +44,163 @@ const AppScreen: React.FC = () => {
|
||||
})
|
||||
};
|
||||
|
||||
// add new apps here
|
||||
const cardsData = [
|
||||
sbtApp,
|
||||
zupassApp,
|
||||
gitcoinApp
|
||||
];
|
||||
|
||||
const scanQRCode = () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
if (NativeModules.QRScannerBridge && NativeModules.QRScannerBridge.scanQRCode) {
|
||||
NativeModules.QRScannerBridge.scanQRCode()
|
||||
.then((result: string) => {
|
||||
handleQRCodeScan(result);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('QR Scanner Error:', error);
|
||||
toast.show('Error', {
|
||||
message: 'Failed to scan QR code',
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('QR Scanner module not found for iOS');
|
||||
toast.show('Error', {
|
||||
message: 'QR Scanner not available',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
} else if (Platform.OS === 'android') {
|
||||
if (NativeModules.QRCodeScanner && NativeModules.QRCodeScanner.scanQRCode) {
|
||||
NativeModules.QRCodeScanner.scanQRCode()
|
||||
.then((result: string) => {
|
||||
handleQRCodeScan(result);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('QR Scanner Error:', error);
|
||||
toast.show('Error', {
|
||||
message: 'Failed to scan QR code',
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('QR Scanner module not found for Android');
|
||||
toast.show('Error', {
|
||||
message: 'QR Scanner not available',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleQRCodeScan = (result: string) => {
|
||||
try {
|
||||
console.log(result);
|
||||
const app = createAppType(JSON.parse(result));
|
||||
console.log(app);
|
||||
setSelectedApp(app);
|
||||
setSelectedTab("prove");
|
||||
} catch (error) {
|
||||
console.error('Error parsing QR code result:', error);
|
||||
toast.show('Error', {
|
||||
message: 'Invalid QR code format',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollView f={1}>
|
||||
<YStack my="$8" gap="$5" px="$5" jc="center" alignItems='center'>
|
||||
<YStack f={1} pb="$3" px="$3">
|
||||
{/* <XStack h="$0.25" bg={separatorColor} mx="$0" /> */}
|
||||
<ScrollView showsVerticalScrollIndicator={true} indicatorStyle="black">
|
||||
<YStack >
|
||||
<Text fontSize="$8" mt="$2" >Account</Text>
|
||||
<XStack ml="$2" gap="$2" ai="center">
|
||||
<Text fontSize="$5">status:</Text>
|
||||
{registered ?
|
||||
<XStack bg={bgGreen} px="$2.5" py="$2" borderRadius="$10">
|
||||
<Text color={textBlack} fontSize="$4">registered</Text>
|
||||
</XStack> :
|
||||
<XStack bg={'#FFB897'} px="$2.5" py="$2" borderRadius="$10">
|
||||
<Text color={textBlack} fontSize="$4">not registered</Text>
|
||||
</XStack>}
|
||||
|
||||
</XStack>
|
||||
{/* <XStack ml="$2" gap="$2" mt="$1">
|
||||
<Text fontSize="$5">userID:</Text>
|
||||
<Text color={textBlack} fontSize="$5">0x1234567890</Text>
|
||||
</XStack> */}
|
||||
</YStack>
|
||||
<YStack>
|
||||
<Text mt="$4" fontSize="$8" >How to use Proof of Passport?</Text>
|
||||
<YStack>
|
||||
<XStack mt="$3" px="$5" gap="$2" >
|
||||
<QrCode size={50} color={textBlack} />
|
||||
<YStack>
|
||||
<Text fontSize="$5" mb="$1">Scan QR code</Text>
|
||||
<XStack gap="$2"><Text fontSize="$3">1</Text><Text fontSize="$3" maxWidth={220}>Find the QR code on the page of the app that asks for proof of passport.</Text></XStack>
|
||||
<XStack mt="$1" gap="$2"><Text fontSize="$3">2</Text><Text fontSize="$3" maxWidth={220}>Scan the QR code.</Text></XStack>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack mt="$4" px="$5" gap="$2" >
|
||||
<BadgeCheck size={50} color={textBlack} />
|
||||
<YStack>
|
||||
<Text fontSize="$5" mb="$1">Generate a Proof</Text>
|
||||
<XStack gap="$2"><Text fontSize="$3">1</Text><Text fontSize="$3" maxWidth={220}>Generate a proof of the selected information.</Text></XStack>
|
||||
<XStack mt="$1" gap="$2"><Text fontSize="$3">2</Text><Text fontSize="$3" maxWidth={220}>Share the proof with the application.</Text></XStack>
|
||||
</YStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
<YStack mb="$4">
|
||||
<Text mt="$5" fontSize="$8" >How does it works?</Text>
|
||||
<YStack>
|
||||
<XStack mt="$3" px="$5" gap="$2" >
|
||||
<Binary size={50} color={textBlack} />
|
||||
<YStack>
|
||||
<Text fontSize="$5" mb="$1">Strong cryptography</Text>
|
||||
<XStack gap="$2"><Text fontSize="$3">·</Text><Text fontSize="$3" maxWidth={220}>Proof of Passport uses ZK technologies which allows you to prove a statement without revealing why it's true.</Text></XStack>
|
||||
<XStack gap="$2"><Text fontSize="$3">·</Text><Text fontSize="$3" maxWidth={220}>You are always anonymous</Text></XStack>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack mt="$3" px="$5" gap="$2" >
|
||||
<Smartphone size={50} color={textBlack} />
|
||||
<YStack>
|
||||
<Text fontSize="$5" mb="$1">Serverless</Text>
|
||||
<XStack gap="$2"><Text fontSize="$3">·</Text><Text fontSize="$3" maxWidth={220}>Proof of Passport will never receive your data and will never know who you are.</Text></XStack>
|
||||
<XStack gap="$2"><Text fontSize="$3">·</Text><Text fontSize="$3" maxWidth={220}>Everything is achieved on your device, even the camera and NFC scanning.</Text></XStack>
|
||||
|
||||
</YStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
|
||||
|
||||
<XStack f={1} minHeight="$1" />
|
||||
|
||||
<YStack gap="$2.5">
|
||||
<CustomButton
|
||||
text="Scan QR Code"
|
||||
onPress={() => {
|
||||
if (registered) {
|
||||
scanQRCode();
|
||||
} else {
|
||||
setSheetRegisterIsOpen(true);
|
||||
}
|
||||
}}
|
||||
Icon={<QrCode size={18} color={textBlack} />}
|
||||
/>
|
||||
<CustomButton bgColor='white' text="Open app list" onPress={
|
||||
registered ?
|
||||
() => setSheetAppListOpen(true)
|
||||
:
|
||||
() => setSheetRegisterIsOpen(true)} Icon={<List size={18} color={textBlack} />} />
|
||||
</YStack>
|
||||
|
||||
|
||||
{/* <YStack my="$8" gap="$5" px="$5" jc="center" alignItems='center'>
|
||||
{
|
||||
cardsData.map(app => (
|
||||
<AppCard
|
||||
@@ -47,9 +216,9 @@ const AppScreen: React.FC = () => {
|
||||
/>
|
||||
))
|
||||
}
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
</YStack> */}
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
|
||||
export default AppScreen;
|
||||
export default AppScreen;
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import { YStack, Button, Image, Text } from 'tamagui';
|
||||
import { Camera, SquarePen } from '@tamagui/lucide-icons';
|
||||
import { bgColor, borderColor, textColor1, textColor2 } from '../utils/colors';
|
||||
import { YStack, Button, Image, Text, ScrollView, XStack, Separator } from 'tamagui';
|
||||
import { Camera, ShieldCheck, SquarePen, X } from '@tamagui/lucide-icons';
|
||||
import { bgColor, bgGreen, borderColor, componentBgColor, componentBgColor2, separatorColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import SCANHelp from '../images/scan_help.png'
|
||||
import { startCameraScan } from '../utils/cameraScanner';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
|
||||
interface CameraScreenProps {
|
||||
sheetIsOpen: boolean
|
||||
@@ -11,30 +12,31 @@ interface CameraScreenProps {
|
||||
}
|
||||
|
||||
const CameraScreen: React.FC<CameraScreenProps> = ({ sheetIsOpen, setSheetIsOpen }) => {
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$3">
|
||||
<YStack f={1} jc="center">
|
||||
<Image borderRadius="$5"
|
||||
<YStack f={1} mt="$16">
|
||||
<Text ml="$1" fontSize={34} color={textBlack}><Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>Scan</Text> or type your passport ID</Text>
|
||||
<Text ml="$2" mt="$8" fontSize="$8" color={textBlack}>Open your passport on the <Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>main page</Text> to scan it.</Text>
|
||||
<Text ml="$2" mt="$2" fontSize="$8" color={textBlack} style={{ opacity: 0.7 }}>Your data never leaves your device.</Text>
|
||||
<XStack f={1} />
|
||||
|
||||
<XStack justifyContent='center' alignItems='center' gap="$1.5">
|
||||
<ShieldCheck color={textBlack} size={14} />
|
||||
<Text color={textBlack} fontSize="$4">private and secured</Text>
|
||||
</XStack>
|
||||
</YStack>
|
||||
{/* <Image borderRadius="$5"
|
||||
w="full"
|
||||
h="$13"
|
||||
source={{ uri: SCANHelp }}
|
||||
/>
|
||||
<YStack gap="$0.5" mt="$3.5">
|
||||
<Text mt="$1" color={textColor1}>Use your camera to scan the main page of your passport.</Text>
|
||||
<Text fontSize="$2" color={textColor2} mt="$2">You can also enter those data manually.</Text>
|
||||
<Text fontSize="$2" style={{ fontStyle: 'italic' }} color={textColor2}>The app does not take a picture of your passport, it only reads some fields.</Text>
|
||||
</YStack>
|
||||
/> */}
|
||||
|
||||
<YStack gap="$2.5" mt="$5" >
|
||||
<CustomButton text="Open Camera" onPress={startCameraScan} Icon={<Camera color={textBlack} size={24} />} />
|
||||
<CustomButton bgColor='#ffff' text="Manual Input" onPress={() => setSheetIsOpen(true)} Icon={<SquarePen color={textBlack} size={24} />} />
|
||||
</YStack>
|
||||
|
||||
<YStack gap="$2" mb="$6">
|
||||
<Button borderWidth={1.3} borderColor={borderColor} borderRadius="$10" bg="#3185FC" onPress={startCameraScan}><Camera color={textColor1} /></Button>
|
||||
<Button bg={textColor2} borderColor={borderColor} borderRadius="$10" onPress={() => setSheetIsOpen(true)}><SquarePen /></Button>
|
||||
</YStack>
|
||||
|
||||
</YStack >
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default CameraScreen;
|
||||
export default CameraScreen;
|
||||
@@ -4,9 +4,9 @@ import forge from 'node-forge';
|
||||
import Dialog from "react-native-dialog";
|
||||
import { ethers } from 'ethers';
|
||||
// import ressources
|
||||
import { YStack, XStack, Text, Button, Tabs, Sheet, Label, Fieldset, Input, Switch, H2, Image, useWindowDimensions, H4, H3 } from 'tamagui'
|
||||
import { HelpCircle, IterationCw, VenetianMask, Cog, CheckCircle2, ChevronLeft, Share, Eraser } from '@tamagui/lucide-icons';
|
||||
import X from '../images/x.png'
|
||||
import { YStack, XStack, Text, Button, Tabs, Sheet, Label, Fieldset, Input, Switch, H2, Image, useWindowDimensions, H4, H3, Separator } from 'tamagui'
|
||||
import { HelpCircle, IterationCw, VenetianMask, Cog, CheckCircle2, ChevronLeft, Share, Eraser, CalendarSearch, Cross, X, UserPlus, Wifi } from '@tamagui/lucide-icons';
|
||||
import Xlogo from '../images/x.png'
|
||||
import Telegram from '../images/telegram.png'
|
||||
import Github from '../images/github.png'
|
||||
import Internet from "../images/internet.png"
|
||||
@@ -17,7 +17,7 @@ import { ToastMessage } from '../components/ToastMessage';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
// import utils
|
||||
import { bgColor, blueColorLight, borderColor, componentBgColor, textColor1, textColor2 } from '../utils/colors';
|
||||
import { bgColor, bgGreen, bgWhite, blueColorLight, borderColor, componentBgColor, componentBgColor2, separatorColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import { ModalProofSteps, Steps } from '../utils/utils';
|
||||
import { scan } from '../utils/nfcScanner';
|
||||
import { CircuitName, fetchZkey } from '../utils/zkeyDownload';
|
||||
@@ -40,6 +40,13 @@ import AppScreen from './AppScreen';
|
||||
import { RPC_URL, SignatureAlgorithm } from '../../../common/src/constants/constants';
|
||||
import { mock_csca_sha256_rsa_4096, mock_dsc_sha256_rsa_4096 } from '../../../common/src/constants/mockCertificates';
|
||||
|
||||
import DatePicker from 'react-native-date-picker'
|
||||
import StartScreen from './StartScreen';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import StepOneStepTwo from '../components/StepOneStepTwo';
|
||||
import SplashScreen from './SplashScreen';
|
||||
import ValidProofScreen from './ValidProofScreen';
|
||||
import WrongProofScreen from './WrongProofScreen';
|
||||
|
||||
const MainScreen: React.FC = () => {
|
||||
const [NFCScanIsOpen, setNFCScanIsOpen] = useState(false);
|
||||
@@ -49,7 +56,14 @@ const MainScreen: React.FC = () => {
|
||||
const [dialogDeleteSecretIsOpen, setDialogDeleteSecretIsOpen] = useState(false);
|
||||
const [HelpIsOpen, setHelpIsOpen] = useState(false);
|
||||
const [sheetIsOpen, setSheetIsOpen] = useState(false);
|
||||
const [sheetAppListOpen, setSheetAppListOpen] = useState(false);
|
||||
const [sheetRegisterIsOpen, setSheetRegisterIsOpen] = useState(false);
|
||||
const [modalProofStep, setModalProofStep] = useState(0);
|
||||
const [dateOfBirthDatePicker, setDateOfBirthDatePicker] = useState<Date | null>(null)
|
||||
const [dateOfExpiryDatePicker, setDateOfExpiryDatePicker] = useState<Date | null>(null)
|
||||
const [dateOfBirthDatePickerIsOpen, setDateOfBirthDatePickerIsOpen] = useState(false)
|
||||
const [dateOfExpiryDatePickerIsOpen, setDateOfExpiryDatePickerIsOpen] = useState(false)
|
||||
const [isFormComplete, setIsFormComplete] = useState(false);
|
||||
|
||||
const {
|
||||
passportNumber,
|
||||
@@ -73,16 +87,18 @@ const MainScreen: React.FC = () => {
|
||||
step,
|
||||
setStep,
|
||||
selectedTab,
|
||||
setSelectedTab,
|
||||
hideData,
|
||||
toast,
|
||||
showRegistrationErrorSheet,
|
||||
registrationErrorMessage,
|
||||
nfcSheetIsOpen,
|
||||
setNfcSheetIsOpen,
|
||||
} = useNavigationStore();
|
||||
|
||||
const handleRestart = () => {
|
||||
updateNavigationStore({
|
||||
selectedTab: "scan",
|
||||
selectedApp: null,
|
||||
selectedTab: "start",
|
||||
step: Steps.MRZ_SCAN,
|
||||
})
|
||||
deleteMrzFields();
|
||||
@@ -120,7 +136,6 @@ const MainScreen: React.FC = () => {
|
||||
useUserStore.getState().setDscSecret(secret);
|
||||
}
|
||||
|
||||
|
||||
const inputs_csca = getCSCAInputs(
|
||||
secret,
|
||||
dscCert,
|
||||
@@ -136,12 +151,19 @@ const MainScreen: React.FC = () => {
|
||||
toast.show("Using mock passport data!", { type: "info" })
|
||||
}
|
||||
|
||||
const castDate = (date: Date) => {
|
||||
return (date.toISOString().slice(2, 4) + date.toISOString().slice(5, 7) + date.toISOString().slice(8, 10)).toString();
|
||||
}
|
||||
|
||||
const decrementStep = () => {
|
||||
if (selectedTab === "nfc") {
|
||||
setStep(Steps.MRZ_SCAN);
|
||||
if (selectedTab === "scan") {
|
||||
setSelectedTab("start");
|
||||
}
|
||||
else if (selectedTab === "nfc") {
|
||||
setSelectedTab("scan");
|
||||
}
|
||||
else if (selectedTab === "next") {
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
setSelectedTab("nfc");
|
||||
}
|
||||
else if (selectedTab === "register") {
|
||||
setStep(Steps.NEXT_SCREEN);
|
||||
@@ -196,6 +218,7 @@ const MainScreen: React.FC = () => {
|
||||
throw new Error("Transaction failed");
|
||||
}
|
||||
setRegistered(true);
|
||||
setSelectedTab("app");
|
||||
setStep(Steps.REGISTERED);
|
||||
toast.show('✅', {
|
||||
message: "Registered",
|
||||
@@ -210,88 +233,117 @@ const MainScreen: React.FC = () => {
|
||||
}
|
||||
}, [modalProofStep]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (passportNumber?.length === 9 && (dateOfBirth?.length === 6 && dateOfExpiry?.length === 6)) {
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
}
|
||||
setIsFormComplete(passportNumber?.length === 9 && dateOfBirth?.length === 6 && dateOfExpiry?.length === 6);
|
||||
}, [passportNumber, dateOfBirth, dateOfExpiry]);
|
||||
|
||||
useEffect(() => {
|
||||
if (registered && step < Steps.REGISTERED) {
|
||||
setStep(Steps.REGISTERED);
|
||||
}
|
||||
}, [registered]);
|
||||
// useEffect(() => {
|
||||
// if (registered && step < Steps.REGISTERED) {
|
||||
// setStep(Steps.REGISTERED);
|
||||
// }
|
||||
// }, [registered]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
if (step == Steps.MRZ_SCAN) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "scan",
|
||||
})
|
||||
timeoutId = setTimeout(() => {
|
||||
setNFCScanIsOpen(false);
|
||||
}, 0);
|
||||
}
|
||||
else if (step == Steps.MRZ_SCAN_COMPLETED) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "nfc",
|
||||
})
|
||||
timeoutId = setTimeout(() => {
|
||||
setNFCScanIsOpen(false);
|
||||
}, 0);
|
||||
}
|
||||
else if (step == Steps.NEXT_SCREEN) {
|
||||
// Set the timeout and store its ID
|
||||
timeoutId = setTimeout(() => {
|
||||
setNFCScanIsOpen(false);
|
||||
}, 700);
|
||||
}
|
||||
else if (step == Steps.PROOF_GENERATED) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "mint",
|
||||
})
|
||||
}
|
||||
if (step == Steps.NEXT_SCREEN) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "next",
|
||||
})
|
||||
}
|
||||
if (step == Steps.REGISTER) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "register",
|
||||
})
|
||||
}
|
||||
if (step == Steps.REGISTERED) {
|
||||
updateNavigationStore({
|
||||
selectedTab: "app",
|
||||
})
|
||||
}
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [step]);
|
||||
// useEffect(() => {
|
||||
// let timeoutId: ReturnType<typeof setTimeout>;
|
||||
// if (step == Steps.START) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "start",
|
||||
// })
|
||||
// }
|
||||
|
||||
// if (step == Steps.MRZ_SCAN) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "scan",
|
||||
// })
|
||||
// timeoutId = setTimeout(() => {
|
||||
// setNFCScanIsOpen(false);
|
||||
// }, 0);
|
||||
// }
|
||||
// else if (step == Steps.MRZ_SCAN_COMPLETED) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "nfc",
|
||||
// })
|
||||
// timeoutId = setTimeout(() => {
|
||||
// setNFCScanIsOpen(false);
|
||||
// }, 0);
|
||||
// }
|
||||
// else if (step == Steps.NEXT_SCREEN) {
|
||||
// // Set the timeout and store its ID
|
||||
// timeoutId = setTimeout(() => {
|
||||
// setNFCScanIsOpen(false);
|
||||
// }, 700);
|
||||
// }
|
||||
// else if (step == Steps.PROOF_GENERATED) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "mint",
|
||||
// })
|
||||
// }
|
||||
// if (step == Steps.NEXT_SCREEN) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "next",
|
||||
// })
|
||||
// }
|
||||
// if (step == Steps.REGISTER) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "register",
|
||||
// })
|
||||
// }
|
||||
// if (step == Steps.REGISTERED) {
|
||||
// updateNavigationStore({
|
||||
// selectedTab: "app",
|
||||
// })
|
||||
// }
|
||||
// return () => {
|
||||
// if (timeoutId) {
|
||||
// clearTimeout(timeoutId);
|
||||
// }
|
||||
// };
|
||||
// }, [step]);
|
||||
|
||||
const { height } = useWindowDimensions();
|
||||
|
||||
return (
|
||||
<>
|
||||
<YStack f={1} bc="#161616" mt={Platform.OS === 'ios' ? "$8" : "$0"} >
|
||||
<YStack f={1}>
|
||||
<ToastViewport portalToRoot flexDirection="column-reverse" top={85} right={0} left={0} />
|
||||
<ToastMessage />
|
||||
<YStack f={1} mt={Platform.OS === 'ios' ? "$8" : "$0"} mb={Platform.OS === 'ios' ? "$4" : "$2"}>
|
||||
<YStack >
|
||||
<XStack jc="space-between" ai="center" px="$3">
|
||||
<Button p="$2" py="$3" unstyled onPress={decrementStep}><ChevronLeft color={(selectedTab === "scan") ? "transparent" : "#a0a0a0"} /></Button>
|
||||
<StepOneStepTwo variable={selectedTab} step1="scan" step2="nfc" />
|
||||
{selectedTab !== ("app") && selectedTab !== ("splash") && <XStack onPress={() => setSelectedTab("app")} px="$4" py="$2" mt="$3" alignSelf='flex-end'><X size={28} color={textBlack} /></XStack>}
|
||||
{selectedTab === "app" &&
|
||||
<XStack px="$4" py="$2" mt="$0" ai="center">
|
||||
<Text fontSize="$9" >Proof of Passport</Text>
|
||||
<XStack f={1} />
|
||||
|
||||
<Text fontSize="$6" color="#a0a0a0">
|
||||
{selectedTab === "scan" ? "Scan" : (selectedTab === "app" ? "Apps" : "Prove")}
|
||||
</Text>
|
||||
<XStack>
|
||||
<Button p="$2" py="$3" unstyled onPress={() => setSettingsIsOpen(true)}><Cog color="#a0a0a0" /></Button>
|
||||
<Button p="$2" py="$3" unstyled onPress={() => setHelpIsOpen(true)}><HelpCircle color="#a0a0a0" /></Button>
|
||||
<XStack onPress={() => setHelpIsOpen(true)}><HelpCircle size={28} color={textBlack} /></XStack>
|
||||
<XStack p="$2" onPress={() => setSettingsIsOpen(true)}><Cog size={24} color={textBlack} /></XStack>
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Sheet open={NFCScanIsOpen} onOpenChange={setNFCScanIsOpen} dismissOnSnapToBottom modal dismissOnOverlayPress={false} disableDrag animation="medium" snapPoints={[35]}>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
{/* {selectedTab !== "start" && selectedTab !== "scan" && selectedTab !== "nfc" && selectedTab !== "next" && selectedTab !== "register" && (
|
||||
<YStack>
|
||||
<XStack jc="space-between" ai="center" px="$3">
|
||||
<Button p="$2" py="$3" unstyled onPress={decrementStep}><ChevronLeft color={(selectedTab === "start") ? "transparent" : "#a0a0a0"} /></Button>
|
||||
|
||||
<Text fontSize="$6" color="#a0a0a0">
|
||||
{selectedTab === "scan" ? "Scan" : (selectedTab === "app" ? "Apps" : "Prove")}
|
||||
</Text>
|
||||
<XStack>
|
||||
<Button p="$2" py="$3" unstyled onPress={() => setSettingsIsOpen(true)}><Cog color="#a0a0a0" /></Button>
|
||||
<Button p="$2" py="$3" unstyled onPress={() => setHelpIsOpen(true)}><HelpCircle color="#a0a0a0" /></Button>
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Separator borderColor={separatorColor} />
|
||||
</YStack>
|
||||
)} */}
|
||||
<Sheet open={nfcSheetIsOpen} onOpenChange={setNfcSheetIsOpen} dismissOnSnapToBottom modal dismissOnOverlayPress={false} disableDrag animation="medium" snapPoints={[35]}>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame>
|
||||
<YStack gap="$5" f={1} pt="$3">
|
||||
@@ -421,6 +473,16 @@ const MainScreen: React.FC = () => {
|
||||
<Eraser color={textColor2} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
<Fieldset gap="$4" mt="$1" horizontal>
|
||||
<Label color={textColor1} width={200} justifyContent="flex-end" htmlFor="skip" >
|
||||
registered = (!registered)
|
||||
</Label>
|
||||
<Button bg={componentBgColor} jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" onPress={() => setRegistered(!registered)}>
|
||||
<UserPlus color={textColor2} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
|
||||
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -436,85 +498,91 @@ const MainScreen: React.FC = () => {
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
|
||||
<Sheet open={HelpIsOpen} onOpenChange={setHelpIsOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[88]}>
|
||||
<Sheet open={HelpIsOpen} onOpenChange={setHelpIsOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[76]}>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame bg={bgColor} borderRadius="$9">
|
||||
<YStack px="$3" pb="$5" flex={1} >
|
||||
<XStack ml="$2" mt="$3" gap="$2">
|
||||
<H2 color={textColor1}>Help</H2>
|
||||
<HelpCircle color={textColor1} mt="$1" alignSelf='center' size="$2" />
|
||||
<XStack justifyContent="flex-end" f={1} mt="$2" mr="$2" gap="$5">
|
||||
<Pressable onPress={() => Linking.openURL('https://proofofpassport.com')}>
|
||||
<Image
|
||||
source={{ uri: Internet, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://t.me/proofofpassport')}>
|
||||
<Image
|
||||
source={{ uri: Telegram, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://x.com/proofofpassport')}>
|
||||
<Image
|
||||
source={{ uri: X, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://github.com/zk-passport/proof-of-passport')}>
|
||||
<Image
|
||||
tintColor={textColor1}
|
||||
source={{ uri: Github, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Sheet.Frame bg={bgWhite} borderTopLeftRadius="$9" borderTopRightRadius="$9" pt="$2" pb="$3">
|
||||
<YStack p="$4" f={1} gap="$3">
|
||||
|
||||
<XStack>
|
||||
<Text fontSize="$8" mb="$2">Help 💁</Text>
|
||||
<XStack f={1} />
|
||||
<XStack onPress={() => setHelpIsOpen(false)} p="$2">
|
||||
<X color={borderColor} size="$1.5" mr="$2" />
|
||||
</XStack>
|
||||
</XStack>
|
||||
<YStack flex={1} mt="$3" jc="space-evenly">
|
||||
<YStack >
|
||||
<H3 color={textColor1}>Security and Privacy</H3>
|
||||
<Text color={textColor2} ml="$2" mt="$1">Proof of Passport uses zero-knowledge cryptography to allow you to prove facts about yourself like humanity, nationality or age without disclosing sensitive information.</Text>
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
|
||||
|
||||
<YStack flex={1} jc="space-between">
|
||||
{/* <YStack >
|
||||
<H3 color={textBlack}>Security and Privacy</H3>
|
||||
<Text color={textBlack} ml="$2" mt="$1">Proof of Passport uses zero-knowledge cryptography to allow you to prove facts about yourself like humanity, nationality or age without disclosing sensitive information.</Text>
|
||||
</YStack>
|
||||
<YStack >
|
||||
<H3 color={textColor1}>About ZK Proofs</H3>
|
||||
<Text color={textColor2} ml="$2" mt="$1">Zero-knowledge proofs rely on mathematical magic tricks to show the validity of some computation without revealing of all its inputs. In our case, the proof shows the passport has not been forged, but allows you to hide sensitive data.</Text>
|
||||
</YStack>
|
||||
<H3 color={textBlack}>About ZK Proofs</H3>
|
||||
<Text color={textBlack} ml="$2" mt="$1">Zero-knowledge proofs rely on mathematical magic tricks to show the validity of some computation without revealing of all its inputs. In our case, the proof shows the passport has not been forged, but allows you to hide sensitive data.</Text>
|
||||
</YStack> */}
|
||||
<YStack gap="$1">
|
||||
<H3 color={textColor1}>FAQ</H3>
|
||||
<H3 color={textBlack}>FAQ</H3>
|
||||
<YStack ml="$1">
|
||||
<H4 color={textColor1}>Troubleshoot NFC scanning</H4>
|
||||
<Text color={textColor2} ml="$2" >Refer to <Text onPress={() => Linking.openURL('https://zk-passport.github.io/posts/how-to-scan-your-passport-using-nfc/')} color={blueColorLight} style={{ textDecorationLine: 'underline', fontStyle: 'italic' }}>this tutorial</Text> on how to scan your passport using NFC.</Text>
|
||||
</YStack>
|
||||
<YStack ml="$1">
|
||||
<H4 color={textColor1}>My camera is down</H4>
|
||||
<Text color={textColor2} ml="$2">Go to settings and turn on the broken camera option.</Text>
|
||||
</YStack>
|
||||
<YStack ml="$1">
|
||||
<H4 color={textColor1}>My passport is not supported</H4>
|
||||
<Text color={textColor2} ml="$2">Please contact us on Telegram, or if you have programming skills, you can easily <Text onPress={() => Linking.openURL('https://t.me/proofofpassport')} color={blueColorLight} style={{ textDecorationLine: 'underline', fontStyle: 'italic' }}>contribute</Text> to the project by adding your signature algorithm.</Text>
|
||||
<H4 color={textBlack}>My passport is not supported</H4>
|
||||
<Text color={textBlack} ml="$2">Please contact us on Telegram, or if you have programming skills, you can easily <Text onPress={() => Linking.openURL('https://t.me/proofofpassport')} color={blueColorLight} style={{ textDecorationLine: 'underline', fontStyle: 'italic' }}>contribute</Text> to the project by adding your signature algorithm.</Text>
|
||||
</YStack>
|
||||
</YStack>
|
||||
|
||||
|
||||
|
||||
</YStack>
|
||||
{/* <Button mt="$3" bg={componentBgColor} jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" alignSelf='center' w="80%" onPress={() => setHelpIsOpen(false)}>
|
||||
<Text color={textColor1} w="80%" textAlign='center' fow="bold">Close</Text>
|
||||
</Button> */}
|
||||
<XStack justifyContent="center" mb="$2" gap="$5" mt="$8">
|
||||
<Pressable onPress={() => Linking.openURL('https://proofofpassport.com')}>
|
||||
<Image
|
||||
source={{ uri: Internet, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://t.me/proofofpassport')}>
|
||||
<Image
|
||||
source={{ uri: Telegram, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://x.com/proofofpassport')}>
|
||||
<Image
|
||||
source={{ uri: Xlogo, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => Linking.openURL('https://github.com/zk-passport/proof-of-passport')}>
|
||||
<Image
|
||||
tintColor={textBlack}
|
||||
source={{ uri: Github, width: 24, height: 24 }}
|
||||
/>
|
||||
</Pressable>
|
||||
</XStack>
|
||||
|
||||
</YStack>
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
|
||||
<Sheet open={sheetIsOpen} onOpenChange={setSheetIsOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[80]}>
|
||||
<Sheet open={sheetIsOpen} onOpenChange={setSheetIsOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[44]} moveOnKeyboardChange>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame bg={bgColor} borderRadius="$9" pt="$2">
|
||||
<Sheet.Frame bg={bgWhite} borderTopLeftRadius="$9" borderTopRightRadius="$9" pt="$2" pb="$3">
|
||||
<YStack p="$4" f={1} gap="$3">
|
||||
<Text fontSize="$6" mb="$4" color={textColor1}>Enter your the information manually</Text>
|
||||
<Fieldset gap="$4" horizontal>
|
||||
<Text color={textColor1} width={160} justifyContent="flex-end" fontSize="$4">
|
||||
<XStack>
|
||||
<Text fontSize="$8" mb="$">Manual input ✍️</Text>
|
||||
<XStack f={1} />
|
||||
<XStack onPress={() => setSheetIsOpen(false)} p="$2">
|
||||
<X color={borderColor} size="$1.5" mr="$2" />
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<Fieldset gap="$4" horizontal mt="$2">
|
||||
<Text color={textBlack} width={160} justifyContent="flex-end" fontSize="$5">
|
||||
Passport Number
|
||||
</Text>
|
||||
<Input
|
||||
bg={componentBgColor}
|
||||
color={textColor1}
|
||||
bg={bgWhite}
|
||||
color={textBlack}
|
||||
h="$3.5"
|
||||
borderColor={passportNumber?.length === 9 ? "green" : "unset"}
|
||||
borderColor={passportNumber?.length === 9 ? bgGreen : textBlack}
|
||||
flex={1}
|
||||
id="passportnumber"
|
||||
onChangeText={(text) => {
|
||||
@@ -524,42 +592,165 @@ const MainScreen: React.FC = () => {
|
||||
keyboardType="default"
|
||||
/>
|
||||
</Fieldset>
|
||||
|
||||
|
||||
<Fieldset gap="$4" horizontal>
|
||||
<Text color={textColor1} width={160} justifyContent="flex-end" fontSize="$4">
|
||||
Date of birth (yymmdd)
|
||||
<Text color={textBlack} width={160} justifyContent="flex-end" fontSize="$5">
|
||||
Date of birth
|
||||
</Text>
|
||||
<Input
|
||||
bg={componentBgColor}
|
||||
color={textColor1}
|
||||
h="$3.5"
|
||||
borderColor={dateOfBirth?.length === 6 ? "green" : "unset"}
|
||||
flex={1}
|
||||
id="dateofbirth"
|
||||
onChangeText={(text) => {
|
||||
update({ dateOfBirth: text })
|
||||
<Text color={textBlack} f={1}>
|
||||
{dateOfBirthDatePicker ? dateOfBirthDatePicker.toISOString().slice(0, 10) : ''}
|
||||
</Text>
|
||||
<Button bg={bgGreen} onPress={() => setDateOfBirthDatePickerIsOpen(true)}
|
||||
borderRadius={"$10"}
|
||||
>
|
||||
<CalendarSearch />
|
||||
</Button>
|
||||
<DatePicker
|
||||
modal
|
||||
mode='date'
|
||||
open={dateOfBirthDatePickerIsOpen}
|
||||
date={dateOfBirthDatePicker || new Date()}
|
||||
onConfirm={(date) => {
|
||||
setDateOfBirthDatePickerIsOpen(false)
|
||||
setDateOfBirthDatePicker(date)
|
||||
update({ dateOfBirth: castDate(date) })
|
||||
}}
|
||||
onCancel={() => {
|
||||
setDateOfBirthDatePickerIsOpen(false)
|
||||
}}
|
||||
value={dateOfBirth}
|
||||
keyboardType={Platform.OS === "ios" ? "default" : "number-pad"}
|
||||
/>
|
||||
</Fieldset>
|
||||
<Fieldset gap="$4" horizontal>
|
||||
<Text color={textColor1} width={160} justifyContent="flex-end" fontSize="$4">
|
||||
Date of expiry (yymmdd)
|
||||
<Text color={textBlack} width={160} justifyContent="flex-end" fontSize="$5">
|
||||
Date of expiry
|
||||
</Text>
|
||||
<Input
|
||||
bg={componentBgColor}
|
||||
color={textColor1}
|
||||
h="$3.5"
|
||||
borderColor={dateOfExpiry?.length === 6 ? "green" : "unset"}
|
||||
flex={1}
|
||||
id="dateofexpiry"
|
||||
onChangeText={(text) => {
|
||||
update({ dateOfExpiry: text })
|
||||
<Text color={textBlack} f={1}>
|
||||
{dateOfExpiryDatePicker ? dateOfExpiryDatePicker.toISOString().slice(0, 10) : ''}
|
||||
</Text>
|
||||
<Button bg={bgGreen} onPress={() => setDateOfExpiryDatePickerIsOpen(true)}
|
||||
borderRadius="$10"
|
||||
>
|
||||
<CalendarSearch />
|
||||
</Button>
|
||||
<DatePicker
|
||||
modal
|
||||
mode='date'
|
||||
open={dateOfExpiryDatePickerIsOpen}
|
||||
date={dateOfExpiryDatePicker || new Date()}
|
||||
onConfirm={(date) => {
|
||||
setDateOfExpiryDatePickerIsOpen(false)
|
||||
setDateOfExpiryDatePicker(date)
|
||||
update({ dateOfExpiry: castDate(date) })
|
||||
}}
|
||||
onCancel={() => {
|
||||
setDateOfExpiryDatePickerIsOpen(false)
|
||||
}}
|
||||
value={dateOfExpiry}
|
||||
keyboardType={Platform.OS === "ios" ? "default" : "number-pad"}
|
||||
/>
|
||||
</Fieldset>
|
||||
<XStack f={1} />
|
||||
<YStack gap="$2">
|
||||
<CustomButton
|
||||
text="Submit"
|
||||
onPress={() => {
|
||||
setSelectedTab("nfc");
|
||||
setSheetIsOpen(false);
|
||||
}}
|
||||
bgColor={isFormComplete ? bgGreen : separatorColor}
|
||||
isDisabled={!isFormComplete}
|
||||
disabledOnPress={() => toast.show('✍️', {
|
||||
message: "Please fill in all fields.",
|
||||
customData: {
|
||||
type: "info",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</YStack>
|
||||
|
||||
</YStack>
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
|
||||
<Sheet open={sheetAppListOpen} onOpenChange={setSheetAppListOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[35]}>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame bg={bgWhite} borderTopLeftRadius="$9" borderTopRightRadius="$9" pt="$2" mb="$3">
|
||||
<YStack p="$4" f={1} gap="$3">
|
||||
<XStack>
|
||||
<Text fontSize="$8" mb="$2">Applications</Text>
|
||||
<XStack f={1} />
|
||||
<XStack onPress={() => setSheetAppListOpen(false)} p="$2">
|
||||
<X color={borderColor} size="$1.5" mr="$2" />
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<XStack f={1} />
|
||||
<YStack gap="$2">
|
||||
<CustomButton
|
||||
text="Zupass"
|
||||
onPress={() => toast.show('😖', {
|
||||
message: "Work in progress",
|
||||
customData: {
|
||||
type: "info",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
<CustomButton
|
||||
text="Gitcoin passport"
|
||||
onPress={() => toast.show('😖', {
|
||||
message: "Work in progress",
|
||||
customData: {
|
||||
type: "info",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
<CustomButton
|
||||
text="SBT"
|
||||
onPress={() => toast.show('😖', {
|
||||
message: "Work in progress",
|
||||
customData: {
|
||||
type: "info",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</YStack>
|
||||
<XStack f={1} />
|
||||
|
||||
</YStack>
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
|
||||
<Sheet open={sheetRegisterIsOpen} onOpenChange={setSheetRegisterIsOpen} dismissOnSnapToBottom modal animation="medium" snapPoints={[35]}>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame bg={bgWhite} borderTopLeftRadius="$9" borderTopRightRadius="$9" pt="$2" >
|
||||
<YStack p="$4" f={1} gap="$3">
|
||||
<XStack>
|
||||
<Text fontSize="$8" mb="$2">👋 Not registered yet?</Text>
|
||||
<XStack f={1} />
|
||||
<XStack onPress={() => setSheetRegisterIsOpen(false)} p="$2">
|
||||
<X color={borderColor} size="$1.5" mr="$2" />
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$7" color={textBlack}>Registering to Proof of Passport does not leak anything about your personal information.</Text>
|
||||
<Text fontSize="$6" onPress={() => Linking.openURL('https://zk-passport.github.io/posts/how-to-scan-your-passport-using-nfc/')} color={blueColorLight} style={{ textDecorationLine: 'underline', fontStyle: 'italic' }}>Learn more.</Text>
|
||||
</YStack>
|
||||
|
||||
<XStack f={1} />
|
||||
<YStack gap="$2">
|
||||
<CustomButton
|
||||
text="Register"
|
||||
Icon={<UserPlus color={textBlack} />}
|
||||
onPress={() => {
|
||||
setSheetRegisterIsOpen(false);
|
||||
setSelectedTab("start");
|
||||
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
<XStack f={1} />
|
||||
|
||||
</YStack>
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
@@ -574,33 +765,43 @@ const MainScreen: React.FC = () => {
|
||||
dismissOnSnapToBottom modal animation="medium" snapPoints={[80]}
|
||||
>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame bg={bgColor} borderRadius="$9" pt="$2">
|
||||
<YStack p="$4" f={1} gap="$3">
|
||||
<H2 textAlign='center' mb="$6" color={textColor1}>Passport unsupported</H2>
|
||||
<Text fontSize="$6" mb="$4" color={textColor1}>Unfortunately, your passport is currently not supported. Details:</Text>
|
||||
<Text fontSize="$6" mb="$4" textAlign="center" color="#a0a0a0">{registrationErrorMessage} </Text>
|
||||
<Sheet.Frame bg={bgWhite} borderRadius="$9" pt="$2">
|
||||
<YStack p="$4" f={1} gap="$3" pb="$6">
|
||||
<YStack jc="flex-start" >
|
||||
<Text fontSize="$9" textAlign='left' mb="$2" color={textBlack}>Sorry, an error has occurred</Text>
|
||||
</YStack>
|
||||
|
||||
<Text fontSize="$6" mb="$4" color={textColor1}>To help us add support for it, please consider contributing its data!</Text>
|
||||
<Fieldset gap="$4" mt="$1" horizontal>
|
||||
<Label color={textColor1} width={200} justifyContent="flex-end" htmlFor="restart">
|
||||
Contribute
|
||||
</Label>
|
||||
<Button bg={componentBgColor} jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" onPress={() => setDialogContributeIsOpen(true)}>
|
||||
<Share color={textColor1} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
<Text fontSize="$7">Error details:</Text>
|
||||
<Text fontSize="$6" mb="$2" textAlign="center" color="#a0a0a0">{registrationErrorMessage} </Text>
|
||||
|
||||
<Separator borderColor={separatorColor} />
|
||||
<Text mt="$4" fontSize="$6" mb="$4" color={textBlack}>Unfortunately, your passport is currently not supported.</Text>
|
||||
|
||||
<Text fontSize="$6" mb="$4" color={textBlack}>To help us add support for it, please consider contributing its data!</Text>
|
||||
<XStack f={1} />
|
||||
<CustomButton
|
||||
text="Contribute"
|
||||
onPress={() => setDialogContributeIsOpen(true)}
|
||||
Icon={<Share />}
|
||||
/>
|
||||
</YStack>
|
||||
</Sheet.Frame>
|
||||
</Sheet>
|
||||
|
||||
<XStack bc="#343434" h={1.2} />
|
||||
</YStack>
|
||||
<Tabs f={1} orientation="horizontal" flexDirection="column" defaultValue={"scan"}
|
||||
|
||||
<Tabs f={1} orientation="horizontal" flexDirection="column" defaultValue={"splash"}
|
||||
value={selectedTab}
|
||||
onValueChange={(value) => updateNavigationStore({ selectedTab: value })}
|
||||
>
|
||||
<ToastViewport flexDirection="column-reverse" top={15} right={0} left={0} />
|
||||
<ToastMessage />
|
||||
<Tabs.Content value="splash" f={1}>
|
||||
<SplashScreen
|
||||
/>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="start" f={1}>
|
||||
<StartScreen
|
||||
/>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="scan" f={1}>
|
||||
<CameraScreen
|
||||
sheetIsOpen={sheetIsOpen}
|
||||
@@ -619,15 +820,27 @@ const MainScreen: React.FC = () => {
|
||||
<RegisterScreen />
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="app" f={1}>
|
||||
<AppScreen />
|
||||
<AppScreen
|
||||
setSheetAppListOpen={setSheetAppListOpen}
|
||||
setSheetRegisterIsOpen={setSheetRegisterIsOpen}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="prove" f={1}>
|
||||
<ProveScreen />
|
||||
<ProveScreen
|
||||
setSheetRegisterIsOpen={setSheetRegisterIsOpen}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="mint" f={1}>
|
||||
<SendProofScreen />
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="valid" f={1}>
|
||||
<ValidProofScreen />
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="wrong" f={1}>
|
||||
<WrongProofScreen />
|
||||
</Tabs.Content>
|
||||
</Tabs>
|
||||
|
||||
</YStack>
|
||||
<Modal visible={showWarningModal.show} animationType="slide" transparent={true}>
|
||||
<YStack bc="#161616" p={20} ai="center" jc="center" position="absolute" top={0} bottom={0} left={0} right={0}>
|
||||
@@ -656,7 +869,7 @@ const MainScreen: React.FC = () => {
|
||||
</YStack>
|
||||
</YStack>
|
||||
</Modal>
|
||||
</>
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack, Text, Button, Image, useWindowDimensions, Fieldset } from 'tamagui';
|
||||
import { Info } from '@tamagui/lucide-icons';
|
||||
import { ArrowRight, Info } from '@tamagui/lucide-icons';
|
||||
import { getFirstName, maskString } from '../../utils/utils';
|
||||
import { attributeToPosition } from '../../../common/src/constants/constants';
|
||||
import USER from '../images/user.png'
|
||||
import { borderColor, componentBgColor, textColor1, textColor2 } from '../utils/colors';
|
||||
import { bgGreen, borderColor, componentBgColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import { Platform } from 'react-native';
|
||||
import { formatAttribute, Steps } from '../utils/utils';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
|
||||
|
||||
const NextScreen: React.FC = () => {
|
||||
const {
|
||||
hideData,
|
||||
setStep,
|
||||
setSelectedTab
|
||||
|
||||
} = useNavigationStore()
|
||||
|
||||
@@ -32,8 +34,8 @@ const NextScreen: React.FC = () => {
|
||||
const { height } = useWindowDimensions();
|
||||
|
||||
return (
|
||||
<YStack px="$4" f={1} mb={Platform.OS === 'ios' ? "$5" : "$0"}>
|
||||
<YStack flex={1} mx="$2" gap="$2">
|
||||
<YStack p="$3" f={1} mb={Platform.OS === 'ios' ? "$5" : "$0"}>
|
||||
<YStack flex={1} mx="$2" gap="$2" mt="$2">
|
||||
<YStack alignSelf='center' my="$3">
|
||||
{hideData
|
||||
? <Image
|
||||
@@ -54,17 +56,19 @@ const NextScreen: React.FC = () => {
|
||||
/>
|
||||
}
|
||||
</YStack>
|
||||
<Text color={textColor1} fontSize="$5" fontWeight="bold">
|
||||
<Text color={textBlack} fontSize="$8" mt="$8" >
|
||||
Hi{" "}
|
||||
{
|
||||
hideData
|
||||
? maskString(getFirstName(passportData.mrz))
|
||||
: getFirstName(passportData.mrz)
|
||||
}
|
||||
<Text color={textBlack} fontSize="$8" style={{
|
||||
textDecorationLine: "underline", textDecorationColor: bgGreen
|
||||
}}>{
|
||||
hideData
|
||||
? maskString(getFirstName(passportData.mrz))
|
||||
: getFirstName(passportData.mrz)
|
||||
}</Text>
|
||||
{" "}👋
|
||||
</Text>
|
||||
|
||||
<YStack gap="$2.5" mt="$2" ml="$2">
|
||||
<YStack gap="$2" mt="$4" >
|
||||
{Object.keys(disclosureOptions).map((key) => {
|
||||
const key_ = key;
|
||||
const indexes = attributeToPosition[key_ as keyof typeof attributeToPosition];
|
||||
@@ -74,11 +78,15 @@ const NextScreen: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Fieldset horizontal key={key} gap="$3" alignItems='center'>
|
||||
<Text color={textColor2} w="$10" justifyContent="flex-end" >
|
||||
<Text color={textBlack} w="$10" justifyContent="flex-end" fontSize="$5" style={{
|
||||
opacity: 0.7
|
||||
}}>
|
||||
{keyFormatted}:
|
||||
</Text>
|
||||
<Text
|
||||
color={textColor1}
|
||||
color={textBlack}
|
||||
fontSize="$5"
|
||||
|
||||
>
|
||||
{hideData ? maskString(mrzAttributeFormatted) : mrzAttributeFormatted}
|
||||
</Text>
|
||||
@@ -89,20 +97,15 @@ const NextScreen: React.FC = () => {
|
||||
</YStack>
|
||||
<YStack f={1} />
|
||||
|
||||
<XStack mt="$6" bg={componentBgColor} borderRadius={100} borderWidth={1} borderColor={borderColor} py="$2.5" px="$3">
|
||||
<Info alignSelf='center' size={24} color={textColor1} />
|
||||
<Text ml="$3" pr="$6" fontSize="$3" color={textColor1}>Your information will remain confidential and will not be used or shared without your explicit consent.</Text>
|
||||
<XStack bg="#ffff" borderRadius={100} py="$2.5" px="$3">
|
||||
<Info alignSelf='center' size={24} color={textBlack} />
|
||||
<Text ml="$3" pr="$6" fontSize="$3" color={textBlack}>Your information will remain confidential and will not be used or shared without your explicit consent.</Text>
|
||||
</XStack>
|
||||
<Button
|
||||
mt="$8"
|
||||
alignSelf='center'
|
||||
onPress={() => setStep(Steps.REGISTER)}
|
||||
borderWidth={1.3} borderColor={borderColor} borderRadius="$10" bg="#3185FC"
|
||||
mb="$6"
|
||||
w="100%"
|
||||
>
|
||||
<Text color="white" fontSize="$5">Next</Text>
|
||||
</Button>
|
||||
|
||||
<YStack f={1} />
|
||||
|
||||
<CustomButton onPress={() => setSelectedTab("register")} text="Next" Icon={<ArrowRight color={textBlack} />} />
|
||||
|
||||
</YStack >
|
||||
</YStack >
|
||||
);
|
||||
|
||||
@@ -1,57 +1,100 @@
|
||||
import React from 'react';
|
||||
import { YStack, Text, XStack, Button, Image } from 'tamagui';
|
||||
import { Nfc } from '@tamagui/lucide-icons';
|
||||
import { blueColorDark, blueColorLight, borderColor, componentBgColor2, greenColorDark, greenColorLight, redColorDark, redColorLight, textColor1, textColor2 } from '../utils/colors';
|
||||
import NFCHelp from '../images/nfc_help.png'
|
||||
import React, { useState } from 'react';
|
||||
import { YStack, Text, XStack, Button, ScrollView } from 'tamagui';
|
||||
import { Nfc, X } from '@tamagui/lucide-icons';
|
||||
import { bgGreen, borderColor, textBlack, textColor1 } from '../utils/colors';
|
||||
import { Carousel } from '../components/Carousel';
|
||||
import US_PASSPORT from '../images/us-passport.png'
|
||||
import REMOVE_CASE from '../images/remove_case.png'
|
||||
import US_PASSPORT_LASTPAGE from '../images/passport_lastpage_graybg.png'
|
||||
import US_PASSPORT_LASTPAGE_IOS from '../images/passport_lastpage_iphone.png'
|
||||
import US_PASSPORT_LASTPAGE_ANDROID from '../images/passport_lastpage_android.png'
|
||||
import PHONE_SCANBUTTON from "../images/phone_scanbutton.png"
|
||||
|
||||
import Dialog from "react-native-dialog";
|
||||
import NfcManager from 'react-native-nfc-manager';
|
||||
import { Platform, Linking, Dimensions } from 'react-native';
|
||||
|
||||
interface NfcScreenProps {
|
||||
handleNFCScan: () => void;
|
||||
}
|
||||
|
||||
|
||||
const NfcScreen: React.FC<NfcScreenProps> = ({ handleNFCScan }) => {
|
||||
const [isLastSlideReached, setIsLastSlideReached] = useState(false);
|
||||
const [dialogVisible, setDialogVisible] = useState(false);
|
||||
const [dialogMessage, setDialogMessage] = useState('');
|
||||
const [isNfcSupported, setIsNfcSupported] = useState(true);
|
||||
const carouselImages = [US_PASSPORT, REMOVE_CASE, US_PASSPORT_LASTPAGE, Platform.OS === 'ios' ? US_PASSPORT_LASTPAGE_IOS : US_PASSPORT_LASTPAGE_ANDROID, PHONE_SCANBUTTON,];
|
||||
const windowHeight = Dimensions.get('window').height;
|
||||
|
||||
const handleSlideChange = (index: number) => {
|
||||
if (index === carouselImages.length - 1) {
|
||||
setIsLastSlideReached(true);
|
||||
}
|
||||
};
|
||||
|
||||
const openNfcSettings = () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
Linking.openURL('App-Prefs:root=General&path=About');
|
||||
} else {
|
||||
Linking.sendIntent('android.settings.NFC_SETTINGS');
|
||||
}
|
||||
setDialogVisible(false);
|
||||
};
|
||||
|
||||
const checkNfcSupport = async () => {
|
||||
const isSupported = await NfcManager.isSupported();
|
||||
if (isSupported) {
|
||||
const isEnabled = await NfcManager.isEnabled();
|
||||
if (!isEnabled) {
|
||||
setDialogMessage('NFC is not enabled. Would you like to enable it in settings?');
|
||||
setDialogVisible(true);
|
||||
setIsNfcSupported(true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
setDialogMessage("Sorry, your device doesn't seem to have an NFC reader.");
|
||||
setDialogVisible(true);
|
||||
setIsNfcSupported(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleNfcScan = async () => {
|
||||
const nfcSupported = await checkNfcSupport();
|
||||
if (nfcSupported) {
|
||||
handleNFCScan();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$3">
|
||||
|
||||
<Image borderRadius="$5" alignSelf='center'
|
||||
w="$12"
|
||||
h="$14"
|
||||
source={{ uri: NFCHelp }}
|
||||
/>
|
||||
|
||||
<YStack f={1} gap="$2">
|
||||
<YStack mt="$2">
|
||||
<Text fontSize="$7" fow="bold" mt="$1" color={textColor1}>Scan the NFC chip in your passport.</Text>
|
||||
<Text fontSize="$6" color={textColor1} mt="$2">How do I find and scan the NFC chip?</Text>
|
||||
<YStack ml="$3" gap="$2" mt="$1" >
|
||||
<XStack gap="$1">
|
||||
<Text fontSize="$4" color={textColor2}>1.</Text>
|
||||
<Text fontSize="$4" color={textColor2}>Close your passport and hold the middle of the back cover of your passport to the top of the phoneThe passport should touch the phone.</Text>
|
||||
<ScrollView flex={1} contentContainerStyle={{ flexGrow: 1 }}>
|
||||
<YStack f={1} p="$3" >
|
||||
{/* <Text fontSize="$8" fow="bold" mt="$1.5" mb="$3" color={textColor1} textAlign='center'>Verify your passport using NFC</Text> */}
|
||||
<Text fontSize="$9" mt="$0" color={textBlack} mb="$4" ml="$2">Verify your passport using <Text fontSize="$9" color={textBlack} style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>NFC</Text></Text>
|
||||
<Carousel
|
||||
images={carouselImages}
|
||||
height={300}
|
||||
onSlideChange={handleSlideChange}
|
||||
handleNfcScan={handleNfcScan}
|
||||
/>
|
||||
<Dialog.Container visible={dialogVisible}>
|
||||
<Dialog.Title>NFC Status</Dialog.Title>
|
||||
<Dialog.Description>
|
||||
{dialogMessage}
|
||||
</Dialog.Description>
|
||||
{isNfcSupported ? (
|
||||
<XStack>
|
||||
<XStack f={1} />
|
||||
<Dialog.Button label="Open Settings" onPress={openNfcSettings} />
|
||||
</XStack>
|
||||
<XStack gap="$1">
|
||||
<Text fontSize="$4" color={textColor2}>2.</Text>
|
||||
<Text fontSize="$4" color={textColor2}>If that does not work, try using the front cover of your passport.</Text>
|
||||
</XStack>
|
||||
<XStack gap="$1">
|
||||
<Text fontSize="$4" color={textColor2}>3.</Text>
|
||||
<Text fontSize="$4" color={textColor2}>Move your phone slowly up and down until scanning starts.</Text>
|
||||
</XStack>
|
||||
<XStack gap="$1">
|
||||
<Text fontSize="$4" color={textColor2}>4.</Text>
|
||||
<Text fontSize="$4" color={textColor2}>Hold your device still when scanning starts.</Text>
|
||||
</XStack>
|
||||
</YStack>
|
||||
|
||||
</YStack>
|
||||
|
||||
) : (
|
||||
<Dialog.Button label="OK" onPress={() => setDialogVisible(false)} />
|
||||
)}
|
||||
</Dialog.Container>
|
||||
</YStack>
|
||||
|
||||
<YStack gap="$2" mb="$6">
|
||||
<Button borderWidth={1.3} borderColor={borderColor} borderRadius="$10" bg="#3185FC" onPress={handleNFCScan}><Nfc color={textColor1} /></Button>
|
||||
</YStack>
|
||||
|
||||
</YStack >
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
export default NfcScreen;
|
||||
export default NfcScreen;
|
||||
31
app/src/screens/NoSkipCarousel.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { YStack, Button, Image, Text, styled } from 'tamagui';
|
||||
import { Camera, SquarePen, UserPlus } from '@tamagui/lucide-icons';
|
||||
import { bgColor, borderColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import { Steps } from "../utils/utils";
|
||||
import CustomButton from '../components/CustomButton';
|
||||
|
||||
const NoSkipCarousel: React.FC = () => {
|
||||
const textStyle = styled(Text, {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: textBlack,
|
||||
});
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$3" bg="white">
|
||||
<YStack f={1} jc="center">
|
||||
<YStack gap="$0.5" mt="$3.5">
|
||||
<Text fontSize="$9" mt="$1" >Lorem ipsum doflor siat amet</Text>
|
||||
<Text fontSize="$2" mt="$2" color={textBlack}>Lorem ipsum dolor sit amet</Text>
|
||||
</YStack>
|
||||
|
||||
</YStack>
|
||||
<CustomButton text="Let's start" onPress={() => {
|
||||
console.log("Let's start");
|
||||
}} />
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
export default NoSkipCarousel;
|
||||
@@ -1,46 +1,177 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { YStack, XStack, Text, Checkbox, Input, Button, Spinner, Image, useWindowDimensions, ScrollView } from 'tamagui';
|
||||
import { Check, Plus, Minus, PenTool } from '@tamagui/lucide-icons';
|
||||
import { getFirstName, maskString } from '../../utils/utils';
|
||||
import { attributeToPosition } from '../../../common/src/constants/constants';
|
||||
import { YStack, XStack, Text, Input, Button, Spinner, Image, useWindowDimensions, ScrollView, Fieldset } from 'tamagui';
|
||||
import { Check, CheckCircle, CheckCircle2, Share, } from '@tamagui/lucide-icons';
|
||||
import { attributeToPosition, DEFAULT_MAJORITY, } from '../../../common/src/constants/constants';
|
||||
import USER from '../images/user.png'
|
||||
import { borderColor, componentBgColor, componentBgColor2, textColor1, textColor2 } from '../utils/colors';
|
||||
import { bgGreen, borderColor, componentBgColor, componentBgColor2, separatorColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import { ethers } from 'ethers';
|
||||
import { Platform } from 'react-native';
|
||||
import { formatAttribute, Steps } from '../utils/utils';
|
||||
import { downloadZkey } from '../utils/zkeyDownload';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { AppType } from '../utils/appType';
|
||||
import { AppType } from '../../../common/src/utils/appType';
|
||||
import useSbtStore from '../stores/sbtStore';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import { generateCircuitInputsDisclose } from '../../../common/src/utils/generateInputs';
|
||||
import { PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
import axios from 'axios';
|
||||
import { stringToNumber } from '../../../common/src/utils/utils';
|
||||
import { revealBitmapFromAttributes } from '../../../common/src/utils/revealBitmap';
|
||||
import { getTreeFromTracker } from '../../../common/src/utils/pubkeyTree';
|
||||
import { generateProof } from '../utils/prover';
|
||||
import io, { Socket } from 'socket.io-client';
|
||||
|
||||
export const appStoreMapping = {
|
||||
'soulbound': useSbtStore,
|
||||
// Add more app ID to store mappings as needed
|
||||
};
|
||||
interface ProveScreenProps {
|
||||
setSheetRegisterIsOpen: (value: boolean) => void;
|
||||
}
|
||||
|
||||
const ProveScreen: React.FC = () => {
|
||||
const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) => {
|
||||
const [generatingProof, setGeneratingProof] = useState(false);
|
||||
const selectedApp = useNavigationStore(state => state.selectedApp) as AppType;
|
||||
const {
|
||||
hideData,
|
||||
isZkeyDownloading,
|
||||
step,
|
||||
toast,
|
||||
setSelectedTab
|
||||
} = useNavigationStore()
|
||||
|
||||
const {
|
||||
fields,
|
||||
handleProve,
|
||||
circuit,
|
||||
} = selectedApp
|
||||
secret,
|
||||
setProofVerificationResult
|
||||
} = useUserStore()
|
||||
|
||||
const useAppStore = appStoreMapping[selectedApp.id as keyof typeof appStoreMapping]
|
||||
const [proofStatus, setProofStatus] = useState<string>('');
|
||||
|
||||
const {
|
||||
address,
|
||||
majority,
|
||||
disclosure,
|
||||
update
|
||||
} = useAppStore();
|
||||
const [socket, setSocket] = useState<Socket | null>(null);
|
||||
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
|
||||
const waitForSocketConnection = (socket: Socket): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
if (socket.connected) {
|
||||
resolve();
|
||||
} else {
|
||||
socket.once('connect', () => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const newSocket = io('https://proofofpassport-merkle-tree.xyz', {
|
||||
path: '/websocket',
|
||||
transports: ['websocket'],
|
||||
query: { sessionId: selectedApp.userId, clientType: 'mobile' }
|
||||
});
|
||||
|
||||
newSocket.on('connect', () => {
|
||||
console.log('Connected to WebSocket server');
|
||||
});
|
||||
|
||||
newSocket.on('disconnect', () => {
|
||||
console.log('Disconnected from WebSocket server');
|
||||
});
|
||||
|
||||
newSocket.on('connect_error', (error) => {
|
||||
console.error('Connection error:', error);
|
||||
});
|
||||
|
||||
newSocket.on('proof_verification_result', (result) => {
|
||||
console.log('Proof verification result:', result);
|
||||
setProofVerificationResult(JSON.parse(result));
|
||||
setProofStatus(`Proof verification result: ${result}`);
|
||||
console.log("result", result);
|
||||
setSelectedTab(JSON.parse(result).valid ? "valid" : "wrong");
|
||||
});
|
||||
|
||||
setSocket(newSocket);
|
||||
|
||||
return () => {
|
||||
newSocket.disconnect();
|
||||
};
|
||||
}, [selectedApp.userId]);
|
||||
|
||||
const handleProve = async () => {
|
||||
try {
|
||||
setIsConnecting(true);
|
||||
setGeneratingProof(true);
|
||||
|
||||
if (!socket) {
|
||||
throw new Error('Socket not initialized');
|
||||
}
|
||||
|
||||
await waitForSocketConnection(socket);
|
||||
|
||||
setIsConnecting(false);
|
||||
setProofStatus('Generating proof...');
|
||||
socket.emit('proof_generation_start', { sessionId: selectedApp.userId });
|
||||
|
||||
const tree = await getTreeFromTracker();
|
||||
|
||||
const inputs = generateCircuitInputsDisclose(
|
||||
secret,
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
passportData,
|
||||
tree as any,
|
||||
(selectedApp.disclosureOptions && selectedApp.disclosureOptions.older_than) ? selectedApp.disclosureOptions.older_than : DEFAULT_MAJORITY,
|
||||
revealBitmapFromAttributes(selectedApp.disclosureOptions as any),
|
||||
selectedApp.scope,
|
||||
stringToNumber(selectedApp.userId).toString()
|
||||
);
|
||||
|
||||
console.log("inputs", inputs);
|
||||
const localProof = await generateProof(
|
||||
selectedApp.circuit,
|
||||
inputs,
|
||||
);
|
||||
|
||||
setProofStatus('Sending proof to verification...');
|
||||
// console.log("localProof", localProof);
|
||||
|
||||
// Send the proof via WebSocket
|
||||
const formattedLocalProof = {
|
||||
proof: {
|
||||
pi_a: [
|
||||
localProof.proof.a[0],
|
||||
localProof.proof.a[1],
|
||||
"1"
|
||||
],
|
||||
pi_b: [
|
||||
[localProof.proof.b[0][0], localProof.proof.b[0][1]],
|
||||
[localProof.proof.b[1][0], localProof.proof.b[1][1]],
|
||||
["1", "0"]
|
||||
],
|
||||
pi_c: [
|
||||
localProof.proof.c[0],
|
||||
localProof.proof.c[1],
|
||||
"1"
|
||||
],
|
||||
protocol: "groth16",
|
||||
curve: "bn128"
|
||||
},
|
||||
publicSignals: (localProof as any).pub_signals
|
||||
};
|
||||
// console.log("formattedLocalProof", formattedLocalProof);
|
||||
socket.emit('proof_generated', { sessionId: selectedApp.userId, proof: formattedLocalProof });
|
||||
|
||||
// Wait for verification result
|
||||
const verificationResult = await new Promise((resolve) => {
|
||||
socket.once('proof_verification_result', resolve);
|
||||
});
|
||||
|
||||
setProofStatus(`Proof verification result: ${(verificationResult)}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in handleProve:', error);
|
||||
setProofStatus(`Error: ${error || 'An unknown error occurred'}`);
|
||||
} finally {
|
||||
setGeneratingProof(false);
|
||||
setIsConnecting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
registered,
|
||||
@@ -49,213 +180,81 @@ const ProveScreen: React.FC = () => {
|
||||
|
||||
const handleDisclosureChange = (field: string) => {
|
||||
const requiredOrOptional = selectedApp.disclosureOptions[field as keyof typeof selectedApp.disclosureOptions];
|
||||
|
||||
if (requiredOrOptional === 'required') {
|
||||
return;
|
||||
}
|
||||
|
||||
update({
|
||||
disclosure: {
|
||||
...disclosure,
|
||||
[field]: !disclosure[field as keyof typeof disclosure]
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const { height } = useWindowDimensions();
|
||||
|
||||
useEffect(() => {
|
||||
// this already checks if downloading is required
|
||||
downloadZkey(circuit);
|
||||
}, [])
|
||||
|
||||
const disclosureFieldsToText = (key: string, value: string = "") => {
|
||||
if (key === 'older_than') {
|
||||
return `I am older than ${value} years old.`;
|
||||
}
|
||||
if (key === 'nationality') {
|
||||
return `I have a valid passport from ${value}.`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack px="$4" f={1} mb={Platform.OS === 'ios' ? "$5" : "$0"}>
|
||||
<YStack flex={1} mx="$2" gap="$2">
|
||||
<YStack alignSelf='center' my="$3">
|
||||
{hideData
|
||||
? <Image
|
||||
w={height > 750 ? 150 : 100}
|
||||
h={height > 750 ? 190 : 80}
|
||||
borderRadius={height > 800 ? "$7" : "$6"}
|
||||
source={{
|
||||
uri: USER,
|
||||
}}
|
||||
/>
|
||||
: <Image
|
||||
w={height > 750 ? 150 : 110}
|
||||
h={height > 750 ? 190 : 130}
|
||||
borderRadius={height > 750 ? "$7" : "$6"}
|
||||
source={{
|
||||
uri: passportData.photoBase64 ?? USER,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</YStack>
|
||||
<Text color={textColor1} fontSize="$5" fontWeight="bold" ml="$2" mb="$1">
|
||||
Hi{" "}
|
||||
{
|
||||
hideData
|
||||
? maskString(getFirstName(passportData.mrz))
|
||||
: getFirstName(passportData.mrz)
|
||||
}
|
||||
{" "}👋
|
||||
<YStack f={1} p="$3">
|
||||
|
||||
{Object.keys(selectedApp.disclosureOptions as any).length > 0 ? <YStack mt="$4">
|
||||
<Text fontSize="$9">
|
||||
<Text fow="bold" style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>{selectedApp.name}</Text> is requesting you to prove the following information.
|
||||
</Text>
|
||||
<Text mt="$3" fontSize="$8" color={textBlack} style={{ opacity: 0.9 }}>
|
||||
|
||||
{fields.map((Field, index) => (
|
||||
<Field key={index} />
|
||||
))}
|
||||
No <Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>other</Text> information than the one selected below will be shared with {selectedApp.name}.
|
||||
</Text>
|
||||
</YStack> :
|
||||
<Text fontSize="$9">
|
||||
<Text fow="bold" style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>{selectedApp.name}</Text> is requesting you to prove you own a valid passport.
|
||||
</Text>
|
||||
}
|
||||
|
||||
<YStack f={1} >
|
||||
<YStack bc="#1c1c1c" borderWidth={1.2} borderColor="#343434" borderRadius="$6">
|
||||
<YStack p="$3">
|
||||
<XStack gap="$4" ai="center">
|
||||
<XStack p="$2" bc="#232323" borderWidth={1.2} borderColor="#343434" borderRadius="$3">
|
||||
<PenTool color="#a0a0a0" />
|
||||
</XStack>
|
||||
<YStack gap="$1">
|
||||
<XStack gap="$2">
|
||||
<Text fontSize={16} fow="bold" color="#ededed">Disclose</Text>
|
||||
</XStack>
|
||||
<Text color="#a0a0a0">Select what to disclose</Text>
|
||||
</YStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
<YStack
|
||||
gap="$2"
|
||||
p="$3"
|
||||
bc="#232323"
|
||||
borderWidth={1.2}
|
||||
borderLeftWidth={0}
|
||||
borderRightWidth={0}
|
||||
borderBottomWidth={0}
|
||||
borderColor="#343434"
|
||||
borderBottomLeftRadius="$6"
|
||||
borderBottomRightRadius="$6"
|
||||
>
|
||||
<ScrollView h={height < 750 ? "$6" : ""} >
|
||||
{selectedApp && Object.keys(selectedApp.disclosureOptions).map((key) => {
|
||||
const key_ = key;
|
||||
const indexes = attributeToPosition[key_ as keyof typeof attributeToPosition];
|
||||
const keyFormatted = key_.replace(/_/g, ' ').split(' ').map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
||||
const mrzAttribute = passportData.mrz.slice(indexes[0], indexes[1] + 1);
|
||||
const mrzAttributeFormatted = formatAttribute(key_, mrzAttribute);
|
||||
<YStack mt="$6">
|
||||
{selectedApp && Object.keys(selectedApp.disclosureOptions as any).map((key) => {
|
||||
const key_ = key;
|
||||
const keyFormatted = key_.replace(/_/g, ' ').split(' ').map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
||||
|
||||
return (
|
||||
<XStack key={key} mx="$2" gap="$3" alignItems='center'>
|
||||
<XStack p="$2" onPress={() => handleDisclosureChange(key_)} >
|
||||
<Checkbox
|
||||
bg={componentBgColor}
|
||||
borderColor={borderColor}
|
||||
value={key}
|
||||
checked={disclosure[key_ as keyof typeof disclosure]}
|
||||
onCheckedChange={() => handleDisclosureChange(key_)}
|
||||
aria-label={keyFormatted}
|
||||
size="$6"
|
||||
>
|
||||
<Checkbox.Indicator >
|
||||
<Check color={textColor1} />
|
||||
</Checkbox.Indicator>
|
||||
</Checkbox>
|
||||
</XStack>
|
||||
<Text color={textColor2} >{keyFormatted}: </Text>
|
||||
|
||||
{key_ === 'older_than' ? (
|
||||
<XStack gap="$1.5" jc='center' ai='center'>
|
||||
<XStack mr="$2">
|
||||
<Text color={textColor1} w="$1" fontSize={16}>{majority}</Text>
|
||||
<Text color={textColor1} fontSize={16}> yo</Text>
|
||||
</XStack>
|
||||
<Button
|
||||
bg={componentBgColor}
|
||||
borderColor={borderColor}
|
||||
h="$2"
|
||||
w="$3"
|
||||
onPress={() => update({
|
||||
majority: majority - 1
|
||||
})}
|
||||
>
|
||||
<Minus color={textColor1} size={18} />
|
||||
</Button>
|
||||
<Button
|
||||
bg={componentBgColor}
|
||||
borderColor={borderColor}
|
||||
h="$2"
|
||||
w="$3"
|
||||
onPress={() => update({
|
||||
majority: majority + 1
|
||||
})}
|
||||
>
|
||||
<Plus color={textColor1} size={18} />
|
||||
</Button>
|
||||
</XStack>
|
||||
) : (
|
||||
<Text
|
||||
color={textColor1}
|
||||
>
|
||||
{hideData ? maskString(mrzAttributeFormatted) : mrzAttributeFormatted}
|
||||
</Text>
|
||||
)}
|
||||
</XStack>
|
||||
);
|
||||
})}
|
||||
</ScrollView >
|
||||
</YStack >
|
||||
</YStack >
|
||||
</YStack >
|
||||
<Button
|
||||
disabled={isZkeyDownloading[selectedApp.circuit] || (address == ethers.ZeroAddress)}
|
||||
borderWidth={1.3}
|
||||
borderColor={borderColor}
|
||||
borderRadius={100}
|
||||
onPress={handleProve}
|
||||
mt="$8"
|
||||
backgroundColor={address == ethers.ZeroAddress ? "#cecece" : "#3185FC"}
|
||||
alignSelf='center'
|
||||
>
|
||||
{!registered ? (
|
||||
<XStack ai="center" gap="$1">
|
||||
<Spinner />
|
||||
<Text color={textColor1} fow="bold">
|
||||
Registering identity...
|
||||
return (
|
||||
<XStack key={key} gap="$3" mb="$3" ml="$3" >
|
||||
<CheckCircle size={16} mt="$1.5" />
|
||||
<Text fontSize="$7" color={textBlack} w="85%">
|
||||
{disclosureFieldsToText(key_, (selectedApp.disclosureOptions as any)[key_])}
|
||||
</Text>
|
||||
</XStack>
|
||||
) : isZkeyDownloading[selectedApp.circuit] ? (
|
||||
<XStack ai="center" gap="$1">
|
||||
<Spinner />
|
||||
<Text color={textColor1} fow="bold">
|
||||
Downloading ZK proving key
|
||||
</Text>
|
||||
</XStack>
|
||||
) : step === Steps.GENERATING_PROOF ? (
|
||||
<XStack ai="center" gap="$1">
|
||||
<Spinner />
|
||||
<Text color={textColor2} marginLeft="$2" fow="bold">
|
||||
Generating ZK proof
|
||||
</Text>
|
||||
</XStack>
|
||||
) : address == ethers.ZeroAddress ? (
|
||||
<Text color={textColor2} fow="bold">
|
||||
Enter address
|
||||
</Text>
|
||||
) : (
|
||||
<Text color={textColor1} fow="bold">
|
||||
Generate ZK proof
|
||||
</Text>
|
||||
)}
|
||||
</Button>
|
||||
{
|
||||
(height > 750) &&
|
||||
<Text
|
||||
fontSize={10}
|
||||
color={step === Steps.GENERATING_PROOF ? "#a0a0a0" : "#161616"}
|
||||
py="$2"
|
||||
alignSelf='center'
|
||||
>
|
||||
This operation can take up to 1 mn, phone may freeze during this time
|
||||
</Text>
|
||||
}
|
||||
</YStack >
|
||||
);
|
||||
})}
|
||||
</YStack>
|
||||
|
||||
<XStack f={1} />
|
||||
|
||||
<CustomButton
|
||||
Icon={isConnecting ? <Spinner /> : generatingProof ? <Spinner /> : <CheckCircle />}
|
||||
isDisabled={isConnecting || generatingProof}
|
||||
text={isConnecting ? "Connecting..." : generatingProof ? "Generating Proof..." : "Verify"}
|
||||
onPress={registered ? handleProve : () => setSheetRegisterIsOpen(true)}
|
||||
bgColor={isConnecting || generatingProof ? separatorColor : bgGreen}
|
||||
disabledOnPress={() => toast.show('⏳', {
|
||||
message: isConnecting ? "Connecting to server..." : "Proof is generating",
|
||||
customData: {
|
||||
type: "info",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
|
||||
{/* {proofStatus && (
|
||||
<Text mt="$4" fontSize="$6" color={textBlack}>
|
||||
{proofStatus}
|
||||
</Text>
|
||||
)} */}
|
||||
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { useState } from 'react';
|
||||
import { YStack, XStack, Text, Button, Spinner } from 'tamagui';
|
||||
import { LockKeyhole } from '@tamagui/lucide-icons';
|
||||
import { borderColor, componentBgColor, componentBgColor2, textColor1, textColor2 } from '../utils/colors';
|
||||
import { LockKeyhole, UserPlus } from '@tamagui/lucide-icons';
|
||||
import { bgGreen, borderColor, componentBgColor, componentBgColor2, textBlack } from '../utils/colors';
|
||||
import { Platform } from 'react-native';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
|
||||
const RegisterScreen: React.FC = () => {
|
||||
|
||||
@@ -16,6 +17,7 @@ const RegisterScreen: React.FC = () => {
|
||||
const handleRegister = async () => {
|
||||
setRegistering(true);
|
||||
useUserStore.getState().registerCommitment();
|
||||
|
||||
setRegisterStep("Generating witness...");
|
||||
setTimeout(() => {
|
||||
setRegisterStep("Generating proof...");
|
||||
@@ -29,23 +31,30 @@ const RegisterScreen: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack px="$4" f={1} mb={Platform.OS === 'ios' ? "$5" : "$0"}>
|
||||
<YStack p="$3" f={1} mb={Platform.OS === 'ios' ? "$5" : "$0"}>
|
||||
<YStack flex={1} mx="$2" gap="$2">
|
||||
<Text mt="$12" color={textColor1} fontSize="$10" fontWeight="bold">
|
||||
Register
|
||||
</Text>
|
||||
<Text mt="$6" fontSize="$6" color={textColor1}>Join Proof of Passport to start sharing your identity securely.</Text>
|
||||
<Text mt="$1" fontSize="$4" color={textColor2}>Easily verify your nationality, humanity, or age and share only what you want to reveal.</Text>
|
||||
<YStack f={1} />
|
||||
<Text mt="$7" fontSize="$9" color={textBlack}>Join Proof of Passport to start sharing your identity<Text style={{
|
||||
textDecorationLine: "underline", textDecorationColor: bgGreen
|
||||
}}> securely. </Text></Text>
|
||||
<Text mt="$0" color={textBlack} fontSize="$8">Easily verify your nationality, humanity, or age and share<Text style={{
|
||||
textDecorationLine: "underline", textDecorationColor: bgGreen
|
||||
}}> only </Text>what you want to reveal.</Text>
|
||||
<XStack f={1} />
|
||||
|
||||
<XStack mt="$5" bg={componentBgColor} borderRadius={100} borderWidth={1} borderColor={borderColor} py="$2" px="$3">
|
||||
<XStack bg={componentBgColor2} borderRadius={100} p="$2" >
|
||||
<LockKeyhole alignSelf='center' size={24} color={textColor1} />
|
||||
<XStack mt="$5" bg="white" borderRadius={100} mb="$12" py="$2.5" px="$3">
|
||||
<XStack p="$2" >
|
||||
<LockKeyhole alignSelf='center' size={24} color={textBlack} />
|
||||
</XStack>
|
||||
<Text alignSelf='center' ml="$3" pr="$5" fontSize="$3" color={textColor1}>Registration does not leak any personal information</Text>
|
||||
<Text alignSelf='center' ml="$3" pr="$5" fontSize="$3" color={textBlack}>Registration does not leak any personal information</Text>
|
||||
</XStack>
|
||||
|
||||
<Button
|
||||
<CustomButton
|
||||
isDisabled={isZkeyDownloading.register_sha256WithRSAEncryption_65537 || registering}
|
||||
onPress={handleRegister}
|
||||
text={isZkeyDownloading.register_sha256WithRSAEncryption_65537 ? "Downloading zkey..." : (registerStep || "Register")}
|
||||
Icon={isZkeyDownloading.register_sha256WithRSAEncryption_65537 || registering ? <Spinner color={textBlack} /> : <UserPlus color={textBlack} />}
|
||||
/>
|
||||
{/* <Button
|
||||
disabled={isZkeyDownloading.register_sha256WithRSAEncryption_65537}
|
||||
mt="$8"
|
||||
alignSelf='center'
|
||||
@@ -56,11 +65,11 @@ const RegisterScreen: React.FC = () => {
|
||||
>
|
||||
<XStack gap="$3">
|
||||
{(registering || isZkeyDownloading.register_sha256WithRSAEncryption_65537) && <Spinner color="white" size="small" />}
|
||||
<Text color={textColor1} fontSize="$5" >
|
||||
<Text color={textBlack} fontSize="$5" >
|
||||
{isZkeyDownloading.register_sha256WithRSAEncryption_65537 ? "Downloading zkey..." : (registerStep || "Register")}
|
||||
</Text>
|
||||
</XStack>
|
||||
</Button>
|
||||
</Button> */}
|
||||
</YStack >
|
||||
</YStack >
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import ProofGrid from '../components/ProofGrid';
|
||||
import { Platform } from 'react-native';
|
||||
import { blueColor, borderColor, componentBgColor, textColor1, textColor2 } from '../utils/colors';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { AppType } from '../utils/appType';
|
||||
import { AppType } from '../../../common/src/utils/appType';
|
||||
import { appStoreMapping } from './ProveScreen';
|
||||
|
||||
const SendProofScreen: React.FC = () => {
|
||||
|
||||
31
app/src/screens/SplashScreen.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { YStack, Text, Spinner, XStack } from 'tamagui';
|
||||
import { bgGreen, textBlack } from '../utils/colors';
|
||||
|
||||
const SplashScreen = () => {
|
||||
const { userLoaded, registered } = useUserStore();
|
||||
const { setSelectedTab } = useNavigationStore();
|
||||
|
||||
// once registered is retrieved from zustand, navigate to the appropriate screen
|
||||
useEffect(() => {
|
||||
if (userLoaded) {
|
||||
if (registered) {
|
||||
setSelectedTab('app');
|
||||
} else {
|
||||
setSelectedTab('start');
|
||||
}
|
||||
}
|
||||
}, [userLoaded]);
|
||||
return (
|
||||
<YStack ai="center" f={1} gap="$8" mt="$18" mb="$8">
|
||||
<Text fontSize="$9">Proof of Passport</Text>
|
||||
<XStack f={1} />
|
||||
<Spinner color={textBlack} />
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default SplashScreen;
|
||||
44
app/src/screens/StartScreen.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { YStack, Button, Image, Text, styled } from 'tamagui';
|
||||
import { ArrowRight, Camera, SquarePen, UserPlus } from '@tamagui/lucide-icons';
|
||||
import { bgColor, bgGreen, borderColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import { Steps } from "../utils/utils";
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
|
||||
const StartScreen: React.FC = () => {
|
||||
|
||||
const {
|
||||
setStep,
|
||||
step,
|
||||
selectedTab,
|
||||
setSelectedTab
|
||||
} = useNavigationStore();
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$3">
|
||||
<YStack f={1} mt="$12">
|
||||
<YStack gap="$0.5" mb="$14">
|
||||
<Text fontSize="$9" >Welcome to Proof of Passport 👋</Text>
|
||||
<Text fontSize="$8" mt="$6" color={textBlack}>Proof of Passport allows you to scan your passport, and to prove your identity in a
|
||||
<Text fontSize="$8" color={textBlack} style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}> secure </Text>way.
|
||||
</Text>
|
||||
<Text fontSize="$8" mt="$4" color={textBlack} style={{ opacity: 0.7 }}>You can for example prove that you are over 18 yo while staying fully
|
||||
<Text fontSize="$8" color={textBlack} style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}> anonymous.</Text>
|
||||
</Text>
|
||||
</YStack>
|
||||
|
||||
</YStack>
|
||||
<CustomButton Icon={<ArrowRight />} text="Let's start" onPress={() => {
|
||||
setSelectedTab("scan");
|
||||
}} />
|
||||
{/* <Button onPress={() => {
|
||||
setSelectedTab("register");
|
||||
}}>
|
||||
Register
|
||||
</Button> */}
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
export default StartScreen;
|
||||
23
app/src/screens/ValidProofScreen.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { YStack, Button, Image, Text, ScrollView, XStack, Separator } from 'tamagui';
|
||||
import { Camera, ShieldCheck, SquarePen, X } from '@tamagui/lucide-icons';
|
||||
import { bgColor, bgGreen, borderColor, componentBgColor, componentBgColor2, separatorColor, textBlack, textColor1, textColor2 } from '../utils/colors';
|
||||
import SCANHelp from '../images/scan_help.png'
|
||||
import { startCameraScan } from '../utils/cameraScanner';
|
||||
import CustomButton from '../components/CustomButton';
|
||||
|
||||
|
||||
const SuccessScreen: React.FC = () => {
|
||||
return (
|
||||
<YStack f={1} p="$3">
|
||||
<YStack f={1} mt="$8">
|
||||
<Text ml="$1" fontSize="$10" color={textBlack}><Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>Success</Text>, the proof has been verified</Text>
|
||||
<XStack f={1} />
|
||||
</YStack>
|
||||
|
||||
|
||||
</YStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default SuccessScreen;
|
||||
59
app/src/screens/WrongProofScreen.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { YStack, Text, XStack } from 'tamagui';
|
||||
import { bgGreen, textBlack } from '../utils/colors';
|
||||
import useUserStore from '../stores/userStore';
|
||||
|
||||
const WrongProofScreen: React.FC = () => {
|
||||
const { proofVerificationResult } = useUserStore();
|
||||
|
||||
console.log('Raw proofVerificationResult:', JSON.stringify(proofVerificationResult));
|
||||
|
||||
const formatFieldName = (field: string) => {
|
||||
return field.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
||||
};
|
||||
|
||||
// Remove the parsing step
|
||||
const parsedResult = proofVerificationResult;
|
||||
|
||||
const fieldsToCheck = [
|
||||
'scope', 'merkle_root', 'attestation_id', 'current_date', 'issuing_state',
|
||||
'name', 'passport_number', 'nationality', 'date_of_birth', 'gender',
|
||||
'expiry_date', 'older_than', 'owner_of', 'proof'
|
||||
];
|
||||
|
||||
const failedConditions = [];
|
||||
for (const field of fieldsToCheck) {
|
||||
console.log(`Checking field ${field}: ${JSON.stringify(parsedResult[field])}`);
|
||||
if (parsedResult[field] === false) {
|
||||
failedConditions.push(formatFieldName(field));
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Failed conditions:', JSON.stringify(failedConditions));
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$3">
|
||||
<YStack f={1} mt="$4" >
|
||||
<Text ml="$1" fontSize={34} color={textBlack}>
|
||||
<Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>Oops</Text>, the proof is not valid.
|
||||
</Text>
|
||||
<Text ml="$2" mt="$3" fontSize="$8" color={textBlack}>
|
||||
Some of the <Text >conditions</Text> have not been satisfied:
|
||||
</Text>
|
||||
<YStack ml="$4" mt="$5">
|
||||
{failedConditions.map((condition, index) => (
|
||||
<Text key={index} fontSize="$7" color={textBlack} >
|
||||
· <Text key={index} style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>{condition}</Text>
|
||||
</Text>
|
||||
))}
|
||||
</YStack>
|
||||
<Text ml="$2" mt="$8" fontSize="$7" color={textBlack} style={{ opacity: 0.7 }}>
|
||||
<Text style={{ textDecorationLine: 'underline', textDecorationColor: bgGreen }}>Check again</Text> your eligibility, if you are sure to be eligible to this verification please contact Proof of Passport support.
|
||||
</Text>
|
||||
<XStack f={1} />
|
||||
</YStack>
|
||||
</YStack >
|
||||
);
|
||||
};
|
||||
|
||||
export default WrongProofScreen;
|
||||
@@ -2,7 +2,7 @@ import { create } from 'zustand'
|
||||
import { IsZkeyDownloading, ShowWarningModalProps } from '../utils/zkeyDownload';
|
||||
import { Steps } from '../utils/utils';
|
||||
import { useToastController } from '@tamagui/toast';
|
||||
import { AppType } from '../utils/appType';
|
||||
import { AppType } from '../../../common/src/utils/appType';
|
||||
|
||||
interface NavigationState {
|
||||
step: number
|
||||
@@ -11,12 +11,16 @@ interface NavigationState {
|
||||
hideData: boolean
|
||||
toast: ReturnType<typeof useToastController>
|
||||
selectedTab: string
|
||||
setSelectedTab: (tab: string) => void
|
||||
selectedApp: AppType | null
|
||||
setSelectedApp: (app: AppType | null) => void
|
||||
showRegistrationErrorSheet: boolean
|
||||
registrationErrorMessage: string
|
||||
setToast: (toast: ReturnType<typeof useToastController>) => void;
|
||||
setStep: (step: number) => void
|
||||
update: (patch: any) => void
|
||||
nfcSheetIsOpen: boolean
|
||||
setNfcSheetIsOpen: (isOpen: boolean) => void
|
||||
}
|
||||
|
||||
const useNavigationStore = create<NavigationState>((set, get) => ({
|
||||
@@ -41,8 +45,10 @@ const useNavigationStore = create<NavigationState>((set, get) => ({
|
||||
selectedApp: null,
|
||||
|
||||
setToast: (toast) => set({ toast }),
|
||||
setSelectedApp: (app) => set({ selectedApp: app }),
|
||||
|
||||
setStep: (step) => set({ step }),
|
||||
setSelectedTab: (tab) => set({ selectedTab: tab }),
|
||||
|
||||
update: (patch) => {
|
||||
set({
|
||||
@@ -50,6 +56,8 @@ const useNavigationStore = create<NavigationState>((set, get) => ({
|
||||
...patch,
|
||||
});
|
||||
},
|
||||
nfcSheetIsOpen: false,
|
||||
setNfcSheetIsOpen: (isOpen) => set({ nfcSheetIsOpen: isOpen }),
|
||||
}))
|
||||
|
||||
export default useNavigationStore
|
||||
@@ -20,6 +20,8 @@ import { sendRegisterTransaction } from '../utils/transactions';
|
||||
import { loadPassportData, loadSecret, loadSecretOrCreateIt, storePassportData } from '../utils/keychain';
|
||||
import { ethers } from 'ethers';
|
||||
import { isCommitmentRegistered } from '../utils/registration';
|
||||
import { ProofOfPassportVerifierReport } from '@proofofpassport/sdk';
|
||||
|
||||
|
||||
interface UserState {
|
||||
passportNumber: string
|
||||
@@ -32,6 +34,7 @@ interface UserState {
|
||||
cscaProof: Proof | null
|
||||
localProof: Proof | null
|
||||
dscSecret: string | null
|
||||
userLoaded: boolean
|
||||
initUserStore: () => void
|
||||
registerPassportData: (passportData: PassportData) => void
|
||||
registerCommitment: (passportData?: PassportData) => void
|
||||
@@ -42,9 +45,13 @@ interface UserState {
|
||||
deleteMrzFields: () => void
|
||||
setRegistered: (registered: boolean) => void
|
||||
setDscSecret: (dscSecret: string) => void
|
||||
setUserLoaded: (userLoaded: boolean) => void
|
||||
proofVerificationResult: string,
|
||||
setProofVerificationResult: (proofVerificationResult: string) => void
|
||||
}
|
||||
|
||||
const useUserStore = create<UserState>((set, get) => ({
|
||||
userLoaded: false,
|
||||
passportNumber: DEFAULT_PNUMBER ?? "",
|
||||
dateOfBirth: DEFAULT_DOB ?? "",
|
||||
dateOfExpiry: DEFAULT_DOE ?? "",
|
||||
@@ -61,7 +68,13 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
setDscSecret: (dscSecret: string) => {
|
||||
set({ dscSecret });
|
||||
},
|
||||
|
||||
setUserLoaded: (userLoaded: boolean) => {
|
||||
set({ userLoaded });
|
||||
},
|
||||
proofVerificationResult: "null",
|
||||
setProofVerificationResult: (proofVerificationResult: string) => {
|
||||
set({ proofVerificationResult });
|
||||
},
|
||||
// When user opens the app, checks presence of passportData
|
||||
// - If passportData is not present, starts the onboarding flow
|
||||
// - If passportData is present, then secret must be here too (they are always set together). Request the tree.
|
||||
@@ -78,6 +91,9 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
const passportData = await loadPassportData();
|
||||
if (!passportData) {
|
||||
console.log("No passport data found, starting onboarding flow")
|
||||
set({
|
||||
userLoaded: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,8 +103,10 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
console.log("not registered but passport data found, skipping to nextScreen")
|
||||
set({
|
||||
passportData: JSON.parse(passportData),
|
||||
userLoaded: true,
|
||||
});
|
||||
useNavigationStore.getState().setStep(Steps.NEXT_SCREEN);
|
||||
// useNavigationStore.getState().setStep(Steps.NEXT_SCREEN);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,7 +115,8 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
passportData: JSON.parse(passportData),
|
||||
registered: true,
|
||||
});
|
||||
// useNavigationStore.getState().setStep(Steps.REGISTERED);
|
||||
useNavigationStore.getState().setStep(Steps.REGISTERED);
|
||||
set({ userLoaded: true });
|
||||
},
|
||||
|
||||
// When reading passport for the first time:
|
||||
@@ -116,6 +135,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
},
|
||||
|
||||
registerCommitment: async (mockPassportData?: PassportData) => {
|
||||
console.log("registerCommitment")
|
||||
const {
|
||||
toast,
|
||||
setStep,
|
||||
@@ -128,6 +148,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
}
|
||||
|
||||
const isAlreadyRegistered = await isCommitmentRegistered(secret, passportData);
|
||||
console.log("isAlreadyRegistered", isAlreadyRegistered)
|
||||
if (isAlreadyRegistered) {
|
||||
console.log("commitment is already registered")
|
||||
toast.show('Identity already registered, skipping', {
|
||||
@@ -160,7 +181,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
|
||||
);
|
||||
|
||||
amplitude.track(`Sig alg supported: ${passportData.signatureAlgorithm}`);
|
||||
//amplitude.track(`Sig alg supported: ${passportData.signatureAlgorithm}`);
|
||||
console.log("userStore - inputs - Object.keys(inputs).forEach((key) => {...")
|
||||
Object.keys(inputs).forEach((key) => {
|
||||
if (Array.isArray(inputs[key as keyof typeof inputs])) {
|
||||
@@ -184,7 +205,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
|
||||
const end = Date.now();
|
||||
console.log('Total proof time from frontend:', end - start);
|
||||
amplitude.track('Proof generation successful, took ' + ((end - start) / 1000) + ' seconds');
|
||||
//amplitude.track('Proof generation successful, took ' + ((end - start) / 1000) + ' seconds');
|
||||
|
||||
|
||||
if ((get().cscaProof !== null) && (get().localProof !== null)) {
|
||||
@@ -199,6 +220,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
}
|
||||
set({ registered: true });
|
||||
setStep(Steps.REGISTERED);
|
||||
useNavigationStore.getState().setSelectedTab("app");
|
||||
toast.show('✅', {
|
||||
message: "Registered",
|
||||
customData: {
|
||||
@@ -217,7 +239,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
registrationErrorMessage: error.message,
|
||||
})
|
||||
setStep(Steps.NEXT_SCREEN);
|
||||
amplitude.track(error.message);
|
||||
//amplitude.track(error.message);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { CircuitName } from "./zkeyDownload";
|
||||
|
||||
type DisclosureOption = "required" | "optional";
|
||||
|
||||
type Disclosure = {
|
||||
[key: string]: DisclosureOption;
|
||||
};
|
||||
|
||||
export type AppType = {
|
||||
id: string;
|
||||
|
||||
// AppScreen UI
|
||||
title: string,
|
||||
description: string,
|
||||
background?: string,
|
||||
colorOfTheText: string,
|
||||
selectable: boolean,
|
||||
icon: any,
|
||||
tags: React.JSX.Element[]
|
||||
|
||||
// ProveScreen UI
|
||||
name: string;
|
||||
disclosureOptions: Disclosure | {};
|
||||
|
||||
beforeSendText1: string;
|
||||
beforeSendText2: string;
|
||||
sendButtonText: string;
|
||||
sendingButtonText: string;
|
||||
|
||||
successTitle: string;
|
||||
successText: string;
|
||||
|
||||
successComponent: () => React.JSX.Element;
|
||||
finalButtonAction: () => void;
|
||||
finalButtonText: string;
|
||||
|
||||
scope: string;
|
||||
circuit: CircuitName; // circuit and witness calculator name
|
||||
|
||||
fields: React.FC[];
|
||||
|
||||
handleProve: () => void;
|
||||
handleSendProof: () => void;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
|
||||
export const startCameraScan = async () => {
|
||||
const {toast, setStep} = useNavigationStore.getState();
|
||||
const { toast, setSelectedTab } = useNavigationStore.getState();
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
try {
|
||||
@@ -19,17 +19,15 @@ export const startCameraScan = async () => {
|
||||
dateOfExpiry: formatDateToYYMMDD(result.expiryDate),
|
||||
})
|
||||
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
setSelectedTab("nfc");
|
||||
toast.show("Scan successful", {
|
||||
message: 'Nice to meet you!',
|
||||
message: '✅',
|
||||
customData: {
|
||||
type: "success",
|
||||
},
|
||||
})
|
||||
amplitude.track('Camera scan successful');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
amplitude.track('Camera scan unsuccessful');
|
||||
}
|
||||
} else {
|
||||
NativeModules.CameraActivityModule.startCameraActivity()
|
||||
@@ -43,22 +41,19 @@ export const startCameraScan = async () => {
|
||||
dateOfExpiry: expiryDate,
|
||||
})
|
||||
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track('Camera scan successful');
|
||||
setSelectedTab("nfc");
|
||||
toast.show("Scan successful", {
|
||||
message: 'Nice to meet you!',
|
||||
message: '✅',
|
||||
customData: {
|
||||
type: "success",
|
||||
},
|
||||
})
|
||||
})
|
||||
} catch (error: any) {
|
||||
console.error('Invalid MRZ format:', error.message);
|
||||
amplitude.track('Camera scan unsuccessful');
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('Camera Activity Error:', error);
|
||||
amplitude.track('Camera scan unsuccessful');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -13,3 +13,8 @@ export const redColorDark = "#3c181a"
|
||||
export const redColorLight = "#e5484d"
|
||||
export const yellowColorDark = "#2d2200"
|
||||
export const yellowColorLight = "#f5d90a"
|
||||
export const bgWhite = "#F5F5F5"
|
||||
export const textBlack = "#333333"
|
||||
export const bgGreen = "#94FBAB"
|
||||
export const bgBlue = "#69DFFF"
|
||||
export const separatorColor = "#E0E0E0"
|
||||
@@ -22,7 +22,7 @@ export const scan = async (setModalProofStep: (modalProofStep: number) => void)
|
||||
dateOfExpiry,
|
||||
} = useUserStore.getState()
|
||||
|
||||
const { toast, setStep } = useNavigationStore.getState();
|
||||
const { toast, setStep, nfcSheetIsOpen, setNfcSheetIsOpen } = useNavigationStore.getState();
|
||||
|
||||
const check = checkInputs(
|
||||
passportNumber,
|
||||
@@ -57,7 +57,9 @@ const scanAndroid = async (setModalProofStep: (modalProofStep: number) => void)
|
||||
dateOfExpiry,
|
||||
dscCertificate
|
||||
} = useUserStore.getState()
|
||||
const { toast, setStep } = useNavigationStore.getState();
|
||||
const { toast, setNfcSheetIsOpen } = useNavigationStore.getState();
|
||||
setNfcSheetIsOpen(true);
|
||||
|
||||
|
||||
try {
|
||||
const response = await PassportReader.scan({
|
||||
@@ -66,12 +68,13 @@ const scanAndroid = async (setModalProofStep: (modalProofStep: number) => void)
|
||||
dateOfExpiry: dateOfExpiry
|
||||
});
|
||||
console.log('scanned');
|
||||
amplitude.track('NFC scan successful');
|
||||
setNfcSheetIsOpen(false);
|
||||
//amplitude.track('NFC scan successful');
|
||||
handleResponseAndroid(response, setModalProofStep);
|
||||
} catch (e: any) {
|
||||
console.log('error during scan:', e);
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track('NFC scan unsuccessful', { error: JSON.stringify(e) });
|
||||
setNfcSheetIsOpen(false);
|
||||
//amplitude.track('NFC scan unsuccessful', { error: JSON.stringify(e) });
|
||||
toast.show('Error', {
|
||||
message: e.message,
|
||||
customData: {
|
||||
@@ -98,11 +101,11 @@ const scanIOS = async (setModalProofStep: (modalProofStep: number) => void) => {
|
||||
);
|
||||
console.log('scanned');
|
||||
handleResponseIOS(response, setModalProofStep);
|
||||
amplitude.track('NFC scan successful');
|
||||
//amplitude.track('NFC scan successful');
|
||||
} catch (e: any) {
|
||||
console.log('error during scan:', e);
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track(`NFC scan unsuccessful, error ${e.message}`);
|
||||
//amplitude.track(`NFC scan unsuccessful, error ${e.message}`);
|
||||
if (!e.message.includes("UserCanceled")) {
|
||||
toast.show('Failed to read passport', {
|
||||
message: e.message,
|
||||
@@ -155,7 +158,7 @@ const handleResponseIOS = async (
|
||||
|
||||
const encryptedDigestArray = Array.from(Buffer.from(signatureBase64, 'base64')).map(byte => byte > 127 ? byte - 256 : byte);
|
||||
|
||||
amplitude.track('Sig alg before conversion: ' + signatureAlgorithm);
|
||||
//amplitude.track('Sig alg before conversion: ' + signatureAlgorithm);
|
||||
console.log('signatureAlgorithm before conversion', signatureAlgorithm);
|
||||
const passportData = {
|
||||
mrz,
|
||||
@@ -196,10 +199,11 @@ const handleResponseIOS = async (
|
||||
sendCSCARequest(inputs_csca, setModalProofStep);
|
||||
|
||||
useNavigationStore.getState().setStep(Steps.NEXT_SCREEN);
|
||||
useNavigationStore.getState().setSelectedTab("next");
|
||||
} catch (e: any) {
|
||||
console.log('error during parsing:', e);
|
||||
useNavigationStore.getState().setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track('Signature algorithm unsupported (ecdsa not parsed)', { error: JSON.stringify(e) });
|
||||
//amplitude.track('Signature algorithm unsupported (ecdsa not parsed)', { error: JSON.stringify(e) });
|
||||
toast.show('Error', {
|
||||
message: "Your signature algorithm is not supported at that time. Please try again later.",
|
||||
customData: {
|
||||
@@ -231,7 +235,7 @@ const handleResponseAndroid = async (
|
||||
documentSigningCertificate
|
||||
} = response;
|
||||
|
||||
amplitude.track('Sig alg before conversion: ' + signatureAlgorithm);
|
||||
//amplitude.track('Sig alg before conversion: ' + signatureAlgorithm);
|
||||
|
||||
const pem = "-----BEGIN CERTIFICATE-----" + documentSigningCertificate + "-----END CERTIFICATE-----"
|
||||
|
||||
@@ -255,7 +259,7 @@ const handleResponseAndroid = async (
|
||||
encryptedDigest: JSON.parse(encryptedDigest),
|
||||
photoBase64: photo.base64,
|
||||
};
|
||||
amplitude.track('Sig alg after conversion: ' + passportData.signatureAlgorithm);
|
||||
//amplitude.track('Sig alg after conversion: ' + passportData.signatureAlgorithm);
|
||||
|
||||
console.log('passportData', JSON.stringify({
|
||||
...passportData,
|
||||
@@ -304,4 +308,5 @@ const handleResponseAndroid = async (
|
||||
);
|
||||
sendCSCARequest(inputs_csca, setModalProofStep);
|
||||
useNavigationStore.getState().setStep(Steps.NEXT_SCREEN);
|
||||
useNavigationStore.getState().setSelectedTab("next");
|
||||
};
|
||||
|
||||
@@ -8,7 +8,16 @@ import { formatMrz, packBytes } from "../../../common/src/utils/utils";
|
||||
import { findIndexInTree } from "../../../common/src/utils/generateInputs";
|
||||
|
||||
export async function isCommitmentRegistered(secret: string, passportData: PassportData) {
|
||||
const response = await axios.get(COMMITMENT_TREE_TRACKER_URL)
|
||||
|
||||
|
||||
let response;
|
||||
console.log(COMMITMENT_TREE_TRACKER_URL)
|
||||
try {
|
||||
response = await axios.get(COMMITMENT_TREE_TRACKER_URL);
|
||||
} catch (error) {
|
||||
console.error('Error fetching commitment tree:', error);
|
||||
throw error; // rethrow the error after logging
|
||||
}
|
||||
console.log('response.data:', response.data);
|
||||
|
||||
const imt = new LeanIMT(
|
||||
@@ -40,7 +49,7 @@ export async function isCommitmentRegistered(secret: string, passportData: Passp
|
||||
try {
|
||||
findIndexInTree(imt as any, commitment); // this will throw if not found
|
||||
return true
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ export function formatDateToYYMMDD(inputDate: string) {
|
||||
}
|
||||
|
||||
export const Steps = {
|
||||
START: 0,
|
||||
MRZ_SCAN: 1,
|
||||
MRZ_SCAN_COMPLETED: 2,
|
||||
NFC_SCANNING: 3,
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function downloadZkey(
|
||||
const downloadRequired = await isDownloadRequired(circuit, isZkeyDownloading);
|
||||
if (!downloadRequired) {
|
||||
console.log(`zkey for ${circuit} already downloaded`)
|
||||
amplitude.track(`zkey for ${circuit} already downloaded`);
|
||||
//amplitude.track(`zkey for ${circuit} already downloaded`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export async function fetchZkey(
|
||||
circuit: CircuitName,
|
||||
) {
|
||||
console.log(`fetching zkey for ${circuit} ...`)
|
||||
amplitude.track(`fetching zkey for ${circuit} ...`);
|
||||
//amplitude.track(`fetching zkey for ${circuit} ...`);
|
||||
|
||||
const {
|
||||
isZkeyDownloading,
|
||||
@@ -171,7 +171,7 @@ export async function fetchZkey(
|
||||
}
|
||||
});
|
||||
|
||||
amplitude.track('zkey download succeeded, took ' + ((Date.now() - startTime) / 1000) + ' seconds');
|
||||
//amplitude.track('zkey download succeeded, took ' + ((Date.now() - startTime) / 1000) + ' seconds');
|
||||
|
||||
const zipSize = await RNFS.stat(`${RNFS.DocumentDirectoryPath}/${circuit}.zkey.zip`);
|
||||
console.log('zipSize:', zipSize.size);
|
||||
@@ -202,7 +202,7 @@ export async function fetchZkey(
|
||||
[circuit]: false,
|
||||
}
|
||||
});
|
||||
amplitude.track('zkey download failed: ' + error.message);
|
||||
//amplitude.track('zkey download failed: ' + error.message);
|
||||
toast.show('Error', {
|
||||
message: `Error: ${error.message}`,
|
||||
customData: {
|
||||
|
||||
2471
app/yarn.lock
@@ -35,7 +35,7 @@ describe('Disclose', function () {
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))]).toString();
|
||||
|
||||
const majority = ['1', '8'];
|
||||
const majority = '18';
|
||||
const user_identifier = '0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50';
|
||||
const bitmap = Array(90).fill('1');
|
||||
const scope = poseidon1([BigInt(Buffer.from('VOTEEEEE').readUIntBE(0, 6))]).toString();
|
||||
|
||||
@@ -64,6 +64,6 @@ describe('DSC chain certificate - SHA1 RSA', function () {
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const witness = await circuit.calculateWitness(inputs.inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,6 +63,6 @@ describe('DSC chain certificate - SHA256 RSA', function () {
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const witness = await circuit.calculateWitness(inputs.inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -94,6 +94,6 @@ describe('DSC chain certificate - SHA256 RSA-PSS', function () {
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const witness = await circuit.calculateWitness(inputs.inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,17 +55,17 @@ describe('RSA Verifier', function () {
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
|
||||
it('should extract and log certificate information', async () => {
|
||||
const csca_inputs = getCSCAInputs('0', dscCert_forge, cscaCert_forge, n, k, n, k, 2048, true);
|
||||
const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256', n, k);
|
||||
// it('should extract and log certificate information', async () => {
|
||||
// const csca_inputs = getCSCAInputs('0', dscCert_forge, cscaCert_forge, n, k, n, k, 2048, true);
|
||||
// const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256', n, k);
|
||||
|
||||
const inputs = {
|
||||
message: tbsCertificateHashFormatted,
|
||||
signature: csca_inputs.dsc_signature,
|
||||
modulus: csca_inputs.csca_modulus,
|
||||
};
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
// const inputs = {
|
||||
// message: tbsCertificateHashFormatted,
|
||||
// signature: csca_inputs.inputs.dsc_signature,
|
||||
// modulus: csca_inputs.inputs.dsc_modulus,
|
||||
// };
|
||||
// const witness = await circuit.calculateWitness(inputs, true);
|
||||
// });
|
||||
});
|
||||
|
||||
describe('SHA-1 certificates', () => {
|
||||
|
||||
@@ -56,17 +56,17 @@ describe('RSAPSS Verifier', function () {
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
|
||||
it('should extract and log certificate information', async () => {
|
||||
const csca_inputs = getCSCAInputs('0', dscCert_forge, cscaCert_forge, n, k, n, k, 960, true);
|
||||
// const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256', n, k);
|
||||
// it('should extract and log certificate information', async () => {
|
||||
// const csca_inputs = getCSCAInputs('0', dscCert_forge, cscaCert_forge, n, k, n, k, 960, true);
|
||||
// // const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256', n, k);
|
||||
|
||||
const inputs = {
|
||||
raw_message: csca_inputs.raw_dsc_cert,
|
||||
raw_message_padded_bytes: csca_inputs.raw_dsc_cert_padded_bytes,
|
||||
signature: csca_inputs.dsc_signature,
|
||||
modulus: csca_inputs.csca_modulus,
|
||||
};
|
||||
//const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
// const inputs = {
|
||||
// raw_message: csca_inputs.inputs.raw_dsc_cert,
|
||||
// raw_message_padded_bytes: csca_inputs.inputs.raw_dsc_cert_padded_bytes,
|
||||
// signature: csca_inputs.inputs.dsc_signature,
|
||||
// modulus: csca_inputs.inputs.dsc_modulus,
|
||||
// };
|
||||
// /const witness = await circuit.calculateWitness(inputs, true);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"@babel/runtime": "^7.23.4",
|
||||
"@zk-kit/imt": "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675",
|
||||
"@zk-kit/lean-imt": "^2.0.1",
|
||||
"@zk-kit/utils": "^1.2.0",
|
||||
"asn1.js": "^5.4.1",
|
||||
"axios": "^1.7.2",
|
||||
"elliptic": "^6.5.5",
|
||||
@@ -20,4 +21,4 @@
|
||||
"devDependencies": {
|
||||
"@types/node-forge": "^1.3.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
export const RELAYER_URL = "https://0pw5u65m3a.execute-api.eu-north-1.amazonaws.com/api-stage/mint"
|
||||
export const COMMITMENT_TREE_TRACKER_URL = "https://app.proofofpassport.com/apiv2/download-merkle-tree"
|
||||
|
||||
//export const COMMITMENT_TREE_TRACKER_URL = "https://app.proofofpassport.com/apiv2/download-merkle-tree"
|
||||
export const COMMITMENT_TREE_TRACKER_URL = "https://proofofpassport-merkle-tree.xyz/api/download-merkle-tree"
|
||||
export const PUBKEY_TREE_DEPTH = 16
|
||||
export const CSCA_TREE_DEPTH = 12
|
||||
export const COMMITMENT_TREE_DEPTH = 16
|
||||
@@ -14,6 +14,7 @@ export const RPC_URL = "https://opt-mainnet.g.alchemy.com/v2/Mjj_SdklUaCdR6EPfVK
|
||||
|
||||
// we make it global here because passing it to generateCircuitInputsRegister caused trouble
|
||||
export const DEVELOPMENT_MODE = true
|
||||
export const DEFAULT_MAJORITY = "18"
|
||||
|
||||
export enum SignatureAlgorithm {
|
||||
sha256WithRSAEncryption_65537 = 1,
|
||||
@@ -28,6 +29,11 @@ export enum SignatureAlgorithm {
|
||||
sha512WithRSAEncryption_65537 = 10
|
||||
}
|
||||
|
||||
export const signatureOidToName = {
|
||||
"1.2.840.113549.1.1.11": "sha256_rsa",
|
||||
"1.2.840.113549.1.1.5": "sha1_rsa"
|
||||
}
|
||||
|
||||
export const attributeToPosition = {
|
||||
issuing_state: [2, 4],
|
||||
name: [5, 43],
|
||||
@@ -312,7 +318,7 @@ qzOBhID0Nxk4k9sW1uT6ocW1xp1SB2WotORssOKIAOLJM8IbPl6n/DkYNcfvyXI7
|
||||
-----END RSA PUBLIC KEY-----`;
|
||||
|
||||
export const DEFAULT_RPC_URL = "https://mainnet.optimism.io";
|
||||
export const REGISTER_CONTRACT_ADDRESS = "0xEd7495516a957dD7d378d8A78846646461cFF25f";
|
||||
export const REGISTER_CONTRACT_ADDRESS = "0x3F346FFdC5d583e4126AF01A02Ac5b9CdB3f1909";
|
||||
export const SBT_CONTRACT_ADDRESS = "0x601Fd54FD11C5E77DE84d877e55B829aff20f0A6";
|
||||
/*** ABI ***/
|
||||
|
||||
|
||||
159
common/src/constants/vkey.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
export const vkey_disclose = {
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 14,
|
||||
"vk_alpha_1": [
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"6942436740229168666595536581519256291593117600832247164924519038970269461046",
|
||||
"17557865657217054151399710026819127874171362865266657132072043760282335721027"
|
||||
],
|
||||
[
|
||||
"15629082942757783052734933529055204330846116501031658743204188522840567440030",
|
||||
"866803245463331646327183913175583329159450203348438102150009828684148559895"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"10998553002727424987884583305349753345629818748955483305954960876370686844925",
|
||||
"18369020735737057562107768810182682586161750799521907185011795199521493953276",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"3870156317905136354369536369223776179854927352937539086581682263147147725326",
|
||||
"947908099816727525943796981035826395896386995128918341433720280874486019589",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"9619614659642762666110070745787072277198407288262286655564043642023793950605",
|
||||
"1444870940646607538213811271690623291794427513321591343855928143309974143815",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"10290556281387838061211784545032614883237381276187632418810139452226710406378",
|
||||
"12820288689147023950592422696432066467590193138126598372596214785570201388663",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"10044189939644279332588298610988772483187101321076758071894028734198440253205",
|
||||
"15016612240779620571490237444430121691511928826472608688773111463692886510804",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"6158786594227478832634691320618082224218218524296943509099128649963428556955",
|
||||
"2818896662082406397657145229256654653904841140122301210666395782176903475916",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"200295911748915977788397688942615122670319721182540082686195028815964792730",
|
||||
"16374098866162622474777608838325780437892472095191094825634065695603492498672",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"1001933084599581827076405562561115761770358156189382784432273793509010836288",
|
||||
"13618159500648302749264797924828312592779374840705268445533823753672345860949",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"12152127135355257668073159516593687751413730484411437719952408933610175077761",
|
||||
"15590965974244077225547659000022179448961631917634079092877797469009672737373",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"14643873766083688335082369233094018379987105460165787549629338089338629672719",
|
||||
"18976194036990056092890684065171543382286602242265347684324001010669281606450",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4974359282562923295097396773583362835614429754286473873410152881834388935350",
|
||||
"2615967425575591157936435871031665935046196308487298765704452331348089292330",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"16489750714044704248135942822786071904168862423655325973193848507501139487825",
|
||||
"4644993658884496411511912365771411317040070112230395754480725062427812526601",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"11801682757910657983396995619983996921870874978799260563404809167285348391422",
|
||||
"19228652101325919244735412842681375925619382430642205708320466729501949572254",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4495248066509783309072792039672520701419947625749866524660708846549914823847",
|
||||
"4585216314173588273427806971446529726371555267351812069737927114283850919560",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"18719866673490039760627957665040843673978402675108669037278157044178865894074",
|
||||
"11183065716352601580915387671262116390467334689778841393328736869598818253587",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
};
|
||||
35
common/src/utils/appType.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
export type CircuitName = "register_sha256WithRSAEncryption_65537" | "disclose";
|
||||
|
||||
//type DisclosureOption = "required" | "optional";
|
||||
|
||||
interface Disclosure {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface AppType {
|
||||
id?: string;
|
||||
name: string;
|
||||
scope: string;
|
||||
callbackEndPoint?: string;
|
||||
userId: string;
|
||||
disclosureOptions: Disclosure;
|
||||
circuit: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
background?: string;
|
||||
colorOfTheText?: string;
|
||||
icon?: unknown;
|
||||
}
|
||||
|
||||
export function createAppType(data: AppType): AppType {
|
||||
return {
|
||||
//id: data.id || "",
|
||||
name: data.name,
|
||||
scope: data.scope,
|
||||
//callbackEndPoint: data.callbackEndPoint,
|
||||
userId: data.userId,
|
||||
disclosureOptions: data.disclosureOptions,
|
||||
circuit: data.circuit || "disclose",
|
||||
...data
|
||||
};
|
||||
}
|
||||
5
common/src/utils/commitmentTree.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// import { LeanIMT } from "@zk-kit/lean-imt";
|
||||
// import { poseidon2 } from "poseidon-lite";
|
||||
// import axios from "axios";
|
||||
// import { COMMITMENT_TREE_TRACKER_URL } from "../constants/constants";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { sha1Pad, sha256Pad } from "./shaPad";
|
||||
import * as forge from "node-forge";
|
||||
import { splitToWords } from "./utils";
|
||||
import { CSCA_AKI_MODULUS, CSCA_TREE_DEPTH, MODAL_SERVER_ADDRESS } from "../constants/constants";
|
||||
import { CSCA_AKI_MODULUS, CSCA_TREE_DEPTH, MODAL_SERVER_ADDRESS, signatureOidToName } from "../constants/constants";
|
||||
import { poseidon16, poseidon2, poseidon4 } from "poseidon-lite";
|
||||
import { IMT } from "@zk-kit/imt";
|
||||
import serialized_csca_tree from "../../pubkeys/serialized_csca_tree.json"
|
||||
@@ -131,17 +131,22 @@ export function getCSCAInputs(dscSecret: string, dscCertificate: any, cscaCertif
|
||||
|
||||
|
||||
return {
|
||||
"raw_dsc_cert": dsc_message_padded_formatted,
|
||||
"raw_dsc_cert_padded_bytes": [dsc_messagePaddedLen_formatted],
|
||||
"csca_modulus": csca_modulus_formatted,
|
||||
"dsc_signature": dsc_signature_formatted,
|
||||
"dsc_modulus": dsc_modulus_formatted,
|
||||
"start_index": [startIndex_formatted],
|
||||
"secret": [dscSecret],
|
||||
"merkle_root": [BigInt(root).toString()],
|
||||
"path": proof.pathIndices.map(index => index.toString()),
|
||||
"siblings": proof.siblings.flat().map(sibling => sibling.toString())
|
||||
"signature_algorithm": signatureOidToName[signatureAlgorithm],
|
||||
"inputs":
|
||||
{
|
||||
"raw_dsc_cert": dsc_message_padded_formatted,
|
||||
"raw_dsc_cert_padded_bytes": [dsc_messagePaddedLen_formatted],
|
||||
"csca_modulus": csca_modulus_formatted,
|
||||
"dsc_signature": dsc_signature_formatted,
|
||||
"dsc_modulus": dsc_modulus_formatted,
|
||||
"start_index": [startIndex_formatted],
|
||||
"secret": [dscSecret],
|
||||
"merkle_root": [BigInt(root).toString()],
|
||||
"path": proof.pathIndices.map(index => index.toString()),
|
||||
"siblings": proof.siblings.flat().map(sibling => sibling.toString())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function derToBytes(derValue: string) {
|
||||
|
||||
@@ -33,13 +33,13 @@ export function generateCircuitInputsRegister(
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
|
||||
const tree = getCSCAModulusMerkleTree();
|
||||
// const tree = getCSCAModulusMerkleTree();
|
||||
|
||||
if (DEVELOPMENT_MODE) {
|
||||
for (const mockPassportData of mocks) {
|
||||
tree.insert(getLeaf(mockPassportData).toString());
|
||||
}
|
||||
}
|
||||
// if (DEVELOPMENT_MODE) {
|
||||
// for (const mockPassportData of mocks) {
|
||||
// tree.insert(getLeaf(mockPassportData).toString());
|
||||
// }
|
||||
// }
|
||||
|
||||
if (
|
||||
![
|
||||
@@ -75,14 +75,14 @@ export function generateCircuitInputsRegister(
|
||||
...pubKey,
|
||||
}).toString();
|
||||
|
||||
const index = tree.indexOf(leaf);
|
||||
// const index = tree.indexOf(leaf);
|
||||
// console.log(`Index of pubkey in the registry: ${index}`);
|
||||
if (index === -1) {
|
||||
throw new Error('Your public key was not found in the registry');
|
||||
}
|
||||
// if (index === -1) {
|
||||
// throw new Error('Your public key was not found in the registry');
|
||||
// }
|
||||
|
||||
const proof = tree.createProof(index);
|
||||
console.log('verifyProof', tree.verifyProof(proof));
|
||||
// const proof = tree.createProof(index);
|
||||
// console.log('verifyProof', tree.verifyProof(proof));
|
||||
|
||||
if (dataGroupHashes.length > MAX_DATAHASHES_LEN) {
|
||||
console.error(
|
||||
@@ -142,7 +142,7 @@ export function generateCircuitInputsDisclose(
|
||||
attestation_id: string,
|
||||
passportData: PassportData,
|
||||
merkletree: LeanIMT,
|
||||
majority: string[],
|
||||
majority: string,
|
||||
bitmap: string[],
|
||||
scope: string,
|
||||
user_identifier: string
|
||||
@@ -174,6 +174,9 @@ export function generateCircuitInputsDisclose(
|
||||
PUBKEY_TREE_DEPTH
|
||||
);
|
||||
|
||||
// format majority to bigints
|
||||
|
||||
|
||||
return {
|
||||
secret: [secret],
|
||||
attestation_id: [attestation_id],
|
||||
@@ -184,9 +187,9 @@ export function generateCircuitInputsDisclose(
|
||||
path: merkleProofIndices.map((index) => BigInt(index).toString()),
|
||||
siblings: merkleProofSiblings.map((index) => BigInt(index).toString()),
|
||||
bitmap: bitmap,
|
||||
scope: [scope],
|
||||
current_date: getCurrentDateYYMMDD().map((datePart) => BigInt(datePart).toString()),
|
||||
majority: majority.map((char) => BigInt(char.charCodeAt(0)).toString()),
|
||||
scope: [BigInt(scope).toString()],
|
||||
current_date: getCurrentDateYYMMDD().map(datePart => BigInt(datePart).toString()),
|
||||
majority: majority.split('').map(char => BigInt(char.charCodeAt(0)).toString()),
|
||||
user_identifier: [user_identifier],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { SignatureAlgorithm, PUBKEY_TREE_DEPTH, COMMITMENT_TREE_TRACKER_URL } from "../constants/constants";
|
||||
import { IMT, LeanIMT } from '@zk-kit/imt'
|
||||
import { formatSigAlgNameForCircuit } from "./utils";
|
||||
import { toStandardName } from "./formatNames";
|
||||
import axios from "axios";
|
||||
import { poseidon10, poseidon2, poseidon3, poseidon5, poseidon6, poseidon8 } from 'poseidon-lite';
|
||||
import { SignatureAlgorithm, PUBKEY_TREE_DEPTH } from '../constants/constants';
|
||||
import { IMT } from '@zk-kit/imt';
|
||||
import { BigintToArray, hexToDecimal, splitToWords } from './utils';
|
||||
import { formatSigAlgNameForCircuit } from './utils';
|
||||
import { toStandardName } from './formatNames';
|
||||
|
||||
export function buildPubkeyTree(pubkeys: any[]) {
|
||||
let leaves: bigint[] = [];
|
||||
@@ -94,3 +95,13 @@ export function getLeaf(pubkey: any, i?: number): bigint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTreeFromTracker(): Promise<LeanIMT> {
|
||||
const response = await axios.get(COMMITMENT_TREE_TRACKER_URL)
|
||||
const imt = new LeanIMT(
|
||||
(a: bigint, b: bigint) => poseidon2([a, b]),
|
||||
[]
|
||||
);
|
||||
imt.import(response.data)
|
||||
return imt
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { attributeToPosition } from "../constants/constants";
|
||||
|
||||
export function revealBitmapFromMapping(attributeToReveal: {[key: string]: boolean}): string[] {
|
||||
export function revealBitmapFromMapping(attributeToReveal: { [key: string]: string }): string[] {
|
||||
const reveal_bitmap = Array(90).fill('0');
|
||||
|
||||
Object.entries(attributeToReveal).forEach(([attribute, reveal]) => {
|
||||
if (reveal) {
|
||||
if (reveal !== "") {
|
||||
const [start, end] = attributeToPosition[attribute as keyof typeof attributeToPosition];
|
||||
reveal_bitmap.fill('1', start, end + 1);
|
||||
}
|
||||
@@ -12,6 +12,16 @@ export function revealBitmapFromMapping(attributeToReveal: {[key: string]: boole
|
||||
|
||||
return reveal_bitmap;
|
||||
}
|
||||
export function revealBitmapFromAttributes(attributeToReveal: { [key: string]: boolean }): string[] {
|
||||
const reveal_bitmap = Array(90).fill('0');
|
||||
|
||||
Object.entries(attributeToReveal).forEach(([attribute, reveal]) => {
|
||||
const [start, end] = attributeToPosition[attribute as keyof typeof attributeToPosition];
|
||||
reveal_bitmap.fill('1', start, end + 1);
|
||||
});
|
||||
|
||||
return reveal_bitmap;
|
||||
}
|
||||
|
||||
export function unpackReveal(revealedData_packed: string[]): string[] {
|
||||
const revealedData_packed_formatted = [
|
||||
@@ -22,14 +32,14 @@ export function unpackReveal(revealedData_packed: string[]): string[] {
|
||||
|
||||
const bytesCount = [31, 31, 28]; // nb of bytes in each of the first three field elements
|
||||
const bytesArray = revealedData_packed_formatted.flatMap((element: string, index: number) => {
|
||||
const bytes = bytesCount[index];
|
||||
const elementBigInt = BigInt(element);
|
||||
const byteMask = BigInt(255); // 0xFF
|
||||
const bytes = bytesCount[index];
|
||||
const elementBigInt = BigInt(element);
|
||||
const byteMask = BigInt(255); // 0xFF
|
||||
|
||||
const bytesOfElement = [...Array(bytes)].map((_, byteIndex) => {
|
||||
return (elementBigInt >> (BigInt(byteIndex) * BigInt(8))) & byteMask;
|
||||
});
|
||||
return bytesOfElement;
|
||||
const bytesOfElement = [...Array(bytes)].map((_, byteIndex) => {
|
||||
return (elementBigInt >> (BigInt(byteIndex) * BigInt(8))) & byteMask;
|
||||
});
|
||||
return bytesOfElement;
|
||||
});
|
||||
|
||||
return bytesArray.map((byte: bigint) => String.fromCharCode(Number(byte)));
|
||||
|
||||
@@ -92,15 +92,11 @@ contract ProofOfPassportRegister is IRegister, Ownable {
|
||||
if (bytes32(proof.attestation_id) != attestationId) {
|
||||
revert("Register__InvalidAttestationId");
|
||||
}
|
||||
if (
|
||||
!verifyProof(
|
||||
proof,
|
||||
proof_csca,
|
||||
signature_algorithm,
|
||||
signature_algorithm_csca
|
||||
)
|
||||
) {
|
||||
revert("Register__InvalidProof");
|
||||
if (!verifyProofRegister(proof, signature_algorithm)) {
|
||||
revert("Register__InvalidProofRegister");
|
||||
}
|
||||
if (!verifyProofCSCA(proof_csca, signature_algorithm_csca)) {
|
||||
revert("Register__InvalidProofCSCA");
|
||||
}
|
||||
if (
|
||||
bytes32(proof.blinded_dsc_commitment) !=
|
||||
@@ -120,14 +116,12 @@ contract ProofOfPassportRegister is IRegister, Ownable {
|
||||
);
|
||||
}
|
||||
|
||||
function verifyProof(
|
||||
function verifyProofRegister(
|
||||
RegisterProof calldata proof,
|
||||
CSCAProof calldata proof_csca,
|
||||
uint256 signature_algorithm,
|
||||
uint256 signature_algorithm_csca
|
||||
uint256 signature_algorithm
|
||||
) public view override returns (bool) {
|
||||
return
|
||||
IVerifier(verifiers[signature_algorithm]).verifyProof(
|
||||
bool register_proof_result = IVerifier(verifiers[signature_algorithm])
|
||||
.verifyProof(
|
||||
proof.a,
|
||||
proof.b,
|
||||
proof.c,
|
||||
@@ -137,16 +131,23 @@ contract ProofOfPassportRegister is IRegister, Ownable {
|
||||
uint(proof.commitment),
|
||||
uint(proof.attestation_id)
|
||||
]
|
||||
) &&
|
||||
IVerifierCSCA(cscaVerifier[signature_algorithm_csca]).verifyProof(
|
||||
proof_csca.a,
|
||||
proof_csca.b,
|
||||
proof_csca.c,
|
||||
[
|
||||
uint(proof_csca.blinded_dsc_commitment),
|
||||
uint(proof_csca.merkle_root)
|
||||
]
|
||||
);
|
||||
return register_proof_result;
|
||||
}
|
||||
|
||||
function verifyProofCSCA(
|
||||
CSCAProof calldata proof,
|
||||
uint256 signature_algorithm_csca
|
||||
) public view override returns (bool) {
|
||||
bool csca_proof_result = IVerifierCSCA(
|
||||
cscaVerifier[signature_algorithm_csca]
|
||||
).verifyProof(
|
||||
proof.a,
|
||||
proof.b,
|
||||
proof.c,
|
||||
[uint(proof.blinded_dsc_commitment), uint(proof.merkle_root)]
|
||||
);
|
||||
return csca_proof_result;
|
||||
}
|
||||
|
||||
function _addCommitment(uint256 commitment) internal {
|
||||
|
||||
@@ -37,10 +37,10 @@ contract Verifier_disclose {
|
||||
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
|
||||
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
|
||||
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
|
||||
uint256 constant deltax1 = 17557865657217054151399710026819127874171362865266657132072043760282335721027;
|
||||
uint256 constant deltax2 = 6942436740229168666595536581519256291593117600832247164924519038970269461046;
|
||||
uint256 constant deltay1 = 866803245463331646327183913175583329159450203348438102150009828684148559895;
|
||||
uint256 constant deltay2 = 15629082942757783052734933529055204330846116501031658743204188522840567440030;
|
||||
uint256 constant deltax1 = 15676203424747222008362998300678870836264175060817282396863626616184454326330;
|
||||
uint256 constant deltax2 = 8595392371605829087851094594557910940660445712429027269022585227622642504554;
|
||||
uint256 constant deltay1 = 12203872594051358924092008745444424746295079999395247253358361977634312297663;
|
||||
uint256 constant deltay2 = 12761630983022770637435884556671821605356660389025801528165040076412407626174;
|
||||
|
||||
|
||||
uint256 constant IC0x = 10998553002727424987884583305349753345629818748955483305954960876370686844925;
|
||||
|
||||
@@ -37,26 +37,26 @@ contract Verifier_register_sha1WithRSAEncryption_65537 {
|
||||
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
|
||||
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
|
||||
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
|
||||
uint256 constant deltax1 = 13155179383413945275687042601864057745717821721437680053026365184572594484550;
|
||||
uint256 constant deltax2 = 13419763754509431879614817407927849049139910459488314935101788246897460635978;
|
||||
uint256 constant deltay1 = 21461827286215648586210619400681535578437522448486174192703397303023830118552;
|
||||
uint256 constant deltay2 = 12737898342805752317935622271701172371990602062953535674427676773537602957073;
|
||||
uint256 constant deltax1 = 18253612257067907544176772960107463272624812993732140062961899640928066456080;
|
||||
uint256 constant deltax2 = 17318353882487500984282554464840296751913352404012464994030577338417525343971;
|
||||
uint256 constant deltay1 = 721186767351735401414914095792921248540353988754079694804425043629944474130;
|
||||
uint256 constant deltay2 = 8641160395086880158290557415208090358351831755246287088136583424620790058222;
|
||||
|
||||
|
||||
uint256 constant IC0x = 19950267415749769872984420635469219689637916763338714397594201219209357028767;
|
||||
uint256 constant IC0y = 11341752974833232963273183460328031645291254337522467099721253089381997536320;
|
||||
uint256 constant IC0x = 1014191657240367827160282284111839866462582312274715702627427091205567946886;
|
||||
uint256 constant IC0y = 20064777062727594410930852533508532096138075748869034434640217278789575366962;
|
||||
|
||||
uint256 constant IC1x = 11343271873447077701345513372787017979035448895799705910074152336406632103014;
|
||||
uint256 constant IC1y = 15291140079645029904975407443517463786063189008869473596208133516803303710125;
|
||||
uint256 constant IC1x = 8040733382730768800444374594157736147847832041657938614863886123469540225889;
|
||||
uint256 constant IC1y = 15176962615443332259650291303258627816076442767778878415428831772797210231229;
|
||||
|
||||
uint256 constant IC2x = 6292918500439751291901422848995771412468846049104271000519437364662679332041;
|
||||
uint256 constant IC2y = 1878279471168197263319180659589173388877997868101930670989411481503721284369;
|
||||
uint256 constant IC2x = 11540868305335161307326358835675297677768222525355131845910993931594882318691;
|
||||
uint256 constant IC2y = 2733531636908192599307790060017802843953773596015693191555967489792529852910;
|
||||
|
||||
uint256 constant IC3x = 19090924808474659577406284164688929291816288947267788776359044398392811107731;
|
||||
uint256 constant IC3y = 13853769554127135937032588662814446560788563521681976738789630741456776650960;
|
||||
uint256 constant IC3x = 4726489574882911673974820746815872571311765544934541335124510833035518984566;
|
||||
uint256 constant IC3y = 9959433282395160106486758522716112395005767937241995683289413508988346901679;
|
||||
|
||||
uint256 constant IC4x = 10289494778834425299665842959201067528454414592551242737919429067761473110056;
|
||||
uint256 constant IC4y = 10819880897088345060810729932987810005442991406854600436496172825722441835954;
|
||||
uint256 constant IC4x = 2726107064980905793685456391217077600902590214827304503877626599879070362829;
|
||||
uint256 constant IC4y = 20809786446816938445294209618344975739842207809116419224037622667595617959803;
|
||||
|
||||
|
||||
// Memory data
|
||||
|
||||
@@ -22,58 +22,87 @@ pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
// Scalar field size
|
||||
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
uint256 constant r =
|
||||
21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
// Base field size
|
||||
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
uint256 constant q =
|
||||
21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
|
||||
// Verification Key data
|
||||
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
|
||||
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
|
||||
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
|
||||
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
|
||||
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
|
||||
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
|
||||
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
|
||||
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
|
||||
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
|
||||
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
|
||||
uint256 constant deltax1 = 1037380972141538745399950553909330149820502317843211086553895175257817779372;
|
||||
uint256 constant deltax2 = 1740815875839241540332417489268947801829496353730386086007108179404337117013;
|
||||
uint256 constant deltay1 = 6307674282939481529797944800746136626548126296541382914082037305183098846296;
|
||||
uint256 constant deltay2 = 20598922041836569438727926608870745752734230776330209767048604424081248826810;
|
||||
uint256 constant alphax =
|
||||
20491192805390485299153009773594534940189261866228447918068658471970481763042;
|
||||
uint256 constant alphay =
|
||||
9383485363053290200918347156157836566562967994039712273449902621266178545958;
|
||||
uint256 constant betax1 =
|
||||
4252822878758300859123897981450591353533073413197771768651442665752259397132;
|
||||
uint256 constant betax2 =
|
||||
6375614351688725206403948262868962793625744043794305715222011528459656738731;
|
||||
uint256 constant betay1 =
|
||||
21847035105528745403288232691147584728191162732299865338377159692350059136679;
|
||||
uint256 constant betay2 =
|
||||
10505242626370262277552901082094356697409835680220590971873171140371331206856;
|
||||
uint256 constant gammax1 =
|
||||
11559732032986387107991004021392285783925812861821192530917403151452391805634;
|
||||
uint256 constant gammax2 =
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781;
|
||||
uint256 constant gammay1 =
|
||||
4082367875863433681332203403145435568316851327593401208105741076214120093531;
|
||||
uint256 constant gammay2 =
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930;
|
||||
uint256 constant deltax1 =
|
||||
1037380972141538745399950553909330149820502317843211086553895175257817779372;
|
||||
uint256 constant deltax2 =
|
||||
1740815875839241540332417489268947801829496353730386086007108179404337117013;
|
||||
uint256 constant deltay1 =
|
||||
6307674282939481529797944800746136626548126296541382914082037305183098846296;
|
||||
uint256 constant deltay2 =
|
||||
20598922041836569438727926608870745752734230776330209767048604424081248826810;
|
||||
|
||||
uint256 constant IC0x =
|
||||
9720091360134047110754097159401493796660543288592018718226493514433640874991;
|
||||
uint256 constant IC0y =
|
||||
9816797761738028831499868308538515271427588347801916552504443254539173856438;
|
||||
|
||||
uint256 constant IC1x =
|
||||
8321344198478472159116798038892978501539506318034192464536707151301617026931;
|
||||
uint256 constant IC1y =
|
||||
5162036085088930928154136912718425414931610304133625063308206440957516700168;
|
||||
|
||||
uint256 constant IC2x =
|
||||
13177356501445995293332798335857864829950196156174960167346472326702069056696;
|
||||
uint256 constant IC2y =
|
||||
10123754129821780550611152311412848695235565741848206360569448620207136999663;
|
||||
|
||||
uint256 constant IC3x =
|
||||
15800750648534882001293098141511862547516231817837268745140708055565406852893;
|
||||
uint256 constant IC3y =
|
||||
3111875870276149539313318494349104168321847784629653817811461001326987877496;
|
||||
|
||||
uint256 constant IC4x =
|
||||
11374553600031801461260163829101393652119031120393018855112829004013226583739;
|
||||
uint256 constant IC4y =
|
||||
11948013189599962904927300285557649747124295332223275928752245757162896852086;
|
||||
|
||||
|
||||
uint256 constant IC0x = 9720091360134047110754097159401493796660543288592018718226493514433640874991;
|
||||
uint256 constant IC0y = 9816797761738028831499868308538515271427588347801916552504443254539173856438;
|
||||
|
||||
uint256 constant IC1x = 8321344198478472159116798038892978501539506318034192464536707151301617026931;
|
||||
uint256 constant IC1y = 5162036085088930928154136912718425414931610304133625063308206440957516700168;
|
||||
|
||||
uint256 constant IC2x = 13177356501445995293332798335857864829950196156174960167346472326702069056696;
|
||||
uint256 constant IC2y = 10123754129821780550611152311412848695235565741848206360569448620207136999663;
|
||||
|
||||
uint256 constant IC3x = 15800750648534882001293098141511862547516231817837268745140708055565406852893;
|
||||
uint256 constant IC3y = 3111875870276149539313318494349104168321847784629653817811461001326987877496;
|
||||
|
||||
uint256 constant IC4x = 11374553600031801461260163829101393652119031120393018855112829004013226583739;
|
||||
uint256 constant IC4y = 11948013189599962904927300285557649747124295332223275928752245757162896852086;
|
||||
|
||||
|
||||
// Memory data
|
||||
uint16 constant pVk = 0;
|
||||
uint16 constant pPairing = 128;
|
||||
|
||||
uint16 constant pLastMem = 896;
|
||||
|
||||
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[4] calldata _pubSignals) public view returns (bool) {
|
||||
function verifyProof(
|
||||
uint[2] calldata _pA,
|
||||
uint[2][2] calldata _pB,
|
||||
uint[2] calldata _pC,
|
||||
uint[4] calldata _pubSignals
|
||||
) public view returns (bool) {
|
||||
assembly {
|
||||
function checkField(v) {
|
||||
if iszero(lt(v, q)) {
|
||||
if iszero(lt(v, r)) {
|
||||
mstore(0, 0)
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// G1 function to multiply a G1 value(x,y) to value in an address
|
||||
function g1_mulAccC(pR, x, y, s) {
|
||||
let success
|
||||
@@ -108,19 +137,21 @@ contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
mstore(add(_pVk, 32), IC0y)
|
||||
|
||||
// Compute the linear combination vk_x
|
||||
|
||||
|
||||
g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
|
||||
|
||||
|
||||
g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
|
||||
|
||||
|
||||
g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
|
||||
|
||||
|
||||
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
|
||||
|
||||
|
||||
// -A
|
||||
mstore(_pPairing, calldataload(pA))
|
||||
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
|
||||
mstore(
|
||||
add(_pPairing, 32),
|
||||
mod(sub(q, calldataload(add(pA, 32))), q)
|
||||
)
|
||||
|
||||
// B
|
||||
mstore(add(_pPairing, 64), calldataload(pB))
|
||||
@@ -142,7 +173,6 @@ contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
|
||||
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))
|
||||
|
||||
|
||||
// gamma2
|
||||
mstore(add(_pPairing, 448), gammax1)
|
||||
mstore(add(_pPairing, 480), gammax2)
|
||||
@@ -159,8 +189,14 @@ contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
mstore(add(_pPairing, 704), deltay1)
|
||||
mstore(add(_pPairing, 736), deltay2)
|
||||
|
||||
|
||||
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)
|
||||
let success := staticcall(
|
||||
sub(gas(), 2000),
|
||||
8,
|
||||
_pPairing,
|
||||
768,
|
||||
_pPairing,
|
||||
0x20
|
||||
)
|
||||
|
||||
isOk := and(success, mload(_pPairing))
|
||||
}
|
||||
@@ -169,23 +205,22 @@ contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
mstore(0x40, add(pMem, pLastMem))
|
||||
|
||||
// Validate that all evaluations ∈ F
|
||||
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 0)))
|
||||
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 32)))
|
||||
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 64)))
|
||||
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 96)))
|
||||
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 128)))
|
||||
|
||||
|
||||
// Validate all evaluations
|
||||
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
|
||||
|
||||
mstore(0, isValid)
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
/*
|
||||
Copyright 2021 0KIMS association.
|
||||
|
||||
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
|
||||
|
||||
snarkJS is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
snarkJS is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
pragma solidity >=0.7.0 <0.9.0;
|
||||
|
||||
contract Verifier_register_sha256WithRSAEncryption_65537 {
|
||||
// Scalar field size
|
||||
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
// Base field size
|
||||
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
|
||||
// Verification Key data
|
||||
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
|
||||
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
|
||||
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
|
||||
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
|
||||
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
|
||||
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
|
||||
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
|
||||
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
|
||||
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
|
||||
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
|
||||
uint256 constant deltax1 = 15594951545396927133821323111112838246440151372486640584540136770576637393038;
|
||||
uint256 constant deltax2 = 16646501228722464486042890930566300897412243452681656199619061425330163109294;
|
||||
uint256 constant deltay1 = 7391847066598204603635570301223858822745255584907407139867164202959899110336;
|
||||
uint256 constant deltay2 = 16818942323013965805725851186284589299702074465619454314061881957166689439913;
|
||||
|
||||
|
||||
uint256 constant IC0x = 9720091360134047110754097159401493796660543288592018718226493514433640874991;
|
||||
uint256 constant IC0y = 9816797761738028831499868308538515271427588347801916552504443254539173856438;
|
||||
|
||||
uint256 constant IC1x = 8321344198478472159116798038892978501539506318034192464536707151301617026931;
|
||||
uint256 constant IC1y = 5162036085088930928154136912718425414931610304133625063308206440957516700168;
|
||||
|
||||
uint256 constant IC2x = 13177356501445995293332798335857864829950196156174960167346472326702069056696;
|
||||
uint256 constant IC2y = 10123754129821780550611152311412848695235565741848206360569448620207136999663;
|
||||
|
||||
uint256 constant IC3x = 15800750648534882001293098141511862547516231817837268745140708055565406852893;
|
||||
uint256 constant IC3y = 3111875870276149539313318494349104168321847784629653817811461001326987877496;
|
||||
|
||||
uint256 constant IC4x = 11374553600031801461260163829101393652119031120393018855112829004013226583739;
|
||||
uint256 constant IC4y = 11948013189599962904927300285557649747124295332223275928752245757162896852086;
|
||||
|
||||
|
||||
// Memory data
|
||||
uint16 constant pVk = 0;
|
||||
uint16 constant pPairing = 128;
|
||||
|
||||
uint16 constant pLastMem = 896;
|
||||
|
||||
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[4] calldata _pubSignals) public view returns (bool) {
|
||||
assembly {
|
||||
function checkField(v) {
|
||||
if iszero(lt(v, q)) {
|
||||
mstore(0, 0)
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
|
||||
// G1 function to multiply a G1 value(x,y) to value in an address
|
||||
function g1_mulAccC(pR, x, y, s) {
|
||||
let success
|
||||
let mIn := mload(0x40)
|
||||
mstore(mIn, x)
|
||||
mstore(add(mIn, 32), y)
|
||||
mstore(add(mIn, 64), s)
|
||||
|
||||
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
|
||||
|
||||
if iszero(success) {
|
||||
mstore(0, 0)
|
||||
return(0, 0x20)
|
||||
}
|
||||
|
||||
mstore(add(mIn, 64), mload(pR))
|
||||
mstore(add(mIn, 96), mload(add(pR, 32)))
|
||||
|
||||
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
|
||||
|
||||
if iszero(success) {
|
||||
mstore(0, 0)
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
|
||||
function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
|
||||
let _pPairing := add(pMem, pPairing)
|
||||
let _pVk := add(pMem, pVk)
|
||||
|
||||
mstore(_pVk, IC0x)
|
||||
mstore(add(_pVk, 32), IC0y)
|
||||
|
||||
// Compute the linear combination vk_x
|
||||
|
||||
g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
|
||||
|
||||
g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
|
||||
|
||||
g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
|
||||
|
||||
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
|
||||
|
||||
|
||||
// -A
|
||||
mstore(_pPairing, calldataload(pA))
|
||||
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
|
||||
|
||||
// B
|
||||
mstore(add(_pPairing, 64), calldataload(pB))
|
||||
mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
|
||||
mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
|
||||
mstore(add(_pPairing, 160), calldataload(add(pB, 96)))
|
||||
|
||||
// alpha1
|
||||
mstore(add(_pPairing, 192), alphax)
|
||||
mstore(add(_pPairing, 224), alphay)
|
||||
|
||||
// beta2
|
||||
mstore(add(_pPairing, 256), betax1)
|
||||
mstore(add(_pPairing, 288), betax2)
|
||||
mstore(add(_pPairing, 320), betay1)
|
||||
mstore(add(_pPairing, 352), betay2)
|
||||
|
||||
// vk_x
|
||||
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
|
||||
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))
|
||||
|
||||
|
||||
// gamma2
|
||||
mstore(add(_pPairing, 448), gammax1)
|
||||
mstore(add(_pPairing, 480), gammax2)
|
||||
mstore(add(_pPairing, 512), gammay1)
|
||||
mstore(add(_pPairing, 544), gammay2)
|
||||
|
||||
// C
|
||||
mstore(add(_pPairing, 576), calldataload(pC))
|
||||
mstore(add(_pPairing, 608), calldataload(add(pC, 32)))
|
||||
|
||||
// delta2
|
||||
mstore(add(_pPairing, 640), deltax1)
|
||||
mstore(add(_pPairing, 672), deltax2)
|
||||
mstore(add(_pPairing, 704), deltay1)
|
||||
mstore(add(_pPairing, 736), deltay2)
|
||||
|
||||
|
||||
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)
|
||||
|
||||
isOk := and(success, mload(_pPairing))
|
||||
}
|
||||
|
||||
let pMem := mload(0x40)
|
||||
mstore(0x40, add(pMem, pLastMem))
|
||||
|
||||
// Validate that all evaluations ∈ F
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 0)))
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 32)))
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 64)))
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 96)))
|
||||
|
||||
checkField(calldataload(add(_pubSignals, 128)))
|
||||
|
||||
|
||||
// Validate all evaluations
|
||||
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
|
||||
|
||||
mstore(0, isValid)
|
||||
return(0, 0x20)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ interface IRegister {
|
||||
/// @notice Error thrown when the same nullifier is used more than once
|
||||
error Register__YouAreUsingTheSameNullifierTwice();
|
||||
/// @notice Error thrown when the proof provided is invalid
|
||||
error Register__InvalidProof();
|
||||
error Register__InvalidProofRegister();
|
||||
/// @notice Error thrown when the proof provided is invalid
|
||||
error Register__InvalidProofCSCA();
|
||||
/// @notice Error thrown when the signature algorithm provided is invalid
|
||||
error Register__InvalidSignatureAlgorithm();
|
||||
/// @notice Error thrown when the verifier address is invalid
|
||||
@@ -65,10 +67,16 @@ interface IRegister {
|
||||
/// @notice Verifies a Register proof
|
||||
/// @param proof The Register proof to verify
|
||||
/// @return bool Returns true if the proof is valid, false otherwise
|
||||
function verifyProof(
|
||||
function verifyProofRegister(
|
||||
RegisterProof calldata proof,
|
||||
CSCAProof calldata proof_csca,
|
||||
uint256 signature_algorithm,
|
||||
uint256 signature_algorithm
|
||||
) external view returns (bool);
|
||||
|
||||
/// @notice Verifies a Register proof
|
||||
/// @param proof The Register proof to verify
|
||||
/// @return bool Returns true if the proof is valid, false otherwise
|
||||
function verifyProofCSCA(
|
||||
CSCAProof calldata proof,
|
||||
uint256 signature_algorithm_csca
|
||||
) external view returns (bool);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
||||
import { formatRoot } from "../../../common/src/utils/utils";
|
||||
import { generateCircuitInputsRegister } from "../../../common/src/utils/generateInputs";
|
||||
import { mockPassportData_sha256WithRSAEncryption_65537 } from "../../../common/src/utils/mockPassportData";
|
||||
import { countryCodes, k_csca, n_csca } from "../../../common/src/constants/constants";
|
||||
import { getCSCAModulusMerkleTree } from "../../../common/src/utils/csca";
|
||||
|
||||
@@ -15,11 +14,11 @@ export default buildModule("Deploy_Registry", (m) => {
|
||||
const register = m.contract("ProofOfPassportRegister", [registry], { libraries: { PoseidonT3: poseidonT3 } });
|
||||
const Verifier_register_sha256WithRSAEncryption_65537 = m.contract("Verifier_register_sha256WithRSAEncryption_65537");
|
||||
const Verifier_register_sha1WithRSAEncryption_65537 = m.contract("Verifier_register_sha1WithRSAEncryption_65537");
|
||||
const Verifier_dsc_4096 = m.contract("Verifier_dsc_4096");
|
||||
const Verifier_dsc_sha256_rsa_4096 = m.contract("Verifier_dsc_sha256_rsa_4096");
|
||||
|
||||
m.call(register, "addSignatureAlgorithm", [1, Verifier_register_sha256WithRSAEncryption_65537], { id: "a" });
|
||||
m.call(register, "addSignatureAlgorithm", [3, Verifier_register_sha1WithRSAEncryption_65537], { id: "b" });
|
||||
m.call(register, "addCSCAVerifier", [1, Verifier_dsc_4096], { id: "c" });
|
||||
m.call(register, "addCSCAVerifier", [1, Verifier_dsc_sha256_rsa_4096], { id: "c" });
|
||||
|
||||
const verifier_disclose = m.contract("Verifier_disclose");
|
||||
const sbt = m.contract("SBT", [verifier_disclose, formatter, register]);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
||||
import { getCSCAModulusMerkleTree } from "../../../../common/src/utils/csca";
|
||||
import { formatRoot } from "../../../../common/src/utils/utils";
|
||||
|
||||
module.exports = buildModule("UpdateMerkleRoot", (m) => {
|
||||
|
||||
const registryAddress = "0xBabF700EdE592Aa69e14B5BAE1859ee4164C3323";
|
||||
|
||||
const deployedRocketInstance = m.contractAt("Registry", registryAddress);
|
||||
console.log("Deployed registry instance", deployedRocketInstance);
|
||||
const merkleRoot = formatRoot(getCSCAModulusMerkleTree().root);
|
||||
console.log("Merkle root", merkleRoot);
|
||||
m.call(deployedRocketInstance, "update", [merkleRoot]);
|
||||
return { deployedRocketInstance };
|
||||
});
|
||||
15
contracts/ignition/modules/scripts/update_merkle_root.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
||||
import { getCSCAModulusMerkleTree } from "../../../../common/src/utils/csca";
|
||||
import { formatRoot } from "../../../../common/src/utils/utils";
|
||||
|
||||
module.exports = buildModule("UpdateMerkleRoot", (m) => {
|
||||
|
||||
const registryAddress = "0xBabF700EdE592Aa69e14B5BAE1859ee4164C3323";
|
||||
|
||||
const deployedRocketInstance = m.contractAt("Registry", registryAddress);
|
||||
console.log("Deployed registry instance", deployedRocketInstance);
|
||||
const merkleRoot = formatRoot(getCSCAModulusMerkleTree().root);
|
||||
console.log("Merkle root", merkleRoot);
|
||||
m.call(deployedRocketInstance, "update", [merkleRoot]);
|
||||
return { deployedRocketInstance };
|
||||
});
|
||||
15
contracts/ignition/modules/scripts/update_verifier.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
||||
import { getCSCAModulusMerkleTree } from "../../../../common/src/utils/csca";
|
||||
import { formatRoot } from "../../../../common/src/utils/utils";
|
||||
|
||||
module.exports = buildModule("UpdateMerkleRoot", (m) => {
|
||||
|
||||
const registryAddress = "0xBabF700EdE592Aa69e14B5BAE1859ee4164C3323";
|
||||
|
||||
const deployedRocketInstance = m.contractAt("Registry", registryAddress);
|
||||
console.log("Deployed registry instance", deployedRocketInstance);
|
||||
const merkleRoot = formatRoot(getCSCAModulusMerkleTree().root);
|
||||
console.log("Merkle root", merkleRoot);
|
||||
m.call(deployedRocketInstance, "update", [merkleRoot]);
|
||||
return { deployedRocketInstance };
|
||||
});
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"name": "hardhat-project",
|
||||
"scripts": {
|
||||
"test": "npx hardhat test",
|
||||
"deploy_all": "npx hardhat ignition deploy ignition/modules/Deploy_All.ts --network optimism --verify",
|
||||
"compile": "npx hardhat compile"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.6",
|
||||
"@nomicfoundation/hardhat-ethers": "^3.0.5",
|
||||
@@ -16,7 +21,7 @@
|
||||
"@types/snarkjs": "^0.7.7",
|
||||
"chai": "^4.4.1",
|
||||
"ethers": "^6.12.1",
|
||||
"hardhat": "^2.22.3",
|
||||
"hardhat": "^2.22.6",
|
||||
"hardhat-gas-reporter": "^1.0.10",
|
||||
"solidity-coverage": "^0.8.12",
|
||||
"ts-node": "^10.9.1",
|
||||
@@ -42,4 +47,4 @@
|
||||
"poseidon-solidity": "^0.0.5",
|
||||
"snarkjs": "^0.7.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { expect, assert } from "chai";
|
||||
import { ethers } from "hardhat";
|
||||
// import { describe } from "mocha";
|
||||
import { mockPassportData_sha256WithRSASSAPSS_65537, mockPassportData_sha1WithRSAEncryption_65537, mockPassportData_sha256WithRSAEncryption_65537 } from "../../common/src/utils/mockPassportData";
|
||||
import { mockPassportData_sha256_rsa_65537, mockPassportData_sha1_rsa_65537, } from "../../common/src/constants/mockPassportData";
|
||||
import { countryCodes, PASSPORT_ATTESTATION_ID, SignatureAlgorithm } from "../../common/src/constants/constants";
|
||||
import { formatRoot } from "../../common/src/utils/utils";
|
||||
import { groth16 } from 'snarkjs'
|
||||
@@ -12,14 +12,11 @@ import fs from 'fs';
|
||||
import { LeanIMT } from "@zk-kit/lean-imt";
|
||||
import { poseidon2 } from "poseidon-lite";
|
||||
import { Signer } from "ethers";
|
||||
import { getCSCAInputs } from "../../common/src/utils/csca";
|
||||
import { getCSCAInputs, getCSCAModulusMerkleTree } from "../../common/src/utils/csca";
|
||||
import forge from "node-forge";
|
||||
import { mock_csca_sha256_rsa_4096, mock_dsc_sha256_rsa_4096 } from '../../common/src/constants/mockCertificates';
|
||||
import { mock_csca_sha256_rsa_4096, mock_dsc_sha256_rsa_4096, mock_dsc_sha1_rsa_4096, mock_csca_sha1_rsa_4096 } from '../../common/src/constants/mockCertificates';
|
||||
|
||||
//const mock_dsc_sha256_rsa_4096 = fs.readFileSync('../common/src/mock_certificates/sha256_rsa_4096/mock_dsc.pem', 'utf8');
|
||||
//const mock_csca_sha256_rsa_4096 = fs.readFileSync('../common/src/mock_certificates/sha256_rsa_4096/mock_csca.pem', 'utf8');
|
||||
|
||||
type RegisterCircuitArtifacts = {
|
||||
type CircuitArtifacts = {
|
||||
[key: string]: {
|
||||
wasm: string,
|
||||
zkey: string,
|
||||
@@ -35,18 +32,19 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
this.timeout(0);
|
||||
|
||||
let proof, publicSignals;
|
||||
let proof_dsc
|
||||
|
||||
const register_circuits: RegisterCircuitArtifacts = {
|
||||
const register_circuits: CircuitArtifacts = {
|
||||
sha256WithRSAEncryption_65537: {
|
||||
wasm: "../circuits/build/register_sha256WithRSAEncryption_65537_js/register_sha256WithRSAEncryption_65537.wasm",
|
||||
zkey: "../circuits/build/register_sha256WithRSAEncryption_65537_final.zkey",
|
||||
vkey: "../circuits/build/register_sha256WithRSAEncryption_65537_vkey.json"
|
||||
},
|
||||
// sha1WithRSAEncryption_65537: {
|
||||
// wasm: "../circuits/build/register_sha1WithRSAEncryption_65537_js/register_sha1WithRSAEncryption_65537.wasm",
|
||||
// zkey: "../circuits/build/register_sha1WithRSAEncryption_65537_final.zkey",
|
||||
// vkey: "../circuits/build/register_sha1WithRSAEncryption_65537_vkey.json"
|
||||
// },
|
||||
sha1WithRSAEncryption_65537: {
|
||||
wasm: "../circuits/build/register_sha1WithRSAEncryption_65537_js/register_sha1WithRSAEncryption_65537.wasm",
|
||||
zkey: "../circuits/build/register_sha1WithRSAEncryption_65537_final.zkey",
|
||||
vkey: "../circuits/build/register_sha1WithRSAEncryption_65537_vkey.json"
|
||||
},
|
||||
// sha256WithRSASSAPSS_65537: {
|
||||
// wasm: "../circuits/build/register_sha256WithRSASSAPSS_65537_js/register_sha256WithRSASSAPSS_65537.wasm",
|
||||
// zkey: "../circuits/build/register_sha256WithRSASSAPSS_65537_final.zkey",
|
||||
@@ -54,29 +52,32 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
// }
|
||||
}
|
||||
|
||||
const path_dsc_wasm = "../circuits/build/dsc_4096_js/dsc_4096.wasm";
|
||||
const path_dsc_zkey = "../circuits/build/dsc_4096_final.zkey";
|
||||
const path_dsc_vkey = "../circuits/build/dsc_4096_vkey.json";
|
||||
const dsc_circuits: CircuitArtifacts = {
|
||||
sha256WithRSAEncryption_65537: {
|
||||
wasm: "../circuits/build/dsc_sha256_rsa_4096_js/dsc_sha256_rsa_4096.wasm",
|
||||
zkey: "../circuits/build/dsc_sha256_rsa_4096_final.zkey",
|
||||
vkey: "../circuits/build/dsc_sha256_rsa_4096_vkey.json"
|
||||
},
|
||||
sha1WithRSAEncryption_65537: {
|
||||
wasm: "../circuits/build/dsc_sha1_rsa_4096_js/dsc_sha1_rsa_4096.wasm",
|
||||
zkey: "../circuits/build/dsc_sha1_rsa_4096_final.zkey",
|
||||
vkey: "../circuits/build/dsc_sha1_rsa_4096_vkey.json"
|
||||
}
|
||||
}
|
||||
|
||||
const path_disclose_wasm = "../circuits/build/disclose_js/disclose.wasm";
|
||||
const path_disclose_zkey = "../circuits/build/disclose_final.zkey";
|
||||
const path_disclose_vkey = "../circuits/build/disclose_vkey.json";
|
||||
|
||||
// Smart contracts
|
||||
let Verifier_register: any, verifier_register: any, Registry: any, Formatter: any, Register: any, Verifier_disclose: any, SBT: any, PoseidonT3: any;
|
||||
let Verifier_dsc: any, verifier_dsc: any, parsedCallData_dsc: any[], formattedCallData_dsc: any;
|
||||
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
const n_csca = 121;
|
||||
const k_csca = 34;
|
||||
const max_cert_bytes = 1664;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha256_rsa_4096);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha256_rsa_4096);
|
||||
let inputs_csca = getCSCAInputs(BigInt(0).toString(), dscCert, cscaCert, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
let parsedCallData_csca: any;
|
||||
let formattedCallData_csca: any;
|
||||
// console.log(inputs_csca);
|
||||
const dscCert_sha256 = forge.pki.certificateFromPem(mock_dsc_sha256_rsa_4096);
|
||||
const cscaCert_sha256 = forge.pki.certificateFromPem(mock_csca_sha256_rsa_4096);
|
||||
const dscCert_sha1 = forge.pki.certificateFromPem(mock_dsc_sha1_rsa_4096);
|
||||
const cscaCert_sha1 = forge.pki.certificateFromPem(mock_csca_sha1_rsa_4096);
|
||||
|
||||
let user_identifier, current_date;
|
||||
let registry: any, formatter: any, register: any, verifier_disclose: any, sbt: any, poseidonT3: any
|
||||
@@ -85,7 +86,7 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
let bitmap, scope, user_address, majority, input_disclose: any;
|
||||
let proof_disclose, publicSignals_disclose, proof_result_disclose, vkey_disclose, verified_disclose: any, rawCallData_disclose, parsedCallData_disclose: any[], formattedCallData_disclose: any;
|
||||
let proof_csca, publicSignals_csca: any;
|
||||
//let proof_csca, publicSignals_csca: any;
|
||||
let secret: string = BigInt(0).toString();
|
||||
let attestation_id: string = PASSPORT_ATTESTATION_ID;
|
||||
|
||||
@@ -99,27 +100,32 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
register_circuits.sha256WithRSAEncryption_65537.inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
BigInt(0).toString(),
|
||||
secret,
|
||||
attestation_id,
|
||||
mockPassportData_sha256WithRSAEncryption_65537,
|
||||
mockPassportData_sha256_rsa_65537,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
register_circuits.sha1WithRSAEncryption_65537.inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
secret,
|
||||
attestation_id,
|
||||
mockPassportData_sha1_rsa_65537,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
|
||||
);
|
||||
console.log("inputs signature length", register_circuits.sha256WithRSAEncryption_65537.inputs.signature.length);
|
||||
|
||||
// register_circuits.sha1WithRSAEncryption_65537.inputs = generateCircuitInputsRegister(
|
||||
// secret,
|
||||
// attestation_id,
|
||||
// mockPassportData_sha1WithRSAEncryption_65537,
|
||||
// );
|
||||
dsc_circuits.sha256WithRSAEncryption_65537.inputs = getCSCAInputs(BigInt(0).toString(), dscCert_sha256, cscaCert_sha256, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
dsc_circuits.sha1WithRSAEncryption_65537.inputs = getCSCAInputs(BigInt(0).toString(), dscCert_sha1, cscaCert_sha1, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
|
||||
|
||||
|
||||
// register_circuits.sha256WithRSASSAPSS_65537.inputs = generateCircuitInputsRegister(
|
||||
// secret,
|
||||
// attestation_id,
|
||||
// mockPassportData_sha256WithRSASSAPSS_65537,
|
||||
// );
|
||||
console.log("inputs", register_circuits.sha256WithRSAEncryption_65537.inputs);
|
||||
//console.log("inputs", register_circuits.sha256WithRSAEncryption_65537.inputs);
|
||||
|
||||
/*** Deploy contracts ***/
|
||||
await deployContracts();
|
||||
@@ -141,10 +147,17 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
};
|
||||
}
|
||||
|
||||
Verifier_dsc = await ethers.getContractFactory("Verifier_dsc_4096");
|
||||
verifier_dsc = await Verifier_dsc.deploy();
|
||||
await verifier_dsc.waitForDeployment();
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_dsc deployed to ${verifier_dsc.target}`);
|
||||
const Verifier_dsc_sha256_rsa_4096 = await ethers.getContractFactory("Verifier_dsc_sha256_rsa_4096");
|
||||
const verifier_dsc_sha256_rsa_4096 = await Verifier_dsc_sha256_rsa_4096.deploy();
|
||||
await verifier_dsc_sha256_rsa_4096.waitForDeployment();
|
||||
dsc_circuits.sha256WithRSAEncryption_65537.verifier = verifier_dsc_sha256_rsa_4096;
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_dsc_sha256_rsa_4096 deployed to ${verifier_dsc_sha256_rsa_4096.target}`);
|
||||
|
||||
const Verifier_dsc_sha1_rsa_4096 = await ethers.getContractFactory("Verifier_dsc_sha1_rsa_4096");
|
||||
const verifier_dsc_sha1_rsa_4096 = await Verifier_dsc_sha1_rsa_4096.deploy();
|
||||
await verifier_dsc_sha1_rsa_4096.waitForDeployment();
|
||||
dsc_circuits.sha1WithRSAEncryption_65537.verifier = verifier_dsc_sha1_rsa_4096;
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_dsc_sha1_rsa_4096 deployed to ${verifier_dsc_sha1_rsa_4096.target}`);
|
||||
|
||||
const Verifier_register_sha256WithRSAEncryption_65537 = await ethers.getContractFactory("Verifier_register_sha256WithRSAEncryption_65537");
|
||||
const verifier_register_sha256WithRSAEncryption_65537 = await Verifier_register_sha256WithRSAEncryption_65537.deploy(deployOptions);
|
||||
@@ -152,11 +165,11 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
register_circuits.sha256WithRSAEncryption_65537.verifier = verifier_register_sha256WithRSAEncryption_65537;
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_register_sha256WithRSAEncryption_65537 deployed to ${verifier_register_sha256WithRSAEncryption_65537.target}`);
|
||||
|
||||
// const Verifier_register_sha1WithRSAEncryption_65537 = await ethers.getContractFactory("Verifier_register_sha1WithRSAEncryption_65537");
|
||||
// const verifier_register_sha1WithRSAEncryption_65537 = await Verifier_register_sha1WithRSAEncryption_65537.deploy(deployOptions);
|
||||
// await verifier_register_sha1WithRSAEncryption_65537.waitForDeployment();
|
||||
// register_circuits.sha1WithRSAEncryption_65537.verifier = verifier_register_sha1WithRSAEncryption_65537;
|
||||
// console.log('\x1b[34m%s\x1b[0m', `Verifier_register_sha1WithRSAEncryption_65537 deployed to ${verifier_register_sha1WithRSAEncryption_65537.target}`);
|
||||
const Verifier_register_sha1WithRSAEncryption_65537 = await ethers.getContractFactory("Verifier_register_sha1WithRSAEncryption_65537");
|
||||
const verifier_register_sha1WithRSAEncryption_65537 = await Verifier_register_sha1WithRSAEncryption_65537.deploy(deployOptions);
|
||||
await verifier_register_sha1WithRSAEncryption_65537.waitForDeployment();
|
||||
register_circuits.sha1WithRSAEncryption_65537.verifier = verifier_register_sha1WithRSAEncryption_65537;
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_register_sha1WithRSAEncryption_65537 deployed to ${verifier_register_sha1WithRSAEncryption_65537.target}`);
|
||||
|
||||
// const Verifier_register_sha256WithRSASSAPSS_65537 = await ethers.getContractFactory("Verifier_register_sha256WithRSASSAPSS_65537");
|
||||
// const verifier_register_sha256WithRSASSAPSS_65537 = await Verifier_register_sha256WithRSASSAPSS_65537.deploy(deployOptions);
|
||||
@@ -171,7 +184,8 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
console.log('\x1b[34m%s\x1b[0m', `Formatter deployed to ${formatter.target}`);
|
||||
|
||||
const Registry = await ethers.getContractFactory("Registry");
|
||||
registry = await Registry.deploy(formatRoot(inputs_csca.merkle_root.toString()), deployOptions);
|
||||
const merkleTree = getCSCAModulusMerkleTree();
|
||||
registry = await Registry.deploy(formatRoot(merkleTree.root), deployOptions);
|
||||
await registry.waitForDeployment();
|
||||
console.log('\x1b[34m%s\x1b[0m', `Registry deployed to ${registry.target}`);
|
||||
|
||||
@@ -190,7 +204,7 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
await register.waitForDeployment();
|
||||
console.log('\x1b[34m%s\x1b[0m', `Register deployed to ${register.target}`);
|
||||
|
||||
console.log("register merkle root:", await registry.getMerkleRoot());
|
||||
// console.log("register merkle root:", await registry.getMerkleRoot());
|
||||
|
||||
const Verifier_disclose = await ethers.getContractFactory("Verifier_disclose");
|
||||
verifier_disclose = await Verifier_disclose.deploy(deployOptions);
|
||||
@@ -198,9 +212,9 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
console.log('\x1b[34m%s\x1b[0m', `Verifier_disclose deployed to ${verifier_disclose.target}`);
|
||||
|
||||
await register.addSignatureAlgorithm(SignatureAlgorithm["sha256WithRSAEncryption_65537"], verifier_register_sha256WithRSAEncryption_65537.target);
|
||||
await register.addCSCAVerifier(SignatureAlgorithm["sha256WithRSAEncryption_65537"], verifier_dsc.target);
|
||||
// await register.addSignatureAlgorithm(SignatureAlgorithm["sha1WithRSAEncryption_65537"], verifier_register_sha1WithRSAEncryption_65537.target);
|
||||
// await register.addSignatureAlgorithm(SignatureAlgorithm["sha256WithRSASSAPSS_65537"], verifier_register_sha256WithRSASSAPSS_65537.target);
|
||||
await register.addCSCAVerifier(SignatureAlgorithm["sha256WithRSAEncryption_65537"], verifier_dsc_sha256_rsa_4096.target);
|
||||
await register.addSignatureAlgorithm(SignatureAlgorithm["sha1WithRSAEncryption_65537"], verifier_register_sha1WithRSAEncryption_65537.target);
|
||||
await register.addCSCAVerifier(SignatureAlgorithm["sha1WithRSAEncryption_65537"], verifier_dsc_sha1_rsa_4096.target);
|
||||
|
||||
const SBT = await ethers.getContractFactory("SBT");
|
||||
sbt = await SBT.deploy(
|
||||
@@ -229,24 +243,28 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
/*** Register flow ***/
|
||||
describe("Proof of Passport - Register flow", function () {
|
||||
const sigAlgNames = ['sha256WithRSAEncryption_65537'] //, 'sha1WithRSAEncryption_65537', 'sha256WithRSASSAPSS_65537']
|
||||
const sigAlgNames = ['sha256WithRSAEncryption_65537', 'sha1WithRSAEncryption_65537'] //, 'sha1WithRSAEncryption_65537', 'sha256WithRSASSAPSS_65537']
|
||||
|
||||
before(async function () {
|
||||
await Promise.all(sigAlgNames.map(async (sigAlgName) => {
|
||||
const sigAlgArtifacts = register_circuits[sigAlgName];
|
||||
const sigAlgArtifacts_register = register_circuits[sigAlgName];
|
||||
/*** Groth16 saga Register***/
|
||||
// Generate the proofs
|
||||
console.log('\x1b[32m%s\x1b[0m', `Generating proof csca - ${sigAlgName}`);
|
||||
console.log("csc_modulus_length", inputs_csca.csca_modulus.length);
|
||||
//console.log("csc_modulus_length", inputs_csca.inputs.csca_modulus.length);
|
||||
const proof_csca_result = await groth16.fullProve(
|
||||
inputs_csca,
|
||||
path_dsc_wasm,
|
||||
path_dsc_zkey
|
||||
dsc_circuits[sigAlgName].inputs.inputs,
|
||||
dsc_circuits[sigAlgName].wasm,
|
||||
dsc_circuits[sigAlgName].zkey
|
||||
)
|
||||
proof_csca = proof_csca_result.proof;
|
||||
publicSignals_csca = proof_csca_result.publicSignals;
|
||||
const proof_csca = proof_csca_result.proof;
|
||||
const publicSignals_csca = proof_csca_result.publicSignals;
|
||||
|
||||
console.log('\x1b[32m%s\x1b[0m', `Proof generated csca - ${sigAlgName}`);
|
||||
const vKey_csca = JSON.parse(fs.readFileSync(path_dsc_vkey) as unknown as string);
|
||||
// console.log("proof_csca", proof_csca);
|
||||
// console.log("publicSignals_csca", publicSignals_csca);
|
||||
|
||||
const vKey_csca = JSON.parse(fs.readFileSync(dsc_circuits[sigAlgName].vkey) as unknown as string);
|
||||
const verified_csca = await groth16.verify(
|
||||
vKey_csca,
|
||||
publicSignals_csca,
|
||||
@@ -255,20 +273,19 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
assert(verified_csca == true, 'Should verify')
|
||||
console.log('\x1b[32m%s\x1b[0m', `Proof verified csca - ${sigAlgName}`);
|
||||
const rawCallData_csca = await groth16.exportSolidityCallData(proof_csca, publicSignals_csca);
|
||||
parsedCallData_csca = JSON.parse(`[${rawCallData_csca}]`);
|
||||
console.log('parsedCallData_csca', parsedCallData_csca);
|
||||
formattedCallData_csca = formatCallData_dsc(parsedCallData_csca);
|
||||
console.log('formattedCallData_csca', formattedCallData_csca);
|
||||
dsc_circuits[sigAlgName].parsedCallData = JSON.parse(`[${rawCallData_csca}]`);
|
||||
dsc_circuits[sigAlgName].formattedCallData = formatCallData_dsc(dsc_circuits[sigAlgName].parsedCallData);
|
||||
|
||||
//console.log('inputs', sigAlgArtifacts_register.inputs);
|
||||
console.log('\x1b[32m%s\x1b[0m', `Generating proof register - ${sigAlgName}`);
|
||||
({ proof, publicSignals } = await groth16.fullProve(
|
||||
sigAlgArtifacts.inputs,
|
||||
sigAlgArtifacts.wasm,
|
||||
sigAlgArtifacts.zkey
|
||||
sigAlgArtifacts_register.inputs,
|
||||
sigAlgArtifacts_register.wasm,
|
||||
sigAlgArtifacts_register.zkey
|
||||
))
|
||||
console.log('\x1b[32m%s\x1b[0m', `Proof generated register - ${sigAlgName}`);
|
||||
// Verify the proof
|
||||
const vKey = JSON.parse(fs.readFileSync(sigAlgArtifacts.vkey) as unknown as string);
|
||||
const vKey = JSON.parse(fs.readFileSync(sigAlgArtifacts_register.vkey) as unknown as string);
|
||||
const verified = await groth16.verify(
|
||||
vKey,
|
||||
publicSignals,
|
||||
@@ -292,45 +309,47 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
});
|
||||
|
||||
for (const sigAlgName of sigAlgNames) {
|
||||
const sigAlgArtifacts = register_circuits[sigAlgName];
|
||||
const sigAlgArtifacts_register = register_circuits[sigAlgName];
|
||||
const sigAlgArtifacts_dsc = dsc_circuits[sigAlgName];
|
||||
const sigAlgIndex = SignatureAlgorithm[sigAlgName as keyof typeof SignatureAlgorithm]
|
||||
|
||||
it(`Verifier contract verifies a correct proof - Register - ${sigAlgName}`, async function () {
|
||||
expect(
|
||||
await sigAlgArtifacts.verifier.verifyProof(
|
||||
sigAlgArtifacts.parsedCallData[0],
|
||||
sigAlgArtifacts.parsedCallData[1],
|
||||
sigAlgArtifacts.parsedCallData[2],
|
||||
sigAlgArtifacts.parsedCallData[3]
|
||||
await sigAlgArtifacts_register.verifier.verifyProof(
|
||||
sigAlgArtifacts_register.parsedCallData[0],
|
||||
sigAlgArtifacts_register.parsedCallData[1],
|
||||
sigAlgArtifacts_register.parsedCallData[2],
|
||||
sigAlgArtifacts_register.parsedCallData[3]
|
||||
)
|
||||
).to.be.true;
|
||||
});
|
||||
|
||||
it(`Verifier contract verifies a correct proof - DSC - ${sigAlgName}`, async function () {
|
||||
expect(
|
||||
await verifier_dsc.verifyProof(
|
||||
parsedCallData_csca[0],
|
||||
parsedCallData_csca[1],
|
||||
parsedCallData_csca[2],
|
||||
parsedCallData_csca[3]
|
||||
await sigAlgArtifacts_dsc.verifier.verifyProof(
|
||||
sigAlgArtifacts_dsc.parsedCallData[0],
|
||||
sigAlgArtifacts_dsc.parsedCallData[1],
|
||||
sigAlgArtifacts_dsc.parsedCallData[2],
|
||||
sigAlgArtifacts_dsc.parsedCallData[3]
|
||||
)
|
||||
).to.be.true;
|
||||
});
|
||||
|
||||
it(`Register with a wrong proof should fail - Register - ${sigAlgName}`, async function () {
|
||||
await expect(register
|
||||
.validateProof({ ...sigAlgArtifacts.formattedCallData, a: [0, 0] }, formattedCallData_csca, sigAlgIndex, sigAlgIndex))
|
||||
.to.be.revertedWith("Register__InvalidProof");
|
||||
.validateProof({ ...sigAlgArtifacts_register.formattedCallData, a: [0, 0] }, sigAlgArtifacts_dsc.formattedCallData, sigAlgIndex, sigAlgIndex))
|
||||
.to.be.revertedWith("Register__InvalidProofRegister");
|
||||
});
|
||||
|
||||
it(`Register with a wrong attestation id should fail - Register - ${sigAlgName}`, async function () {
|
||||
await expect(register
|
||||
.validateProof({ ...sigAlgArtifacts.formattedCallData, attestation_id: "10" }, formattedCallData_csca, sigAlgIndex, sigAlgIndex))
|
||||
.validateProof({ ...sigAlgArtifacts_register.formattedCallData, attestation_id: "10" }, sigAlgArtifacts_dsc.formattedCallData, sigAlgIndex, sigAlgIndex))
|
||||
.to.be.revertedWith("Register__InvalidAttestationId")
|
||||
});
|
||||
|
||||
it(`Register with a wrong signature algorithm should fail - Register - ${sigAlgName}`, async function () {
|
||||
await expect(register
|
||||
.validateProof({ ...sigAlgArtifacts.formattedCallData }, formattedCallData_csca, sigAlgIndex + 1, sigAlgIndex))
|
||||
.validateProof({ ...sigAlgArtifacts_register.formattedCallData }, sigAlgArtifacts_dsc.formattedCallData, sigAlgIndex + 1, sigAlgIndex))
|
||||
.to.be.revertedWith("Register__InvalidSignatureAlgorithm()")
|
||||
.catch(error => {
|
||||
assert(error.message.includes("Register__InvalidSignatureAlgorithm()"), "Expected revert with Register__InvalidSignatureAlgorithm(), but got another error");
|
||||
@@ -339,14 +358,14 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
it(`Register with a wrong merkle root should fail - Register - ${sigAlgName}`, async function () {
|
||||
await expect(register
|
||||
.validateProof(sigAlgArtifacts.formattedCallData, { ...formattedCallData_csca, merkle_root: 0 }, sigAlgIndex, sigAlgIndex))
|
||||
.validateProof(sigAlgArtifacts_register.formattedCallData, { ...sigAlgArtifacts_dsc.formattedCallData, merkle_root: 0 }, sigAlgIndex, sigAlgIndex))
|
||||
.to.be.revertedWith("Register__InvalidMerkleRoot")
|
||||
});
|
||||
|
||||
it(`Register should succeed - Register - ${sigAlgName}`, async function () {
|
||||
await expect(register
|
||||
.validateProof(sigAlgArtifacts.formattedCallData, formattedCallData_csca, sigAlgIndex, sigAlgIndex)).not.to.be.reverted;
|
||||
imt.insert(BigInt(sigAlgArtifacts.formattedCallData.commitment));
|
||||
.validateProof(sigAlgArtifacts_register.formattedCallData, sigAlgArtifacts_dsc.formattedCallData, sigAlgIndex, sigAlgIndex)).not.to.be.reverted;
|
||||
imt.insert(BigInt(sigAlgArtifacts_register.formattedCallData.commitment));
|
||||
/// check if the merkle root is equal to the one from the imt
|
||||
// console.log('\x1b[34m%s\x1b[0m', `IMT Merkle root of TS Object - TS: ${imt.root}`);
|
||||
// console.log('\x1b[34m%s\x1b[0m', `Merkle root of contract - TSx: ${await register.getMerkleRoot()}`);
|
||||
@@ -357,7 +376,7 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
// it(`Register with the same proof should fail - Register - ${sigAlgName}`, async function () {
|
||||
// await expect(register
|
||||
// .validateProof(sigAlgArtifacts.formattedCallData, sigAlgIndex))
|
||||
// .validateProof(sigAlgArtifacts_register.formattedCallData, sigAlgIndex))
|
||||
// .to.be.revertedWith("Register__YouAreUsingTheSameNullifierTwice()")
|
||||
// .catch(error => {
|
||||
// assert(error.message.includes("Register__YouAreUsingTheSameNullifierTwice()"), "Expected revert with Register__YouAreUsingTheSameNullifierTwice(), but got another error");
|
||||
@@ -368,99 +387,99 @@ describe("Proof of Passport - Contracts - Register & Disclose flow", function ()
|
||||
|
||||
/*** Disclose flow ***/
|
||||
|
||||
describe("Proof of Passport - Disclose flow", function () {
|
||||
this.beforeAll(async function () {
|
||||
user_address = await thirdAccount.getAddress();
|
||||
// We only test with the sha256WithRSAEncryption_65537 commitment for now
|
||||
// describe("Proof of Passport - Disclose flow", function () {
|
||||
// this.beforeAll(async function () {
|
||||
// user_address = await thirdAccount.getAddress();
|
||||
// // We only test with the sha256WithRSAEncryption_65537 commitment for now
|
||||
|
||||
// refactor in generate inputs function
|
||||
bitmap = Array(90).fill("1");
|
||||
scope = BigInt(1).toString();
|
||||
// // refactor in generate inputs function
|
||||
// bitmap = Array(90).fill("1");
|
||||
// scope = BigInt(1).toString();
|
||||
|
||||
majority = ["1", "8"];
|
||||
input_disclose = generateCircuitInputsDisclose(
|
||||
register_circuits.sha256WithRSAEncryption_65537.inputs.secret,
|
||||
register_circuits.sha256WithRSAEncryption_65537.inputs.attestation_id,
|
||||
mockPassportData_sha256WithRSAEncryption_65537,
|
||||
imt as any,
|
||||
majority,
|
||||
bitmap,
|
||||
scope,
|
||||
BigInt(user_address.toString()).toString()
|
||||
);
|
||||
// Generate the proof
|
||||
console.log('\x1b[32m%s\x1b[0m', 'Generating proof - Disclose');
|
||||
try {
|
||||
proof_result_disclose = await groth16.fullProve(
|
||||
input_disclose,
|
||||
path_disclose_wasm,
|
||||
path_disclose_zkey
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error generating proof:", error);
|
||||
throw error;
|
||||
}
|
||||
proof_disclose = proof_result_disclose.proof;
|
||||
publicSignals_disclose = proof_result_disclose.publicSignals;
|
||||
// majority = ["1", "8"];
|
||||
// input_disclose = generateCircuitInputsDisclose(
|
||||
// register_circuits.sha256WithRSAEncryption_65537.inputs.secret,
|
||||
// register_circuits.sha256WithRSAEncryption_65537.inputs.attestation_id,
|
||||
// mockPassportData_sha256_rsa_65537,
|
||||
// imt as any,
|
||||
// majority,
|
||||
// bitmap,
|
||||
// scope,
|
||||
// BigInt(user_address.toString()).toString()
|
||||
// );
|
||||
// // Generate the proof
|
||||
// console.log('\x1b[32m%s\x1b[0m', 'Generating proof - Disclose');
|
||||
// try {
|
||||
// proof_result_disclose = await groth16.fullProve(
|
||||
// input_disclose,
|
||||
// path_disclose_wasm,
|
||||
// path_disclose_zkey
|
||||
// );
|
||||
// } catch (error) {
|
||||
// console.error("Error generating proof:", error);
|
||||
// throw error;
|
||||
// }
|
||||
// proof_disclose = proof_result_disclose.proof;
|
||||
// publicSignals_disclose = proof_result_disclose.publicSignals;
|
||||
|
||||
console.log('\x1b[32m%s\x1b[0m', 'Proof generated - Disclose');
|
||||
// Verify the proof
|
||||
vkey_disclose = JSON.parse(fs.readFileSync(path_disclose_vkey) as unknown as string);
|
||||
verified_disclose = await groth16.verify(
|
||||
vkey_disclose,
|
||||
publicSignals_disclose,
|
||||
proof_disclose
|
||||
)
|
||||
console.log('\x1b[32m%s\x1b[0m', 'Proof verified - Disclose');
|
||||
rawCallData_disclose = await groth16.exportSolidityCallData(proof_disclose, publicSignals_disclose);
|
||||
parsedCallData_disclose = JSON.parse(`[${rawCallData_disclose}]`);
|
||||
formattedCallData_disclose = formatCallData_disclose(parsedCallData_disclose);
|
||||
console.log('formattedCallData_disclose', formattedCallData_disclose);
|
||||
// console.log('\x1b[32m%s\x1b[0m', 'Proof generated - Disclose');
|
||||
// // Verify the proof
|
||||
// vkey_disclose = JSON.parse(fs.readFileSync(path_disclose_vkey) as unknown as string);
|
||||
// verified_disclose = await groth16.verify(
|
||||
// vkey_disclose,
|
||||
// publicSignals_disclose,
|
||||
// proof_disclose
|
||||
// )
|
||||
// console.log('\x1b[32m%s\x1b[0m', 'Proof verified - Disclose');
|
||||
// rawCallData_disclose = await groth16.exportSolidityCallData(proof_disclose, publicSignals_disclose);
|
||||
// parsedCallData_disclose = JSON.parse(`[${rawCallData_disclose}]`);
|
||||
// formattedCallData_disclose = formatCallData_disclose(parsedCallData_disclose);
|
||||
// // console.log('formattedCallData_disclose', formattedCallData_disclose);
|
||||
|
||||
})
|
||||
// })
|
||||
|
||||
it("SBT mint should succeed - SBT", async function () {
|
||||
await expect(sbt.mint(formattedCallData_disclose))
|
||||
.to.not.be.reverted;
|
||||
});
|
||||
// it("SBT mint should succeed - SBT", async function () {
|
||||
// await expect(sbt.mint(formattedCallData_disclose))
|
||||
// .to.not.be.reverted;
|
||||
// });
|
||||
|
||||
|
||||
// // refactor in generate inputs function
|
||||
// bitmap = Array(90).fill("1");
|
||||
// scope = BigInt(1).toString();
|
||||
// user_address = await thirdAccount.getAddress();
|
||||
// majority = ["1", "8"];
|
||||
// input_disclose = generateCircuitInputsDisclose(
|
||||
// inputs.secret,
|
||||
// inputs.attestation_id,
|
||||
// passportData,
|
||||
// imt as any,
|
||||
// majority,
|
||||
// bitmap,
|
||||
// scope,
|
||||
// BigInt(user_address.toString()).toString()
|
||||
// );
|
||||
// // Generate the proof
|
||||
// console.log('\x1b[32m%s\x1b[0m', 'Generating proof - Disclose');
|
||||
// try {
|
||||
// proof_result_disclose = await groth16.fullProve(
|
||||
// input_disclose,
|
||||
// path_disclose_wasm,
|
||||
// path_disclose_zkey
|
||||
// );
|
||||
// } catch (error) {
|
||||
// console.error("Error generating proof:", error);
|
||||
// throw error;
|
||||
// }
|
||||
// proof_disclose = proof_result_disclose.proof;
|
||||
// publicSignals_disclose = proof_result_disclose.publicSignals;
|
||||
// // // refactor in generate inputs function
|
||||
// // bitmap = Array(90).fill("1");
|
||||
// // scope = BigInt(1).toString();
|
||||
// // user_address = await thirdAccount.getAddress();
|
||||
// // majority = ["1", "8"];
|
||||
// // input_disclose = generateCircuitInputsDisclose(
|
||||
// // inputs.secret,
|
||||
// // inputs.attestation_id,
|
||||
// // passportData,
|
||||
// // imt as any,
|
||||
// // majority,
|
||||
// // bitmap,
|
||||
// // scope,
|
||||
// // BigInt(user_address.toString()).toString()
|
||||
// // );
|
||||
// // // Generate the proof
|
||||
// // console.log('\x1b[32m%s\x1b[0m', 'Generating proof - Disclose');
|
||||
// // try {
|
||||
// // proof_result_disclose = await groth16.fullProve(
|
||||
// // input_disclose,
|
||||
// // path_disclose_wasm,
|
||||
// // path_disclose_zkey
|
||||
// // );
|
||||
// // } catch (error) {
|
||||
// // console.error("Error generating proof:", error);
|
||||
// // throw error;
|
||||
// // }
|
||||
// // proof_disclose = proof_result_disclose.proof;
|
||||
// // publicSignals_disclose = proof_result_disclose.publicSignals;
|
||||
|
||||
|
||||
// assert(verified_disclose == true, 'Should verify')
|
||||
// // assert(verified_disclose == true, 'Should verify')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
// });
|
||||
})
|
||||
|
||||
@@ -544,53 +544,53 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@nomicfoundation/edr-darwin-arm64@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz#bbb43f0e01f40839b0bd38c2c443cb6910ae955f"
|
||||
integrity sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg==
|
||||
"@nomicfoundation/edr-darwin-arm64@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.2.tgz#2ff98535f272c9f2a7d06eeda93fe7b207a348a4"
|
||||
integrity sha512-S+hhepupfqpBvMa9M1PVS08sVjGXsLnjyAsjhrrsjsNuTHVLhKzhkguvBD5g4If5skrwgOaVqpag4wnQbd15kQ==
|
||||
|
||||
"@nomicfoundation/edr-darwin-x64@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz#b1ffcd9142418fd8498de34a7336b3f977907c86"
|
||||
integrity sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg==
|
||||
"@nomicfoundation/edr-darwin-x64@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.2.tgz#001dcd0e7fa4c52046d283b0dc61e63a60c614dd"
|
||||
integrity sha512-/zM94AUrXz6CmcsecRNHJ50jABDUFafmGc4iBmkfX/mTp4tVZj7XTyIogrQIt0FnTaeb4CgZoLap2+8tW/Uldg==
|
||||
|
||||
"@nomicfoundation/edr-linux-arm64-gnu@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz#8173d16d4f6f2b3e82ba7096d2a1ea3619d8bfa7"
|
||||
integrity sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ==
|
||||
"@nomicfoundation/edr-linux-arm64-gnu@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.2.tgz#6d19f8265c8ffb22e29bc5bbbb5d1913fe4b306b"
|
||||
integrity sha512-TV3Pr2tFvvmCfPCi9PaCGLtqn+oLaPKfL2NWpnoCeFFdzDQXi2L930yP1oUPY5RXd78NLdVHMkEkbhb2b6Wuvg==
|
||||
|
||||
"@nomicfoundation/edr-linux-arm64-musl@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz#b1ce293a7c3e0d9f70391e1aef1a82b83b997567"
|
||||
integrity sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg==
|
||||
"@nomicfoundation/edr-linux-arm64-musl@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.2.tgz#0b01aa405fdc8048c7a8e95c737f29b437536a30"
|
||||
integrity sha512-PALwrLBk1M9rolXyhSX8xdhe5jL0qf/PgiCIF7W7lUyVKrI/I0oiU0EHDk/Xw7yi2UJg4WRyhhZoHYa0g4g8Qg==
|
||||
|
||||
"@nomicfoundation/edr-linux-x64-gnu@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz#4c12c4e4bfd3d837f5663ad7cbf7cb6d5634ef83"
|
||||
integrity sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA==
|
||||
"@nomicfoundation/edr-linux-x64-gnu@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.2.tgz#10959fd4db9b333d3e0559cb893e109611889af0"
|
||||
integrity sha512-5svkftypDjAZ1LxV1onojlaqPRxrTEjJLkrUwLL+Fao5ZMe7aTnk5QQ1Jv76gW6WYZnMXNgjPhRcnw3oSNrqFA==
|
||||
|
||||
"@nomicfoundation/edr-linux-x64-musl@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz#8842004aa1a47c504f10863687da28b65dca7baa"
|
||||
integrity sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw==
|
||||
"@nomicfoundation/edr-linux-x64-musl@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.2.tgz#8de64a2dfd869dad930dd0eb9572a0593d382379"
|
||||
integrity sha512-qiMlXQTggdH9zfOB4Eil4rQ95z8s7QdLJcOfz5Aym12qJNkCyF9hi4cc4dDCWA0CdI3x3oLbuf8qb81SF8R45w==
|
||||
|
||||
"@nomicfoundation/edr-win32-x64-msvc@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz#29d8bbb2edf9912a95f5453855cf17cdcb269957"
|
||||
integrity sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A==
|
||||
"@nomicfoundation/edr-win32-x64-msvc@0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.2.tgz#13ad4bab9fd68853930e1a3d87c78d69d1d0e2ef"
|
||||
integrity sha512-hDkAb0iaMmGYwBY/rA1oCX8VpsezfQcHPEPIEGXEcWC3WbnOgIZo0Qkpu/g0OMtFOJSQlWLXvKZuV7blhnrQag==
|
||||
|
||||
"@nomicfoundation/edr@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.4.0.tgz#4895ecb6ef321136db837458949c37cce4a29459"
|
||||
integrity sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw==
|
||||
"@nomicfoundation/edr@^0.4.1":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.4.2.tgz#9d7550182d4f75d7510e265ebd3474c4f6fcb62a"
|
||||
integrity sha512-U7v0HuZHfrsl/5FpUzuB2FYA0+FUglHHwiO6NhvLtNYKMZcPzdS6iUriMp/7GWs0SVxW3bAht9GinZPxdhVwWg==
|
||||
dependencies:
|
||||
"@nomicfoundation/edr-darwin-arm64" "0.4.0"
|
||||
"@nomicfoundation/edr-darwin-x64" "0.4.0"
|
||||
"@nomicfoundation/edr-linux-arm64-gnu" "0.4.0"
|
||||
"@nomicfoundation/edr-linux-arm64-musl" "0.4.0"
|
||||
"@nomicfoundation/edr-linux-x64-gnu" "0.4.0"
|
||||
"@nomicfoundation/edr-linux-x64-musl" "0.4.0"
|
||||
"@nomicfoundation/edr-win32-x64-msvc" "0.4.0"
|
||||
"@nomicfoundation/edr-darwin-arm64" "0.4.2"
|
||||
"@nomicfoundation/edr-darwin-x64" "0.4.2"
|
||||
"@nomicfoundation/edr-linux-arm64-gnu" "0.4.2"
|
||||
"@nomicfoundation/edr-linux-arm64-musl" "0.4.2"
|
||||
"@nomicfoundation/edr-linux-x64-gnu" "0.4.2"
|
||||
"@nomicfoundation/edr-linux-x64-musl" "0.4.2"
|
||||
"@nomicfoundation/edr-win32-x64-msvc" "0.4.2"
|
||||
|
||||
"@nomicfoundation/ethereumjs-common@4.0.4":
|
||||
version "4.0.4"
|
||||
@@ -1754,10 +1754,10 @@ command-line-usage@^6.1.0:
|
||||
table-layout "^1.0.2"
|
||||
typical "^5.2.0"
|
||||
|
||||
commander@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
|
||||
integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
|
||||
commander@^8.1.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
@@ -2356,17 +2356,6 @@ fp-ts@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a"
|
||||
integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A==
|
||||
|
||||
fs-extra@^0.30.0:
|
||||
version "0.30.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
|
||||
integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^2.1.0"
|
||||
klaw "^1.0.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@^10.0.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
|
||||
@@ -2560,7 +2549,7 @@ gopd@^1.0.1:
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.3"
|
||||
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.9:
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9:
|
||||
version "4.2.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
|
||||
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
|
||||
@@ -2595,14 +2584,14 @@ hardhat-gas-reporter@^1.0.10:
|
||||
eth-gas-reporter "^0.2.25"
|
||||
sha1 "^1.1.1"
|
||||
|
||||
hardhat@^2.22.3:
|
||||
version "2.22.5"
|
||||
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.5.tgz#7e1a4311fa9e34a1cfe337784eae06706f6469a5"
|
||||
integrity sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw==
|
||||
hardhat@^2.22.6:
|
||||
version "2.22.6"
|
||||
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.6.tgz#d73caece246cd8219a1815554dabc31d400fa035"
|
||||
integrity sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==
|
||||
dependencies:
|
||||
"@ethersproject/abi" "^5.1.2"
|
||||
"@metamask/eth-sig-util" "^4.0.0"
|
||||
"@nomicfoundation/edr" "^0.4.0"
|
||||
"@nomicfoundation/edr" "^0.4.1"
|
||||
"@nomicfoundation/ethereumjs-common" "4.0.4"
|
||||
"@nomicfoundation/ethereumjs-tx" "5.0.4"
|
||||
"@nomicfoundation/ethereumjs-util" "9.0.4"
|
||||
@@ -2636,7 +2625,7 @@ hardhat@^2.22.3:
|
||||
raw-body "^2.4.1"
|
||||
resolve "1.17.0"
|
||||
semver "^6.3.0"
|
||||
solc "0.7.3"
|
||||
solc "0.8.26"
|
||||
source-map-support "^0.5.13"
|
||||
stacktrace-parser "^0.1.10"
|
||||
tsort "0.0.1"
|
||||
@@ -2985,13 +2974,6 @@ json-stringify-safe@^5.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
|
||||
|
||||
jsonfile@^2.1.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
|
||||
integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
@@ -3036,13 +3018,6 @@ kind-of@^6.0.2:
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
|
||||
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
|
||||
|
||||
klaw@^1.0.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
|
||||
integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.9"
|
||||
|
||||
kleur@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||
@@ -3661,7 +3636,7 @@ require-directory@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
||||
|
||||
require-from-string@^2.0.0, require-from-string@^2.0.2:
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
@@ -3697,13 +3672,6 @@ reusify@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rimraf@^2.2.8:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
|
||||
@@ -3889,18 +3857,16 @@ snarkjs@^0.7.1:
|
||||
logplease "^1.2.15"
|
||||
r1csfile "0.0.48"
|
||||
|
||||
solc@0.7.3:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a"
|
||||
integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==
|
||||
solc@0.8.26:
|
||||
version "0.8.26"
|
||||
resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.26.tgz#afc78078953f6ab3e727c338a2fefcd80dd5b01a"
|
||||
integrity sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==
|
||||
dependencies:
|
||||
command-exists "^1.2.8"
|
||||
commander "3.0.2"
|
||||
commander "^8.1.0"
|
||||
follow-redirects "^1.12.1"
|
||||
fs-extra "^0.30.0"
|
||||
js-sha3 "0.8.0"
|
||||
memorystream "^0.3.1"
|
||||
require-from-string "^2.0.0"
|
||||
semver "^5.5.0"
|
||||
tmp "0.0.33"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('MODAL PROVER', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
describe("SHA256 RSA", async () => {
|
||||
it("verify proof", async () => {
|
||||
const circuitInputs = getCSCAInputs(
|
||||
const inputs = getCSCAInputs(
|
||||
BigInt(0).toString(),
|
||||
dscCert_sha256_rsa,
|
||||
cscaCert_sha256_rsa,
|
||||
@@ -36,10 +36,6 @@ describe('MODAL PROVER', function () {
|
||||
max_cert_bytes,
|
||||
true
|
||||
);
|
||||
const inputs = {
|
||||
"signature_algorithm": "sha256_rsa",
|
||||
"inputs": circuitInputs
|
||||
}
|
||||
//console.log(JSON.stringify(inputs));
|
||||
console.log('\x1b[34msending request to modal server\x1b[0m');
|
||||
const response = await sendCSCARequest(inputs);
|
||||
@@ -57,7 +53,7 @@ describe('MODAL PROVER', function () {
|
||||
|
||||
describe("SHA1 RSA", async () => {
|
||||
it("verify proof", async () => {
|
||||
const circuitInputs = getCSCAInputs(
|
||||
const inputs = getCSCAInputs(
|
||||
BigInt(0).toString(),
|
||||
dscCert_sha1_rsa,
|
||||
cscaCert_sha1_rsa,
|
||||
@@ -68,10 +64,6 @@ describe('MODAL PROVER', function () {
|
||||
max_cert_bytes,
|
||||
true
|
||||
);
|
||||
const inputs = {
|
||||
"signature_algorithm": "sha1_rsa",
|
||||
"inputs": circuitInputs
|
||||
}
|
||||
console.log(JSON.stringify(inputs));
|
||||
|
||||
console.log('\x1b[34msending request to modal server\x1b[0m');
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
TEST_ADDRESS = "0x000000000000000000000000000000000000000"
|
||||
TOKEN_ID = "0"
|
||||
MOCK_MERKLE_ROOT_CHECK = "false"
|
||||
3
sdk/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
node_modules/
|
||||
yarn.lock
|
||||
yarn-error.log
|
||||
yarn-error.log
|
||||
dist
|
||||
2
sdk/ProofOfPassportQRCode.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { QRCodeGenerator } from "./QRCodeGenerator";
|
||||
|
||||
79
sdk/ProofOfPassportRegister.ts
Normal file
@@ -1,18 +1,18 @@
|
||||
export class ProofOfPassportVerifierReport {
|
||||
scope: boolean = false;
|
||||
merkle_root: boolean = false;
|
||||
attestation_id: boolean = false;
|
||||
current_date: boolean = false;
|
||||
issuing_state: boolean = false;
|
||||
name: boolean = false;
|
||||
passport_number: boolean = false;
|
||||
nationality: boolean = false;
|
||||
date_of_birth: boolean = false;
|
||||
gender: boolean = false;
|
||||
expiry_date: boolean = false;
|
||||
older_than: boolean = false;
|
||||
owner_of: boolean = false;
|
||||
proof: boolean = false;
|
||||
scope: boolean = true;
|
||||
merkle_root: boolean = true;
|
||||
attestation_id: boolean = true;
|
||||
current_date: boolean = true;
|
||||
issuing_state: boolean = true;
|
||||
name: boolean = true;
|
||||
passport_number: boolean = true;
|
||||
nationality: boolean = true;
|
||||
date_of_birth: boolean = true;
|
||||
gender: boolean = true;
|
||||
expiry_date: boolean = true;
|
||||
older_than: boolean = true;
|
||||
owner_of: boolean = true;
|
||||
proof: boolean = true;
|
||||
|
||||
valid: boolean = true;
|
||||
|
||||
@@ -21,8 +21,9 @@ export class ProofOfPassportVerifierReport {
|
||||
|
||||
constructor() { }
|
||||
|
||||
exposeAttribute(attribute: keyof ProofOfPassportVerifierReport) {
|
||||
(this[attribute] as boolean) = true;
|
||||
exposeAttribute(attribute: keyof ProofOfPassportVerifierReport, value: any = "", expectedValue: any = "") {
|
||||
console.log('exposeAttribute', attribute, "value:", value, "expectedValue:", expectedValue);
|
||||
(this[attribute] as boolean) = false;
|
||||
this.valid = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import { groth16 } from 'snarkjs';
|
||||
import fs from 'fs';
|
||||
import { attributeToPosition, countryCodes, DEFAULT_RPC_URL, PASSPORT_ATTESTATION_ID } from '../common/src/constants/constants';
|
||||
import { attributeToPosition, countryCodes, DEFAULT_RPC_URL, PASSPORT_ATTESTATION_ID } from './common/src/constants/constants';
|
||||
import { checkMerkleRoot, getCurrentDateFormatted, parsePublicSignals, unpackReveal } from './utils';
|
||||
import dotenv from 'dotenv';
|
||||
import { ProofOfPassportVerifierReport } from './ProofOfPassportVerifierReport';
|
||||
import { vkey_disclose } from './common/src/constants/vkey';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const path_disclose_vkey = "../circuits/build/disclose_vkey.json";
|
||||
const MOCK_MERKLE_ROOT_CHECK = process.env.MOCK_MERKLE_ROOT_CHECK === 'true' ? true : false;
|
||||
const MOCK_MERKLE_ROOT_CHECK = false;
|
||||
|
||||
export class ProofOfPassportWeb2Verifier {
|
||||
scope: string;
|
||||
attestationId: string;
|
||||
requirements: Array<[string, number | string]>;
|
||||
requirements: string[][];
|
||||
rpcUrl: string;
|
||||
report: ProofOfPassportVerifierReport;
|
||||
|
||||
constructor(options: { scope: string, attestationId?: string, requirements?: Array<[string, number | string]>, rpcUrl?: string }) {
|
||||
constructor(options: { scope: string, attestationId?: string, requirements?: string[][], rpcUrl?: string }) {
|
||||
this.scope = options.scope;
|
||||
this.attestationId = options.attestationId || PASSPORT_ATTESTATION_ID;
|
||||
this.requirements = options.requirements || [];
|
||||
@@ -29,7 +25,7 @@ export class ProofOfPassportWeb2Verifier {
|
||||
const parsedPublicSignals = parsePublicSignals(proofOfPassportWeb2Inputs.publicSignals);
|
||||
//1. Verify the scope
|
||||
if (parsedPublicSignals.scope !== this.scope) {
|
||||
this.report.exposeAttribute('scope');
|
||||
this.report.exposeAttribute('scope', parsedPublicSignals.scope, this.scope);
|
||||
}
|
||||
console.log('\x1b[32m%s\x1b[0m', `- scope verified`);
|
||||
|
||||
@@ -42,13 +38,13 @@ export class ProofOfPassportWeb2Verifier {
|
||||
|
||||
//3. Verify the attestation_id
|
||||
if (parsedPublicSignals.attestation_id !== this.attestationId) {
|
||||
this.report.exposeAttribute('attestation_id');
|
||||
this.report.exposeAttribute('attestation_id', parsedPublicSignals.attestation_id, this.attestationId);
|
||||
}
|
||||
console.log('\x1b[32m%s\x1b[0m', `- attestation_id verified`);
|
||||
|
||||
//4. Verify the current_date
|
||||
if (parsedPublicSignals.current_date.toString() !== getCurrentDateFormatted().toString()) {
|
||||
this.report.exposeAttribute('current_date');
|
||||
this.report.exposeAttribute('current_date', parsedPublicSignals.current_date, getCurrentDateFormatted());
|
||||
}
|
||||
console.log('\x1b[32m%s\x1b[0m', `- current_date verified`);
|
||||
|
||||
@@ -77,11 +73,14 @@ export class ProofOfPassportWeb2Verifier {
|
||||
}
|
||||
|
||||
//6. Verify the proof
|
||||
const vkey_disclose = JSON.parse(fs.readFileSync(path_disclose_vkey) as unknown as string);
|
||||
|
||||
console.log(vkey_disclose);
|
||||
console.log("publicSignals", proofOfPassportWeb2Inputs.publicSignals);
|
||||
console.log("proof", proofOfPassportWeb2Inputs.proof);
|
||||
const verified_disclose = await groth16.verify(
|
||||
vkey_disclose,
|
||||
proofOfPassportWeb2Inputs.publicSignals,
|
||||
proofOfPassportWeb2Inputs.proof
|
||||
proofOfPassportWeb2Inputs.proof as any
|
||||
)
|
||||
if (!verified_disclose) {
|
||||
this.report.exposeAttribute('proof');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DEFAULT_RPC_URL, PASSPORT_ATTESTATION_ID, SBT_ABI, SBT_CONTRACT_ADDRESS } from '../common/src/constants/constants';
|
||||
import { DEFAULT_RPC_URL, PASSPORT_ATTESTATION_ID, SBT_ABI, SBT_CONTRACT_ADDRESS } from './common/src/constants/constants';
|
||||
import { ethers } from 'ethers';
|
||||
import { attributeToGetter } from './utils';
|
||||
import { ProofOfPassportVerifierReport } from "./ProofOfPassportVerifierReport";
|
||||
import { ProofOfPassportVerifierReport } from './ProofOfPassportVerifierReport';
|
||||
|
||||
export class ProofOfPassportWeb3Verifier {
|
||||
scope: string;
|
||||
|
||||
21
sdk/QRCodeGenerator.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import QRCode from 'easyqrcodejs';
|
||||
import { AppType } from "../common/src/utils/appType";
|
||||
|
||||
export class QRCodeGenerator {
|
||||
static async generateQRCode(appData: AppType, size: number = 256): Promise<HTMLElement> {
|
||||
const qrData = this.serializeAppType(appData);
|
||||
const options = {
|
||||
text: qrData,
|
||||
width: size,
|
||||
height: size,
|
||||
};
|
||||
const element = document.createElement('div');
|
||||
new QRCode(element, options);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
private static serializeAppType(appType: AppType): string {
|
||||
return JSON.stringify(appType);
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
# SDK
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @proofofpassport/sdk
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
yarn install-sdk
|
||||
```
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
yarn test
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
### Web2 applications
|
||||
|
||||
To use the `ProofOfPassportWeb2Verifier` in Web2 applications, import and initialize it as follows:
|
||||
|
||||
|
||||
```typescript
|
||||
import { ProofOfPassportWeb2Verifier } from '@proofofpassport/sdk';
|
||||
const verifier = new ProofOfPassportWeb2Verifier({
|
||||
scope: "yourScope",
|
||||
requirements: [["older_than", "18"], ["nationality", "France"]]
|
||||
});
|
||||
```
|
||||
|
||||
#### parameters for `ProofOfPassportWeb2Verifier`
|
||||
|
||||
| Parameter | Optional | Description |
|
||||
|---------------|----------|-------------|
|
||||
| `scope` | No | The scope of your application, is unique for each application. |
|
||||
| `attestationId` | Yes | The ID of the attestation, defaults to `PASSPORT_ATTESTATION_ID`. |
|
||||
| `requirements` | Yes | An array of requirements, each an array with an attribute and its expected value. |
|
||||
| `rpcUrl` | Yes | The RPC URL to connect to the blockchain, defaults to `DEFAULT_RPC_URL`. |
|
||||
|
||||
Finally, verify the proof:
|
||||
The function fired from the Proof of Passport app will send a `ProofOfPassportWeb2Inputs` object.
|
||||
|
||||
```typescript
|
||||
|
||||
const result = await verifier.verify(proofOfPassportWeb2Inputs); // proofOfPassportWeb2Inputs : ProofOfPassportWeb2Inputs
|
||||
```
|
||||
|
||||
### Web3 application
|
||||
For Web3 applications, use the `ProofOfPassportWeb3Verifier` as follows:
|
||||
|
||||
```typescript
|
||||
import { ProofOfPassportWeb3Verifier } from '@proofofpassport/sdk';
|
||||
const verifier = new ProofOfPassportWeb3Verifier({
|
||||
scope: "yourScope",
|
||||
rpcUrl: "https://custom.rpc.url"
|
||||
});
|
||||
```
|
||||
#### Parameters for `ProofOfPassportWeb3Verifier`
|
||||
|
||||
| Parameter | Optional | Description |
|
||||
|---------------|----------|-------------|
|
||||
| `scope` | No | The scope of the verification. |
|
||||
| `attestationId` | Yes | The ID of the attestation, defaults to `PASSPORT_ATTESTATION_ID`. |
|
||||
| `requirements` | Yes | An array of requirements, each an array with an attribute and its expected value. |
|
||||
| `rpcUrl` | Yes | The RPC URL to connect to the blockchain, defaults to `DEFAULT_RPC_URL`. |
|
||||
|
||||
#### Verify the user owns a sbt which satisfies the requirements:
|
||||
|
||||
```typescript
|
||||
const result = await verifier.verify(address, tokenId);
|
||||
```
|
||||
|
||||
### Handle the report
|
||||
|
||||
Each verification will returns a ProofOfPassportReport object which contains all the informations about the verification of each requirement.
|
||||
|
||||
If a requirement is not satisfied, the corresponding field will be set to `true`.
|
||||
The `valid` field will be `false` if there is at least one requirement that is not satisfied.
|
||||
|
||||
`nullifier` and `user_identifier` are also accessible as report fields.
|
||||
|
||||
```typescript
|
||||
const report = await verifier.verify(publicSignals, proof);
|
||||
const nullifier = report.nullifier;
|
||||
const userIdentifier = report.user_identifier;
|
||||
```
|
||||
|
||||
|
||||
48
sdk/WebSocket.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import io, { Socket } from 'socket.io-client';
|
||||
|
||||
export class ProofWebSocket {
|
||||
private socket: Socket;
|
||||
private callbacks: { [key: string]: (data: any) => void } = {};
|
||||
|
||||
constructor(url: string) {
|
||||
this.socket = io(url);
|
||||
this.setupListeners();
|
||||
}
|
||||
|
||||
private setupListeners() {
|
||||
this.socket.on('proof_generation_started', (data) => this.triggerCallback('proofGenerationStarted', data));
|
||||
this.socket.on('proof_generation_progress', (data) => this.triggerCallback('proofGenerationProgress', data));
|
||||
this.socket.on('proof_submitted', (data) => this.triggerCallback('proofSubmitted', data));
|
||||
this.socket.on('proof_verified', (data) => this.triggerCallback('proofVerified', data));
|
||||
}
|
||||
|
||||
private triggerCallback(event: string, data: any) {
|
||||
if (this.callbacks[event]) {
|
||||
this.callbacks[event](data);
|
||||
}
|
||||
}
|
||||
|
||||
on(event: string, callback: (data: any) => void) {
|
||||
this.callbacks[event] = callback;
|
||||
}
|
||||
|
||||
emitProofGenerationStarted(userId: string) {
|
||||
this.socket.emit('proof_generation_started', { userId });
|
||||
}
|
||||
|
||||
emitProofGenerationProgress(userId: string, progress: number) {
|
||||
this.socket.emit('proof_generation_progress', { userId, progress });
|
||||
}
|
||||
|
||||
emitProofSubmitted(userId: string, proofId: string) {
|
||||
this.socket.emit('proof_submitted', { userId, proofId });
|
||||
}
|
||||
|
||||
emitProofVerified(userId: string, proofId: string, isValid: boolean) {
|
||||
this.socket.emit('proof_verified', { userId, proofId, isValid });
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.socket.disconnect();
|
||||
}
|
||||
}
|
||||
368
sdk/certificates.ts
Normal file
@@ -0,0 +1,368 @@
|
||||
export const pem1 = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
j/sfUhyHHc9GFJPteLrV
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
export const pem2 = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
24YnLM+7w0NVPvwClrpt
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
export const pem3 = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
export const pem4 = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const mock_csca = `-----BEGIN CERTIFICATE-----
|
||||
MIIFpzCCA4+gAwIBAgIUVGoAk38qsh7YYIE2eANMIeZkr+IwDQYJKoZIhvcNAQEL
|
||||
BQAwYzELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCU1vY2tTdGF0ZTERMA8GA1UEBwwI
|
||||
TW9ja0NpdHkxGTAXBgNVBAoMEE1vY2tPcmdhbml6YXRpb24xEjAQBgNVBAMMCW1v
|
||||
Y2tfY3NjYTAeFw0yNDA2MTgxOTA4MzJaFw0yNTA2MTgxOTA4MzJaMGMxCzAJBgNV
|
||||
BAYTAlhYMRIwEAYDVQQIDAlNb2NrU3RhdGUxETAPBgNVBAcMCE1vY2tDaXR5MRkw
|
||||
FwYDVQQKDBBNb2NrT3JnYW5pemF0aW9uMRIwEAYDVQQDDAltb2NrX2NzY2EwggIi
|
||||
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDE0JWh/kOzueMgFHwqLHYabpx4
|
||||
T0OV58DPuJObuMIKugw8/5l1VLg/Zq2II8/FoATn0Is3JYOidHnFskgkKjW89gxv
|
||||
RYRlYFPcvRfAxy+3+AO2f3xCnavkNTUI3Jl9q3jBz05SqHgM1cHiYr61ZX5sA980
|
||||
OveugRWBbT1mEUNhXTnegfPI9K3b+6YL0QXUePXGpRD9f5lTiCoE/mW8wGkieBYx
|
||||
QEEskwVpV3cvqwoLCkbdZkRZmIsYE6u7HeAPw2p/yAK6DhqY/vH3svj3LpWvdzBi
|
||||
Av1wBuuZ6IDgoB0tbgCPOUuc+btezBKhmZXDau0UZc9Y3ND+bMCQEWieXSwCWFYg
|
||||
y41/onaCaLdT+kcvwdOENNVNvHpaYVDnZGWdt8A95w/dl4Dl19wcL3KkqxoFGB8e
|
||||
wG+/SDnYTuuGWY3zaROJQ3KYlCqNi3+OuzZTBiJTujaL3Eb/+7Smhy/qtdd6bVUg
|
||||
mpf3fdBHw+jjl2st+n1rfIYY8rYY7HGrJdome9jXS8pCNfnptp+J8urzgXfEXGFM
|
||||
qHwMKu/vtfiBt4a1+GC/i2ssaXRcGABiI4xG4BQYXT+4U3p0pAA7cDNH5jN0Wny7
|
||||
J5DuEyXzcrRQVFD9hiFmDJfAsc35UwHKpayu9F7JJC4EfWVdahgA9VLhxVIE+eTi
|
||||
HPRHFyMaVaeqmjrBLQIDAQABo1MwUTAdBgNVHQ4EFgQUVGhgTF0HCJvSxKtE0BvV
|
||||
tQNMt0cwHwYDVR0jBBgwFoAUVGhgTF0HCJvSxKtE0BvVtQNMt0cwDwYDVR0TAQH/
|
||||
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAtyt8sirr9jc8i5xEnpV3YM6m0poY
|
||||
bl2S5hDu+xmMRnl8r3lv3v1KE2XrZD0cldV8plYz6oXfWBkCj3j6RUbsNx8w1q27
|
||||
Qsb2NC1KZljYG+kHavIIdJty9FOknhgYSYW+UKixSHPuAS+iJxEmGBN8GxhMPpzM
|
||||
KRzWbpQuPZuBgyKRSeR5ytGqyZrEje9zhkdSg/aFYn3EzLw93CfzrDLrKmXc/dra
|
||||
vEDyP34ts0Cy7UadCGkJN/SPuZpvF9Fy5f7l8ymHE319ipNZHIMhw50h0l/Puzjd
|
||||
vn3iHWtwpFw5r+nJTr5zO+3yL4dPcp8XfX3Daa5nDfCJ7dd1wSOf+/1cvBLB5aKc
|
||||
kyZ/ppvTc3oJAmFHAD2NXf15CUWE18Te/Vy9X2qI8LkFtea6GDF4VBewT2PATg12
|
||||
r03xZWa6KFVbgTIq3GUvtZ8UHm+cluTFKX90rFtbzFo658mxQGw5RnE2zp340NzP
|
||||
v9tNSlP4Tyzr2b1VoQcgmpQ987afINJG39lq2OsSrlK87p9bB4yoFSZwOfqok0nM
|
||||
IICRxBuTUHLqP3Nhvo+tAl+iK848LDJVf87ZVQHl72JX4lkVvOo5LCXnOQPyowaP
|
||||
D++J2c6tUj6gs9HAKVX7fH06m/2T5fJHae/OYx36O242yBXPQdHx6qloF/DNvGyM
|
||||
EHC3NCCjLG5m6G0=
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const fr1pem = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
3sTE6mYNoV8bK4+Y
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const fr2pem = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
|
||||
export const fr3pem = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
iksuh3S4gaW0c9jK
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const fr4pem = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
export const mockpem = `-----BEGIN CERTIFICATE-----
|
||||
MIIFpzCCA4+gAwIBAgIUVGoAk38qsh7YYIE2eANMIeZkr+IwDQYJKoZIhvcNAQEL
|
||||
BQAwYzELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCU1vY2tTdGF0ZTERMA8GA1UEBwwI
|
||||
TW9ja0NpdHkxGTAXBgNVBAoMEE1vY2tPcmdhbml6YXRpb24xEjAQBgNVBAMMCW1v
|
||||
Y2tfY3NjYTAeFw0yNDA2MTgxOTA4MzJaFw0yNTA2MTgxOTA4MzJaMGMxCzAJBgNV
|
||||
BAYTAlhYMRIwEAYDVQQIDAlNb2NrU3RhdGUxETAPBgNVBAcMCE1vY2tDaXR5MRkw
|
||||
FwYDVQQKDBBNb2NrT3JnYW5pemF0aW9uMRIwEAYDVQQDDAltb2NrX2NzY2EwggIi
|
||||
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDE0JWh/kOzueMgFHwqLHYabpx4
|
||||
T0OV58DPuJObuMIKugw8/5l1VLg/Zq2II8/FoATn0Is3JYOidHnFskgkKjW89gxv
|
||||
RYRlYFPcvRfAxy+3+AO2f3xCnavkNTUI3Jl9q3jBz05SqHgM1cHiYr61ZX5sA980
|
||||
OveugRWBbT1mEUNhXTnegfPI9K3b+6YL0QXUePXGpRD9f5lTiCoE/mW8wGkieBYx
|
||||
QEEskwVpV3cvqwoLCkbdZkRZmIsYE6u7HeAPw2p/yAK6DhqY/vH3svj3LpWvdzBi
|
||||
Av1wBuuZ6IDgoB0tbgCPOUuc+btezBKhmZXDau0UZc9Y3ND+bMCQEWieXSwCWFYg
|
||||
y41/onaCaLdT+kcvwdOENNVNvHpaYVDnZGWdt8A95w/dl4Dl19wcL3KkqxoFGB8e
|
||||
wG+/SDnYTuuGWY3zaROJQ3KYlCqNi3+OuzZTBiJTujaL3Eb/+7Smhy/qtdd6bVUg
|
||||
mpf3fdBHw+jjl2st+n1rfIYY8rYY7HGrJdome9jXS8pCNfnptp+J8urzgXfEXGFM
|
||||
qHwMKu/vtfiBt4a1+GC/i2ssaXRcGABiI4xG4BQYXT+4U3p0pAA7cDNH5jN0Wny7
|
||||
J5DuEyXzcrRQVFD9hiFmDJfAsc35UwHKpayu9F7JJC4EfWVdahgA9VLhxVIE+eTi
|
||||
HPRHFyMaVaeqmjrBLQIDAQABo1MwUTAdBgNVHQ4EFgQUVGhgTF0HCJvSxKtE0BvV
|
||||
tQNMt0cwHwYDVR0jBBgwFoAUVGhgTF0HCJvSxKtE0BvVtQNMt0cwDwYDVR0TAQH/
|
||||
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAtyt8sirr9jc8i5xEnpV3YM6m0poY
|
||||
bl2S5hDu+xmMRnl8r3lv3v1KE2XrZD0cldV8plYz6oXfWBkCj3j6RUbsNx8w1q27
|
||||
Qsb2NC1KZljYG+kHavIIdJty9FOknhgYSYW+UKixSHPuAS+iJxEmGBN8GxhMPpzM
|
||||
KRzWbpQuPZuBgyKRSeR5ytGqyZrEje9zhkdSg/aFYn3EzLw93CfzrDLrKmXc/dra
|
||||
vEDyP34ts0Cy7UadCGkJN/SPuZpvF9Fy5f7l8ymHE319ipNZHIMhw50h0l/Puzjd
|
||||
vn3iHWtwpFw5r+nJTr5zO+3yL4dPcp8XfX3Daa5nDfCJ7dd1wSOf+/1cvBLB5aKc
|
||||
kyZ/ppvTc3oJAmFHAD2NXf15CUWE18Te/Vy9X2qI8LkFtea6GDF4VBewT2PATg12
|
||||
r03xZWa6KFVbgTIq3GUvtZ8UHm+cluTFKX90rFtbzFo658mxQGw5RnE2zp340NzP
|
||||
v9tNSlP4Tyzr2b1VoQcgmpQ987afINJG39lq2OsSrlK87p9bB4yoFSZwOfqok0nM
|
||||
IICRxBuTUHLqP3Nhvo+tAl+iK848LDJVf87ZVQHl72JX4lkVvOo5LCXnOQPyowaP
|
||||
D++J2c6tUj6gs9HAKVX7fH06m/2T5fJHae/OYx36O242yBXPQdHx6qloF/DNvGyM
|
||||
EHC3NCCjLG5m6G0=
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
159
sdk/circuits/disclose_vkey.json
Normal file
@@ -0,0 +1,159 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 14,
|
||||
"vk_alpha_1": [
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"6942436740229168666595536581519256291593117600832247164924519038970269461046",
|
||||
"17557865657217054151399710026819127874171362865266657132072043760282335721027"
|
||||
],
|
||||
[
|
||||
"15629082942757783052734933529055204330846116501031658743204188522840567440030",
|
||||
"866803245463331646327183913175583329159450203348438102150009828684148559895"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"10998553002727424987884583305349753345629818748955483305954960876370686844925",
|
||||
"18369020735737057562107768810182682586161750799521907185011795199521493953276",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"3870156317905136354369536369223776179854927352937539086581682263147147725326",
|
||||
"947908099816727525943796981035826395896386995128918341433720280874486019589",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"9619614659642762666110070745787072277198407288262286655564043642023793950605",
|
||||
"1444870940646607538213811271690623291794427513321591343855928143309974143815",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"10290556281387838061211784545032614883237381276187632418810139452226710406378",
|
||||
"12820288689147023950592422696432066467590193138126598372596214785570201388663",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"10044189939644279332588298610988772483187101321076758071894028734198440253205",
|
||||
"15016612240779620571490237444430121691511928826472608688773111463692886510804",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"6158786594227478832634691320618082224218218524296943509099128649963428556955",
|
||||
"2818896662082406397657145229256654653904841140122301210666395782176903475916",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"200295911748915977788397688942615122670319721182540082686195028815964792730",
|
||||
"16374098866162622474777608838325780437892472095191094825634065695603492498672",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"1001933084599581827076405562561115761770358156189382784432273793509010836288",
|
||||
"13618159500648302749264797924828312592779374840705268445533823753672345860949",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"12152127135355257668073159516593687751413730484411437719952408933610175077761",
|
||||
"15590965974244077225547659000022179448961631917634079092877797469009672737373",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"14643873766083688335082369233094018379987105460165787549629338089338629672719",
|
||||
"18976194036990056092890684065171543382286602242265347684324001010669281606450",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4974359282562923295097396773583362835614429754286473873410152881834388935350",
|
||||
"2615967425575591157936435871031665935046196308487298765704452331348089292330",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"16489750714044704248135942822786071904168862423655325973193848507501139487825",
|
||||
"4644993658884496411511912365771411317040070112230395754480725062427812526601",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"11801682757910657983396995619983996921870874978799260563404809167285348391422",
|
||||
"19228652101325919244735412842681375925619382430642205708320466729501949572254",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4495248066509783309072792039672520701419947625749866524660708846549914823847",
|
||||
"4585216314173588273427806971446529726371555267351812069737927114283850919560",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"18719866673490039760627957665040843673978402675108669037278157044178865894074",
|
||||
"11183065716352601580915387671262116390467334689778841393328736869598818253587",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||
99
sdk/circuits/dsc_4096_vkey.json
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 2,
|
||||
"vk_alpha_1": [
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"5689878758968408864570330769586116386424915777760869435924001045372426387042",
|
||||
"14835593574773248144471339475507473753186624066904877663229402603601341881110"
|
||||
],
|
||||
[
|
||||
"2051149603231436076479384106975809917151570357124249160820058911298166997663",
|
||||
"628452860859295088428620228489450512026200467380394004198146223506590955249"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"14532585603301627491293557600415273871129994972736322653869196794622673732921",
|
||||
"18882397311658692526609112965864523608034856647654838257030831022893270548325",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4186298633367159062520988354552715829159959996352603762446141935317873102425",
|
||||
"3924212783150620566854971503130830169563464952561919541343311327675656189646",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4437362653636713552232717650847448346211317604147264938993567382296904710753",
|
||||
"2938386579388053271692442071404949636853984120968379123259292205410760857324",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||