Skip to content

Commit

Permalink
Merge pull request #224 from zk-passport/deeplink
Browse files Browse the repository at this point in the history
qrCode deeplinking
  • Loading branch information
remicolin authored Oct 22, 2024
2 parents f1c5856 + 0a70d30 commit c65b7eb
Show file tree
Hide file tree
Showing 23 changed files with 240 additions and 261 deletions.
8 changes: 7 additions & 1 deletion app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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';
import { setupUniversalLinkListener } from './src/utils/qrCode'; // Adjust the import path as needed
global.Buffer = Buffer;

function App(): React.JSX.Element {
Expand All @@ -29,13 +30,18 @@ function App(): React.JSX.Element {
useEffect(() => {
setSelectedTab('splash');
}, [setSelectedTab]);

useEffect(() => {
if (AMPLITUDE_KEY) {
amplitude.init(AMPLITUDE_KEY);
}
}, []);

useEffect(() => {
const cleanup = setupUniversalLinkListener();
return cleanup;
}, []);

return (
<YStack f={1} bc={bgWhite} h="100%" w="100%">
<YStack h="100%" w="100%">
Expand Down
4 changes: 3 additions & 1 deletion app/ios/OpenPassport.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
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>"; };
169349842CC694DA00166F21 /* OpenPassportDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = OpenPassportDebug.entitlements; path = OpenPassport/OpenPassportDebug.entitlements; 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>"; };
7C737C07B2C3788F9AB02DE4 /* Pods-OpenPassport.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenPassport.release.xcconfig"; path = "Target Support Files/Pods-OpenPassport/Pods-OpenPassport.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -180,6 +181,7 @@
13B07FAE1A68108700A75B9A /* OpenPassport */ = {
isa = PBXGroup;
children = (
169349842CC694DA00166F21 /* OpenPassportDebug.entitlements */,
16E884A42C5BD764003B7125 /* passport.json */,
05EDEDC42B52D25D00AA51AD /* Prover.m */,
05EDEDC52B52D25D00AA51AD /* Prover.swift */,
Expand Down Expand Up @@ -491,7 +493,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = OpenPassport/OpenPassport.entitlements;
CODE_SIGN_ENTITLEMENTS = OpenPassport/OpenPassportDebug.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 63;
Expand Down
13 changes: 11 additions & 2 deletions app/ios/OpenPassport/AppDelegate.mm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTBridge.h>
#import <React/RCTLinkingManager.h>

@implementation AppDelegate

Expand Down Expand Up @@ -30,4 +30,13 @@ - (NSURL *)bundleURL
#endif
}

@end
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}

@end
9 changes: 9 additions & 0 deletions app/ios/OpenPassport/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,14 @@
<string>A0000002472001</string>
<string>00000000000000</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>proofofpassport</string>
</array>
</dict>
</array>
</dict>
</plist>
1 change: 1 addition & 0 deletions app/ios/OpenPassport/OpenPassport.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<string>appclips:openpassport.app</string>
<string>appclips:staging.openpassport.app</string>
<string>appclips:appclip.openpassport.app</string>
<string>applinks:proofofpassport-merkle-tree.xyz</string>
</array>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
Expand Down
23 changes: 23 additions & 0 deletions app/ios/OpenPassport/OpenPassportDebug.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-appclip-app-identifiers</key>
<array>
<string>5B29R5LYHQ.com.warroom.proofofpassport.Clip</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>appclips:openpassport.app</string>
<string>appclips:staging.openpassport.app</string>
<string>appclips:appclip.openpassport.app</string>
<string>applinks:proofofpassport-merkle-tree.xyz</string>
</array>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>
12 changes: 0 additions & 12 deletions app/src/screens/MainScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import ProveScreen from './ProveScreen';
import NfcScreen from './NfcScreen';
import CameraScreen from './CameraScreen';
import NextScreen from './NextScreen';
import RegisterScreen from './RegisterScreen';
import AppScreen from './AppScreen';
// import constants
import { RPC_URL, SignatureAlgorithmIndex } from '../../../common/src/constants/constants';
Expand Down Expand Up @@ -336,14 +335,6 @@ const MainScreen: React.FC = () => {
<Eraser color={textColor2} />
</Button>
</Fieldset>
<Fieldset gap="$4" mt="$1" horizontal>
<Label color={textBlack} width={200} justifyContent="flex-end" htmlFor="skip" >
go to register
</Label>
<Button bg="white" jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" onPress={() => setSelectedTab('register')}>
<ArrowRight color={textColor2} />
</Button>
</Fieldset>
<Fieldset gap="$4" mt="$1" horizontal>
<Label color={textBlack} width={200} justifyContent="flex-end" htmlFor="skip" >
registered = (!registered)
Expand Down Expand Up @@ -689,9 +680,6 @@ const MainScreen: React.FC = () => {
<Tabs.Content value="next" f={1}>
<NextScreen />
</Tabs.Content>
<Tabs.Content value="register" f={1}>
<RegisterScreen />
</Tabs.Content>
<Tabs.Content value="app" f={1}>
<AppScreen
setSheetAppListOpen={setSheetAppListOpen}
Expand Down
72 changes: 25 additions & 47 deletions app/src/screens/ProveScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { countryCodes, DEVELOPMENT_MODE, max_cert_bytes, } from '../../../common
import { bgGreen, bgGreen2, greenColorLight, separatorColor, textBlack } from '../utils/colors';
import useUserStore from '../stores/userStore';
import useNavigationStore from '../stores/navigationStore';
import { ArgumentsDisclose, DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/appType';
import { DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/appType';
import CustomButton from '../components/CustomButton';
import { formatProof, generateProof } from '../utils/prover';
import { generateProof } from '../utils/prover';
import io, { Socket } from 'socket.io-client';
import { getCircuitName, parseCertificate, parseDSC } from '../../../common/src/utils/certificates/handleCertificate';
import { getCircuitName, parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
import { CircuitName } from '../utils/zkeyDownload';
import { generateCircuitInputsInApp } from '../utils/generateInputsInApp';
import { buildAttestation } from '../../../common/src/utils/openPassportAttestation';
Expand Down Expand Up @@ -41,7 +41,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
const [isConnecting, setIsConnecting] = useState(false);
const { signatureAlgorithm, hashFunction, authorityKeyIdentifier } = parseCertificate(passportData.dsc);
const { secret, dscSecret } = useUserStore.getState();
const circuitName = getCircuitName("prove", signatureAlgorithm, hashFunction);
const circuitName = getCircuitName(selectedApp.mode, signatureAlgorithm, hashFunction);

const waitForSocketConnection = (socket: Socket): Promise<void> => {
return new Promise((resolve) => {
Expand Down Expand Up @@ -88,7 +88,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
console.log("result", result);
if (JSON.parse(result).valid) {
toast.show("✅", {
message: "Proof verified",
message: "Identity verified",
customData: {
type: "success",
},
Expand All @@ -98,7 +98,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
}, 700);
} else {
toast.show("❌", {
message: "Wrong proof",
message: "Verification failed",
customData: {
type: "info",
},
Expand Down Expand Up @@ -142,28 +142,16 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>

socket.emit('proof_generation_start', { sessionId: selectedApp.sessionId });

console.log("selectedApp.mode", selectedApp.mode);
const inputs = await generateCircuitInputsInApp(passportData, selectedApp);
let attestation;
let proof;
let dscProof;

switch (selectedApp.mode) {
case 'vc_and_disclose':
const inputs_disclose = await generateCircuitInputsInApp(passportData, selectedApp);
const proof_disclose = await generateProof('vc_and_disclose', inputs_disclose);
const formattedProof_disclose = formatProof(proof_disclose);
console.log(formattedProof_disclose);
const attestation_disclose = buildAttestation({
userIdType: selectedApp.userIdType,
mode: selectedApp.mode,
proof: formattedProof_disclose.proof,
publicSignals: formattedProof_disclose.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
});
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation_disclose });
break;
case 'prove_onchain':
case 'register':
const inputs = await generateCircuitInputsInApp(passportData, selectedApp);
const cscaInputs = generateCircuitInputsDSC(dscSecret as string, passportData.dsc, max_cert_bytes, true);
const [modalResponse, proof] = await Promise.all([
const cscaInputs = generateCircuitInputsDSC(dscSecret as string, passportData.dsc, max_cert_bytes, selectedApp.devMode);
[dscProof, proof] = await Promise.all([
sendCSCARequest(
cscaInputs
),
Expand All @@ -172,17 +160,12 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
inputs,
)
]);
const dscProof = JSON.parse(JSON.stringify(modalResponse));
const cscaPem = getCSCAFromSKI(authorityKeyIdentifier, DEVELOPMENT_MODE);
if (!cscaPem) {
throw new Error(`CSCA not found, devMode: ${DEVELOPMENT_MODE}, authorityKeyIdentifier: ${authorityKeyIdentifier}`);
}
const { signatureAlgorithm: signatureAlgorithmDsc } = parseCertificate(cscaPem);
const formattedProof = formatProof(proof);
const attestation = buildAttestation({
attestation = buildAttestation({
mode: selectedApp.mode,
proof: formattedProof.proof,
publicSignals: formattedProof.publicSignals,
proof: proof.proof,
publicSignals: proof.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
userIdType: selectedApp.userIdType,
Expand All @@ -191,30 +174,25 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
signatureAlgorithmDsc: signatureAlgorithmDsc,
hashFunctionDsc: hashFunction,
});
console.log("\x1b[90mattestation\x1b[0m", attestation);
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation });
break;
case 'prove_offchain':
const inputs_prove = await generateCircuitInputsInApp(passportData, selectedApp);
const proof_prove = await generateProof(
default:
proof = await generateProof(
circuitName,
inputs_prove,
);
const formattedProof_prove = formatProof(proof_prove);
const attestation_prove = buildAttestation({
inputs,
)
attestation = buildAttestation({
userIdType: selectedApp.userIdType,
mode: selectedApp.mode,
proof: formattedProof_prove.proof,
publicSignals: formattedProof_prove.publicSignals,
proof: proof.proof,
publicSignals: proof.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
dsc: passportData.dsc,
});
console.log("\x1b[90mattestation\x1b[0m", attestation_prove);

socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation_prove });
break;
}
console.log("\x1b[90mattestation\x1b[0m", attestation);
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation });

} catch (error) {
toast.show("Error", {
Expand Down
78 changes: 0 additions & 78 deletions app/src/screens/RegisterScreen.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions app/src/utils/prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ export const generateProof = async (
if (Platform.OS === 'android') {
const parsedResponse = parseProofAndroid(response);
console.log('parsedResponse', parsedResponse);
return parsedResponse
return formatProof(parsedResponse)
} else {
const parsedResponse = JSON.parse(response);
console.log('parsedResponse', parsedResponse);

return {
return formatProof({
proof: parsedResponse.proof,
pub_signals: parsedResponse.inputs,
}
})
}
} catch (err: any) {
console.log('err', err);
Expand Down
Loading

0 comments on commit c65b7eb

Please sign in to comment.