Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2fd522e
fix build issues
remicolin Jun 17, 2025
d716ae9
generate disclosure proof with euids
remicolin Jun 17, 2025
4907ebc
generate disclosure proof with euids
remicolin Jun 17, 2025
a5ef23b
Eu id updates 2 (#648)
remicolin Jun 19, 2025
0d0504a
remove the mock user define data
remicolin Jun 19, 2025
03224df
get the useridentifier as a hash from the user defined data
remicolin Jun 19, 2025
aec0a2a
chore: add version and userDefinedData
Nesopie Jun 19, 2025
d611520
feat: use the version in register / dsc proofs as well
Nesopie Jun 19, 2025
3afaa09
update calculateUserIdentifierHash
remicolin Jun 20, 2025
fe15834
yarn nice
remicolin Jun 20, 2025
0de5f55
refactor: consolidate user context data handling and update payload s…
remicolin Jun 20, 2025
6f6d4e3
fix typing issues on sha1
remicolin Jun 20, 2025
9bd33b0
remove console.log(sha1)
remicolin Jun 20, 2025
e6eb174
fix sha1 import
remicolin Jun 20, 2025
572471c
refactor: streamline userDefinedData handling and adjust payload type…
remicolin Jun 21, 2025
062220f
refactor: update sha1 usage and enhance logging in calculateUserIdent…
remicolin Jun 21, 2025
136b8a6
yarn nice
remicolin Jun 21, 2025
9047865
chore: update dependencies in yarn.lock, including create-hash, hash-…
remicolin Jun 21, 2025
9bf0d28
yarn lint common
remicolin Jun 21, 2025
37f30a9
use ts-ignore for sha1 import
remicolin Jun 21, 2025
b5a064a
fix app ci tests
remicolin Jun 21, 2025
a25fc9f
fix typing issue
remicolin Jun 21, 2025
7d88fd1
remove unused ts-ignore
remicolin Jun 21, 2025
b9ba4ba
cast uuid before calling generateinputs
remicolin Jun 21, 2025
7d7ff75
bump qrcode version
remicolin Jun 21, 2025
cbb4298
add tsup on the qrcode sdk
remicolin Jun 21, 2025
0ba0b26
fix: exports on selfxyz/qrcode
Nesopie Jun 21, 2025
1edce70
update how we define config.version
remicolin Jun 22, 2025
9f6b958
merge dev
remicolin Jun 23, 2025
d5a8884
fix yarn imports
remicolin Jun 23, 2025
283d8ff
yarn format
remicolin Jun 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions app/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@ PODS:
- Yoga
- react-native-biometrics (3.0.1):
- React-Core
- react-native-cloud-storage (2.2.2):
- react-native-cloud-storage (2.3.0):
- DoubleConversion
- glog
- RCT-Folly (= 2024.01.01.00)
Expand All @@ -1410,7 +1410,7 @@ PODS:
- React-Core
- react-native-nfc-manager (3.16.1):
- React-Core
- react-native-quick-crypto (0.7.13):
- react-native-quick-crypto (0.7.14):
- DoubleConversion
- glog
- OpenSSL-Universal
Expand Down Expand Up @@ -1680,7 +1680,7 @@ PODS:
- React-logger (= 0.75.4)
- React-perflogger (= 0.75.4)
- React-utils (= 0.75.4)
- RNCAsyncStorage (2.1.2):
- RNCAsyncStorage (2.2.0):
- React-Core
- RNCClipboard (1.13.2):
- React-Core
Expand All @@ -1694,7 +1694,7 @@ PODS:
- FirebaseCoreExtension
- React-Core
- RNFBApp
- RNGestureHandler (2.25.0):
- RNGestureHandler (2.26.0):
- DoubleConversion
- glog
- RCT-Folly (= 2024.01.01.00)
Expand Down Expand Up @@ -1808,7 +1808,7 @@ PODS:
- Yoga
- RNSVG (15.12.0):
- React-Core
- segment-analytics-react-native (2.21.0):
- segment-analytics-react-native (2.21.1):
- React-Core
- sovran-react-native
- Sentry (8.52.1):
Expand Down Expand Up @@ -2193,11 +2193,11 @@ SPEC CHECKSUMS:
React-Mapbuffer: b2642edd9be75d51ead8cda109c986665eae09cf
React-microtasksnativemodule: 7ebf131e1792a668004d2719a36da0ff8d19c43c
react-native-biometrics: 43ed5b828646a7862dbc7945556446be00798e7d
react-native-cloud-storage: 74d1f1456d714e0fca6d10c7ab6fe9a52ba203b6
react-native-cloud-storage: 47e6649373f429d2f244c904347e9fc4d9ef4ca8
react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba
react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187
react-native-nfc-manager: a280ef94cd4871a471b052f0dc70381cf1223049
react-native-quick-crypto: 2d8136faf9e82a8f396a9b5ad85203ac20212739
react-native-quick-crypto: c42da02f2832626ec0b8d8465f2f9b3889a317f6
react-native-safe-area-context: dde2052b903c11d677c320b599c3244021c34ce8
react-native-sqlite-storage: 0c84826214baaa498796c7e46a5ccc9a82e114ed
React-nativeconfig: 31072ab0146e643594f6959c7f970a04b6c9ddd0
Expand Down Expand Up @@ -2225,20 +2225,20 @@ SPEC CHECKSUMS:
React-utils: 7198bd077f07ce8f9263c05bf610da6e251058ad
ReactCodegen: fbd3d6af21ba08f12ccd0f542393393d21134ea5
ReactCommon: b02a50498cb1071cd793044ddbd5d2b5f4db0a34
RNCAsyncStorage: b9f5f78da5d16a853fe3dc22e8268d932fc45a83
RNCAsyncStorage: b44e8a4e798c3e1f56bffccd0f591f674fb9198f
RNCClipboard: 4abb037e8fe3b98a952564c9e0474f91c492df6d
RNDeviceInfo: d863506092aef7e7af3a1c350c913d867d795047
RNFBApp: 4097f75673f8b42a7cd1ba17e6ea85a94b45e4d1
RNFBMessaging: 92325b0d5619ac90ef023a23cfd16fd3b91d0a88
RNGestureHandler: ffb1f106c7a78377a2ae7568d51ccf87dc5c83c6
RNGestureHandler: 91daedefd7d806685658f927603a5302712fce48
RNGoogleSignin: 576a84dd0407b912e7a0adf07492de9feb79e5d9
RNKeychain: 4990d9be2916c60f9ed4f8c484fcd7ced4828b86
RNLocalize: 15463c4d79c7da45230064b4adcf5e9bb984667e
RNReactNativeHapticFeedback: e19b9b2e2ecf5593de8c4ef1496e1e31ae227514
RNScreens: b7e8d29c6be98f478bc3fb4a97cc770aa9ba7509
RNSentry: c462461c0a5aaba206265f1f3db01b237cd33239
RNSVG: e3ad69848b6357587545e0a49628b1148acf082c
segment-analytics-react-native: dab2ae61d917629b8d040b572f9f7a11b2cc5940
segment-analytics-react-native: 5c3e8a4ee6d7532a011ed862d7c7d4fb5e5303e2
Sentry: 1ca8405451040482877dcd344dfa3ef80b646631
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Expand Down
2 changes: 1 addition & 1 deletion app/jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|@react-navigation|@react-native-community|@segment/analytics-react-native|@openpassport|react-native-keychain|react-native-check-version|react-native-nfc-manager|react-native-passport-reader|uuid|@stablelib|@react-native-google-signin|react-native-cloud-storage|@react-native-clipboard|@react-native-firebase)/)',
'node_modules/(?!(react-native|@react-native|@react-navigation|@react-native-community|@segment/analytics-react-native|@openpassport|react-native-keychain|react-native-check-version|react-native-nfc-manager|react-native-passport-reader|react-native-gesture-handler|uuid|@stablelib|@react-native-google-signin|react-native-cloud-storage|@react-native-clipboard|@react-native-firebase)/)',
],
setupFiles: ['<rootDir>/jest.setup.js'],
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$',
Expand Down
8 changes: 8 additions & 0 deletions app/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,22 @@ jest.mock('@segment/analytics-react-native', () => {
reset: jest.fn(),
};

// Mock flush policy classes
const MockFlushPolicy = class {
constructor() {}
};

return {
createClient: jest.fn(() => mockClient),
EventPlugin: jest.fn(),
PluginType: {
ENRICHMENT: 'enrichment',
DESTINATION: 'destination',
BEFORE: 'before',
before: 'before',
},
StartupFlushPolicy: MockFlushPolicy,
BackgroundFlushPolicy: MockFlushPolicy,
};
});

