mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
* chore: centralize license header scripts * chore: run license header checks from root * add header to other files * add header to bundle * add migration script and update check license headers * convert license to mobile sdk * migrate license headers * remove headers from common; convert remaining * fix headers * add license header checks
161 lines
5.3 KiB
TypeScript
161 lines
5.3 KiB
TypeScript
import { poseidon2 } from 'poseidon-lite';
|
|
|
|
import {
|
|
attributeToPosition,
|
|
attributeToPosition_ID,
|
|
DEFAULT_MAJORITY,
|
|
ID_CARD_ATTESTATION_ID,
|
|
PASSPORT_ATTESTATION_ID,
|
|
} from '../../constants/constants.js';
|
|
import type { DocumentCategory, PassportData } from '../../types/index.js';
|
|
import type { SelfApp, SelfAppDisclosureConfig } from '../../utils/appType.js';
|
|
import {
|
|
calculateUserIdentifierHash,
|
|
generateCircuitInputsDSC,
|
|
generateCircuitInputsRegister,
|
|
generateCircuitInputsVCandDisclose,
|
|
getCircuitNameFromPassportData,
|
|
hashEndpointWithScope,
|
|
} from '../../utils/index.js';
|
|
import type { OfacTree } from '../../utils/types.js';
|
|
|
|
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
|
|
import { SMT } from '@openpassport/zk-kit-smt';
|
|
|
|
export { generateCircuitInputsRegister } from './generateInputs.js';
|
|
|
|
export function generateTEEInputsDSC(
|
|
passportData: PassportData,
|
|
cscaTree: string[][],
|
|
env: 'prod' | 'stg'
|
|
) {
|
|
const inputs = generateCircuitInputsDSC(passportData, cscaTree);
|
|
const circuitName = getCircuitNameFromPassportData(passportData, 'dsc');
|
|
const endpointType = env === 'stg' ? 'staging_celo' : 'celo';
|
|
const endpoint = 'https://self.xyz';
|
|
return { inputs, circuitName, endpointType, endpoint };
|
|
}
|
|
|
|
export function generateTEEInputsDiscloseStateless(
|
|
secret: string,
|
|
passportData: PassportData,
|
|
selfApp: SelfApp,
|
|
getTree: <T extends 'ofac' | 'commitment'>(
|
|
doc: DocumentCategory,
|
|
tree: T
|
|
) => T extends 'ofac' ? OfacTree : any
|
|
) {
|
|
const { scope, disclosures, endpoint, userId, userDefinedData, chainID } = selfApp;
|
|
const userIdentifierHash = calculateUserIdentifierHash(chainID, userId, userDefinedData);
|
|
const scope_hash = hashEndpointWithScope(endpoint, scope);
|
|
const document: DocumentCategory = passportData.documentCategory;
|
|
|
|
const selector_dg1 = getSelectorDg1(document, disclosures);
|
|
|
|
const majority = disclosures.minimumAge ? disclosures.minimumAge.toString() : DEFAULT_MAJORITY;
|
|
const selector_older_than = disclosures.minimumAge ? '1' : '0';
|
|
|
|
const selector_ofac = disclosures.ofac ? 1 : 0;
|
|
|
|
const ofac_trees = getTree(document, 'ofac');
|
|
if (!ofac_trees) {
|
|
throw new Error('OFAC trees not loaded');
|
|
}
|
|
|
|
// Validate OFAC tree structure
|
|
if (!ofac_trees.nameAndDob || !ofac_trees.nameAndYob) {
|
|
throw new Error('Invalid OFAC tree structure: missing required fields');
|
|
}
|
|
if (document === 'passport' && !ofac_trees.passportNoAndNationality) {
|
|
throw new Error('Invalid OFAC tree structure: missing passportNoAndNationality for passport');
|
|
}
|
|
|
|
let passportNoAndNationalitySMT: SMT | null = null;
|
|
const nameAndDobSMT = new SMT(poseidon2, true);
|
|
const nameAndYobSMT = new SMT(poseidon2, true);
|
|
if (document === 'passport') {
|
|
passportNoAndNationalitySMT = new SMT(poseidon2, true);
|
|
passportNoAndNationalitySMT.import(ofac_trees.passportNoAndNationality);
|
|
}
|
|
nameAndDobSMT.import(ofac_trees.nameAndDob);
|
|
nameAndYobSMT.import(ofac_trees.nameAndYob);
|
|
|
|
const serialized_tree = getTree(document, 'commitment');
|
|
const tree = LeanIMT.import((a, b) => poseidon2([a, b]), serialized_tree);
|
|
const inputs = generateCircuitInputsVCandDisclose(
|
|
secret,
|
|
document === 'passport' ? PASSPORT_ATTESTATION_ID : ID_CARD_ATTESTATION_ID,
|
|
passportData,
|
|
scope_hash,
|
|
selector_dg1,
|
|
selector_older_than,
|
|
tree,
|
|
majority,
|
|
passportNoAndNationalitySMT,
|
|
nameAndDobSMT,
|
|
nameAndYobSMT,
|
|
selector_ofac,
|
|
disclosures.excludedCountries ?? [],
|
|
userIdentifierHash.toString()
|
|
);
|
|
return {
|
|
inputs,
|
|
circuitName:
|
|
passportData.documentCategory === 'passport' ? 'vc_and_disclose' : 'vc_and_disclose_id',
|
|
endpointType: selfApp.endpointType,
|
|
endpoint: selfApp.endpoint,
|
|
};
|
|
}
|
|
|
|
export function generateTEEInputsRegister(
|
|
secret: string,
|
|
passportData: PassportData,
|
|
dscTree: string,
|
|
env: 'prod' | 'stg'
|
|
) {
|
|
const inputs = generateCircuitInputsRegister(secret, passportData, dscTree);
|
|
const circuitName = getCircuitNameFromPassportData(passportData, 'register');
|
|
const endpointType = env === 'stg' ? 'staging_celo' : 'celo';
|
|
const endpoint = 'https://self.xyz';
|
|
return { inputs, circuitName, endpointType, endpoint };
|
|
}
|
|
|
|
/*** DISCLOSURE ***/
|
|
|
|
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;
|
|
}
|