Expand Down
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"install-app:setup": "yarn install && yarn build:deps && cd ios && bundle install && cd ..",
"ios": "react-native run-ios",
"ios:fastlane-debug": "yarn reinstall && bundle exec fastlane --verbose ios internal_test",
"setup": "yarn clean:build && yarn install && yarn build:deps && cd ios && bundle install && bundle exec pod install --repo-update && cd .. && yarn clean:xcode-env-local",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"nice": "yarn lint:fix && yarn fmt:fix",
Expand Down
25 changes: 25 additions & 0 deletions app/src/screens/prove/ProveScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,31 @@ const ProveScreen: React.FC = () => {
onLayout={handleScrollViewLayout}
>
<Disclosures disclosures={disclosureOptions} />

{/* Display userDefinedData if it exists */}
{selectedApp?.userDefinedData && (
<View marginTop={20} paddingHorizontal={20}>
<BodyText
fontSize={16}
color={black}
fontWeight="600"
marginBottom={10}
>
Additional Information:
</BodyText>
<View
backgroundColor={slate300}
padding={15}
borderRadius={8}
marginBottom={10}
>
<BodyText fontSize={14} color={black} lineHeight={20}>
{selectedApp.userDefinedData}
</BodyText>
</View>
</View>
)}

<View marginTop={20}>
<Caption
textAlign="center"
Expand Down
1 change: 0 additions & 1 deletion app/src/utils/ethers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ ethers.computeHmac.register((algo, key, data) => {
return crypto.createHmac(algo, key).update(data).digest();
});

// @ts-expect-error
ethers.pbkdf2.register((passwd, salt, iter, keylen, algo) => {
return crypto.pbkdf2Sync(passwd, salt, iter, keylen, algo);
});
Expand Down
110 changes: 88 additions & 22 deletions app/src/utils/proving/provingInputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
import { SMT } from '@openpassport/zk-kit-smt';
import {
attributeToPosition,
attributeToPosition_ID,
DEFAULT_MAJORITY,
DocumentCategory,
ID_CARD_ATTESTATION_ID,
PASSPORT_ATTESTATION_ID,
SelfAppDisclosureConfig,
} from '@selfxyz/common';
import { SelfApp } from '@selfxyz/common';
import { getCircuitNameFromPassportData } from '@selfxyz/common';
Expand All @@ -13,9 +17,12 @@ import {
generateCircuitInputsVCandDisclose,
} from '@selfxyz/common';
import { hashEndpointWithScope } from '@selfxyz/common';
import { calculateUserIdentifierHash } from '@selfxyz/common';
import { PassportData } from '@selfxyz/common';
import nameAndDobSMTData from '@selfxyz/common/ofacdata/outputs/nameAndDobSMT.json';
import nameAndDobSMTDataID from '@selfxyz/common/ofacdata/outputs/nameAndDobSMT_ID.json';
import nameAndYobSMTData from '@selfxyz/common/ofacdata/outputs/nameAndYobSMT.json';
import nameAndYobSMTDataID from '@selfxyz/common/ofacdata/outputs/nameAndYobSMT_ID.json';
import passportNoAndNationalitySMTData from '@selfxyz/common/ofacdata/outputs/passportNoAndNationalitySMT.json';
import { poseidon2 } from 'poseidon-lite';

Expand Down Expand Up @@ -55,19 +62,17 @@ export function generateTEEInputsDisclose(
passportData: PassportData,
selfApp: SelfApp,
) {
const { scope, userId, disclosures, endpoint } = selfApp;
const { scope, disclosures, endpoint, userId, userDefinedData, chainID } =
selfApp;
const userIdentifierHash = calculateUserIdentifierHash(
chainID,
userId,
userDefinedData,
);
const scope_hash = hashEndpointWithScope(endpoint, scope);
const selector_dg1 = Array(88).fill('0');
Object.entries(disclosures).forEach(([attribute, reveal]) => {
if (['ofac', 'excludedCountries', 'minimumAge'].includes(attribute)) {
return;
}
if (reveal) {
const [start, end] =
attributeToPosition[attribute as keyof typeof attributeToPosition];
selector_dg1.fill('1', start, end + 1);
}
});
const document: DocumentCategory = passportData.documentCategory;

const selector_dg1 = getSelectorDg1(document, disclosures);

const majority = disclosures.minimumAge
? disclosures.minimumAge.toString()
Expand All @@ -76,30 +81,37 @@ export function generateTEEInputsDisclose(

const selector_ofac = disclosures.ofac ? 1 : 0;

const { passportNoAndNationalitySMT, nameAndDobSMT, nameAndYobSMT } =
getOfacSMTs();
const serialized_tree = useProtocolStore.getState().passport.commitment_tree;
const {
passportNoAndNationalitySMT,
nameAndDobSMT,
nameAndYobSMT,
nameAndDobSMTID,
nameAndYobSMTID,
} = getOfacSMTs();
const serialized_tree = useProtocolStore.getState()[document].commitment_tree;
const tree = LeanIMT.import((a, b) => poseidon2([a, b]), serialized_tree);

const inputs = generateCircuitInputsVCandDisclose(
secret,
PASSPORT_ATTESTATION_ID,
document === 'passport' ? PASSPORT_ATTESTATION_ID : ID_CARD_ATTESTATION_ID,
passportData,
scope_hash,
selector_dg1,
selector_older_than,
tree,
majority,
passportNoAndNationalitySMT,
nameAndDobSMT,
nameAndYobSMT,
document === 'passport' ? nameAndDobSMT : nameAndDobSMTID,
document === 'passport' ? nameAndYobSMT : nameAndYobSMTID,
selector_ofac,
disclosures.excludedCountries ?? [],
userId,
userIdentifierHash.toString(),
);
return {
inputs,
circuitName: 'vc_and_disclose',
circuitName:
passportData.documentCategory === 'passport'
? 'vc_and_disclose'
: 'vc_and_disclose_id',
endpointType: selfApp.endpointType,
endpoint: selfApp.endpoint,
};
Expand All @@ -115,5 +127,59 @@ function getOfacSMTs() {
nameAndDobSMT.import(nameAndDobSMTData);
const nameAndYobSMT = new SMT(poseidon2, true);
nameAndYobSMT.import(nameAndYobSMTData);
return { passportNoAndNationalitySMT, nameAndDobSMT, nameAndYobSMT };
const nameAndDobSMTID = new SMT(poseidon2, true);
nameAndDobSMTID.import(nameAndDobSMTDataID);
const nameAndYobSMTID = new SMT(poseidon2, true);
nameAndYobSMTID.import(nameAndYobSMTDataID);
return {
passportNoAndNationalitySMT,
nameAndDobSMT,
nameAndYobSMT,
nameAndDobSMTID,
nameAndYobSMTID,
};
}

function getSelectorDg1(
document: DocumentCategory,
disclosures: SelfAppDisclosureConfig,
) {
switch (document) {
case 'passport':
return getSelectorDg1Passport(disclosures);
case 'id_card':
return getSelectorDg1IdCard(disclosures);
}
}

function getSelectorDg1Passport(disclosures: SelfAppDisclosureConfig) {
const selector_dg1 = Array(88).fill('0');
Object.entries(disclosures).forEach(([attribute, reveal]) => {
if (['ofac', 'excludedCountries', 'minimumAge'].includes(attribute)) {
return;
}
if (reveal) {
const [start, end] =
attributeToPosition[attribute as keyof typeof attributeToPosition];
selector_dg1.fill('1', start, end + 1);
}
});
return selector_dg1;
}

function getSelectorDg1IdCard(disclosures: SelfAppDisclosureConfig) {
const selector_dg1 = Array(90).fill('0');
Object.entries(disclosures).forEach(([attribute, reveal]) => {
if (['ofac', 'excludedCountries', 'minimumAge'].includes(attribute)) {
return;
}
if (reveal) {
const [start, end] =
attributeToPosition_ID[
attribute as keyof typeof attributeToPosition_ID
];
selector_dg1.fill('1', start, end + 1);
}
});
return selector_dg1;
}
Loading