From a7fb017a490fe17dc326bc6936b5ba1d2f577f09 Mon Sep 17 00:00:00 2001 From: Javier Cortejoso Date: Wed, 28 Jan 2026 09:25:13 +0100 Subject: [PATCH 1/6] chore: increase build timeout to 12 hours in circuits-build.yml (#1664) --- .github/workflows/circuits-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/circuits-build.yml b/.github/workflows/circuits-build.yml index c3c368736..178a4d5ce 100644 --- a/.github/workflows/circuits-build.yml +++ b/.github/workflows/circuits-build.yml @@ -33,6 +33,7 @@ concurrency: jobs: build: runs-on: ["128ram"] + timeout-minutes: 720 # 12 hours permissions: contents: read actions: read From 16c58906d92fe761c13fe2975e9feb9c0bc75c96 Mon Sep 17 00:00:00 2001 From: Nesopie <87437291+Nesopie@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:46:49 +0530 Subject: [PATCH 2/6] chore: remove all instances of selfrica (#1665) --- .../scripts/build/build_disclose_circuits.sh | 6 +- .../IdentityVerificationHubImplV2.sol | 10 +- .../contracts/constants/AttestationId.sol | 4 +- .../constants/CircuitConstantsV2.sol | 12 +- .../interfaces/IIdentityRegistryKycV1.sol | 4 +- .../interfaces/IRegisterCircuitVerifier.sol | 2 +- .../IVcAndDiscloseCircuitVerifier.sol | 2 +- .../contracts/libraries/CustomVerifier.sol | 40 +++---- .../contracts/libraries/ProofVerifierLib.sol | 6 +- .../libraries/RegisterProofVerifierLib.sol | 6 +- ...plV1.sol => IdentityRegistryKycImplV1.sol} | 14 +-- contracts/ignition/modules/hub/deployHubV2.ts | 2 +- contracts/test/utils/deploymentV2.ts | 109 +++++++++--------- contracts/test/utils/generateProof.ts | 26 ++--- contracts/test/utils/types.ts | 12 +- contracts/test/v2/discloseKyc.test.ts | 30 ++--- contracts/test/v2/registerKyc.test.ts | 82 ++++++------- 17 files changed, 183 insertions(+), 184 deletions(-) rename contracts/contracts/registry/{IdentityRegistrySelfricaImplV1.sol => IdentityRegistryKycImplV1.sol} (98%) diff --git a/circuits/scripts/build/build_disclose_circuits.sh b/circuits/scripts/build/build_disclose_circuits.sh index b7855a59d..d1981ada9 100755 --- a/circuits/scripts/build/build_disclose_circuits.sh +++ b/circuits/scripts/build/build_disclose_circuits.sh @@ -15,9 +15,9 @@ OUTPUT_DIR="build/${CIRCUIT_TYPE}" # Define circuits and their configurations # format: name:poweroftau:build_flag CIRCUITS=( - # "vc_and_disclose:20:true" - # "vc_and_disclose_id:20:true" - # "vc_and_disclose_aadhaar:20:true" + "vc_and_disclose:20:true" + "vc_and_disclose_id:20:true" + "vc_and_disclose_aadhaar:20:true" "vc_and_disclose_kyc:17:true" ) diff --git a/contracts/contracts/IdentityVerificationHubImplV2.sol b/contracts/contracts/IdentityVerificationHubImplV2.sol index 23a8f5602..f2fdc9e79 100644 --- a/contracts/contracts/IdentityVerificationHubImplV2.sol +++ b/contracts/contracts/IdentityVerificationHubImplV2.sol @@ -313,8 +313,8 @@ contract IdentityVerificationHubImplV2 is ImplRoot { ); } else if (attestationId == AttestationId.KYC) { IIdentityRegistryKycV1($._registries[attestationId]).registerCommitment( - registerCircuitProof.pubSignals[CircuitConstantsV2.SELFRICA_NULLIFIER_INDEX], - registerCircuitProof.pubSignals[CircuitConstantsV2.SELFRICA_COMMITMENT_INDEX] + registerCircuitProof.pubSignals[CircuitConstantsV2.KYC_NULLIFIER_INDEX], + registerCircuitProof.pubSignals[CircuitConstantsV2.KYC_COMMITMENT_INDEX] ); } else { revert InvalidAttestationId(); @@ -876,7 +876,7 @@ contract IdentityVerificationHubImplV2 is ImplRoot { * @notice Performs current date validation with format-aware parsing * @dev Handles three date formats: * - E_PASSPORT/EU_ID_CARD: 6 ASCII chars (YYMMDD) - * - SELFRICA_ID_CARD: 8 ASCII digits (YYYYMMDD) + * - KYC: 8 ASCII digits (YYYYMMDD) * - AADHAAR: 3 numeric signals (year, month, day) * @param attestationId The attestation type to determine date format * @param vcAndDiscloseProof The proof containing date information @@ -900,7 +900,7 @@ contract IdentityVerificationHubImplV2 is ImplRoot { } currentTimestamp = Formatter.proofDateToUnixTimestamp(dateNum); } else if (attestationId == AttestationId.KYC) { - // SELFRICA: 8 ASCII digits (YYYYMMDD) + // KYC: 8 ASCII digits (YYYYMMDD) uint256[3] memory dateNum; // [year, month, day] unchecked { for (uint256 i; i < 4; ++i) @@ -1016,7 +1016,7 @@ contract IdentityVerificationHubImplV2 is ImplRoot { /** * @notice Creates verification output based on attestation type. * @dev Formats proof data into the appropriate output structure for the attestation type. - * @param attestationId The attestation identifier (passport, EU ID card, Aadhaar, or Selfrica). + * @param attestationId The attestation identifier (passport, EU ID card, Aadhaar, or KYC). * @param vcAndDiscloseProof The VC and Disclose proof data. * @param indices The circuit-specific indices for extracting proof values. * @param userIdentifier The user identifier to include in the output. diff --git a/contracts/contracts/constants/AttestationId.sol b/contracts/contracts/constants/AttestationId.sol index 54dcda9b6..f7add8b7e 100644 --- a/contracts/contracts/constants/AttestationId.sol +++ b/contracts/contracts/constants/AttestationId.sol @@ -8,7 +8,7 @@ pragma solidity 0.8.28; * - E_PASSPORT (1): Electronic passports with NFC chip * - EU_ID_CARD (2): EU biometric ID cards with NFC chip * - AADHAAR (3): Indian Aadhaar identity documents - * - SELFRICA_ID_CARD (4): African identity documents via Selfrica/SmileID + * - KYC (4): African identity documents via SumSub */ library AttestationId { /// @notice Identifier for an E-PASSPORT attestation (electronic passports with NFC chip). @@ -20,6 +20,6 @@ library AttestationId { /// @notice Identifier for an AADHAAR attestation (Indian Aadhaar identity documents). bytes32 constant AADHAAR = bytes32(uint256(3)); - /// @notice Identifier for a SELFRICA_ID_CARD attestation (African identity documents via Selfrica/SmileID). + /// @notice Identifier for a KYC attestation (African identity documents via SumSub). bytes32 constant KYC = bytes32(uint256(4)); } diff --git a/contracts/contracts/constants/CircuitConstantsV2.sol b/contracts/contracts/constants/CircuitConstantsV2.sol index 4dbd15980..4c7203ee3 100644 --- a/contracts/contracts/constants/CircuitConstantsV2.sol +++ b/contracts/contracts/constants/CircuitConstantsV2.sol @@ -55,15 +55,15 @@ library CircuitConstantsV2 { uint256 constant AADHAAR_TIMESTAMP_INDEX = 3; // --------------------------- - // Selfrica Circuit Constants + // KYC Circuit Constants // --------------------------- /** - * @notice Index to access the pubkey commitment in the Selfrica circuit public signals. + * @notice Index to access the pubkey commitment in the KYC circuit public signals. */ - uint256 constant SELFRICA_NULLIFIER_INDEX = 0; - uint256 constant SELFRICA_COMMITMENT_INDEX = 1; - uint256 constant SELFRICA_PUBKEY_COMMITMENT_INDEX = 2; - uint256 constant SELFRICA_ATTESTATION_ID_INDEX = 3; + uint256 constant KYC_NULLIFIER_INDEX = 0; + uint256 constant KYC_COMMITMENT_INDEX = 1; + uint256 constant KYC_PUBKEY_COMMITMENT_INDEX = 2; + uint256 constant KYC_ATTESTATION_ID_INDEX = 3; // ------------------------------------- // VC and Disclose Circuit Constants diff --git a/contracts/contracts/interfaces/IIdentityRegistryKycV1.sol b/contracts/contracts/interfaces/IIdentityRegistryKycV1.sol index e5be790c7..bbe2495ac 100644 --- a/contracts/contracts/interfaces/IIdentityRegistryKycV1.sol +++ b/contracts/contracts/interfaces/IIdentityRegistryKycV1.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.28; /** - * @title IIdentityRegistrySelfricaV1 - * @notice Interface for the Identity Registry Selfrica v1. + * @title IIdentityRegistryKycV1 + * @notice Interface for the Identity Registry KYC v1. * @dev This interface exposes only the external functions accessible by regular callers, * i.e. functions that are not owner-restricted. */ diff --git a/contracts/contracts/interfaces/IRegisterCircuitVerifier.sol b/contracts/contracts/interfaces/IRegisterCircuitVerifier.sol index 0bbca3cb9..d9a4a9372 100644 --- a/contracts/contracts/interfaces/IRegisterCircuitVerifier.sol +++ b/contracts/contracts/interfaces/IRegisterCircuitVerifier.sol @@ -64,7 +64,7 @@ interface IAadhaarRegisterCircuitVerifier { ) external view returns (bool isValid); } -interface ISelfricaRegisterCircuitVerifier { +interface IKycRegisterCircuitVerifier { /** * @notice Verifies a given register circuit proof. * @dev This function checks the validity of the provided proof parameters. diff --git a/contracts/contracts/interfaces/IVcAndDiscloseCircuitVerifier.sol b/contracts/contracts/interfaces/IVcAndDiscloseCircuitVerifier.sol index 0c45455b8..68ac1f963 100644 --- a/contracts/contracts/interfaces/IVcAndDiscloseCircuitVerifier.sol +++ b/contracts/contracts/interfaces/IVcAndDiscloseCircuitVerifier.sol @@ -50,7 +50,7 @@ interface IVcAndDiscloseAadhaarCircuitVerifier { ) external view returns (bool); } -interface IVcAndDiscloseSelfricaCircuitVerifier { +interface IVcAndDiscloseKycCircuitVerifier { /** * @notice Verifies a given VC and Disclose zero-knowledge proof. * @dev This function checks the validity of the provided proof parameters. diff --git a/contracts/contracts/libraries/CustomVerifier.sol b/contracts/contracts/libraries/CustomVerifier.sol index 71304a2ce..c9f18ce29 100644 --- a/contracts/contracts/libraries/CustomVerifier.sol +++ b/contracts/contracts/libraries/CustomVerifier.sol @@ -38,8 +38,8 @@ library CustomVerifier { SelfStructs.AadhaarOutput memory aadhaarOutput = abi.decode(proofOutput, (SelfStructs.AadhaarOutput)); return CustomVerifier.verifyAadhaar(verificationConfig, aadhaarOutput); } else if (attestationId == AttestationId.KYC) { - SelfStructs.KycOutput memory selfricaOutput = abi.decode(proofOutput, (SelfStructs.KycOutput)); - return CustomVerifier.verifySelfrica(verificationConfig, selfricaOutput); + SelfStructs.KycOutput memory kycOutput = abi.decode(proofOutput, (SelfStructs.KycOutput)); + return CustomVerifier.verifyKyc(verificationConfig, kycOutput); } else { revert InvalidAttestationId(); } @@ -298,20 +298,20 @@ library CustomVerifier { } /** - * @notice Verifies a Selfrica output. + * @notice Verifies a KYC output. * @param verificationConfig The verification configuration. - * @param selfricaOutput The Selfrica output from the circuit. + * @param kycOutput The KYC output from the circuit. * @return genericDiscloseOutput The generic disclose output. */ - function verifySelfrica( + function verifyKyc( SelfStructs.VerificationConfigV2 memory verificationConfig, - SelfStructs.KycOutput memory selfricaOutput + SelfStructs.KycOutput memory kycOutput ) internal pure returns (SelfStructs.GenericDiscloseOutputV2 memory) { if (verificationConfig.ofacEnabled[1] || verificationConfig.ofacEnabled[2]) { if ( !CircuitAttributeHandlerV2.compareOfac( AttestationId.KYC, - selfricaOutput.revealedDataPacked, + kycOutput.revealedDataPacked, false, verificationConfig.ofacEnabled[1], verificationConfig.ofacEnabled[2] @@ -324,7 +324,7 @@ library CustomVerifier { if (verificationConfig.forbiddenCountriesEnabled) { for (uint256 i = 0; i < 4; i++) { if ( - selfricaOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i] + kycOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i] ) { revert InvalidForbiddenCountries(); } @@ -335,7 +335,7 @@ library CustomVerifier { if ( !CircuitAttributeHandlerV2.compareOlderThanNumeric( AttestationId.KYC, - selfricaOutput.revealedDataPacked, + kycOutput.revealedDataPacked, verificationConfig.olderThan ) ) { @@ -345,27 +345,27 @@ library CustomVerifier { SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput = SelfStructs.GenericDiscloseOutputV2({ attestationId: AttestationId.KYC, - userIdentifier: selfricaOutput.userIdentifier, - nullifier: selfricaOutput.nullifier, - forbiddenCountriesListPacked: selfricaOutput.forbiddenCountriesListPacked, + userIdentifier: kycOutput.userIdentifier, + nullifier: kycOutput.nullifier, + forbiddenCountriesListPacked: kycOutput.forbiddenCountriesListPacked, issuingState: "UNAVAILABLE", - name: CircuitAttributeHandlerV2.getName(AttestationId.KYC, selfricaOutput.revealedDataPacked), - idNumber: CircuitAttributeHandlerV2.getDocumentNumber(AttestationId.KYC, selfricaOutput.revealedDataPacked), - nationality: CircuitAttributeHandlerV2.getNationality(AttestationId.KYC, selfricaOutput.revealedDataPacked), + name: CircuitAttributeHandlerV2.getName(AttestationId.KYC, kycOutput.revealedDataPacked), + idNumber: CircuitAttributeHandlerV2.getDocumentNumber(AttestationId.KYC, kycOutput.revealedDataPacked), + nationality: CircuitAttributeHandlerV2.getNationality(AttestationId.KYC, kycOutput.revealedDataPacked), dateOfBirth: CircuitAttributeHandlerV2.getDateOfBirthFullYear( AttestationId.KYC, - selfricaOutput.revealedDataPacked + kycOutput.revealedDataPacked ), - gender: CircuitAttributeHandlerV2.getGender(AttestationId.KYC, selfricaOutput.revealedDataPacked), + gender: CircuitAttributeHandlerV2.getGender(AttestationId.KYC, kycOutput.revealedDataPacked), expiryDate: CircuitAttributeHandlerV2.getExpiryDateFullYear( AttestationId.KYC, - selfricaOutput.revealedDataPacked + kycOutput.revealedDataPacked ), olderThan: verificationConfig.olderThan, ofac: [ false, - CircuitAttributeHandlerV2.getNameAndDobOfac(AttestationId.KYC, selfricaOutput.revealedDataPacked), - CircuitAttributeHandlerV2.getNameAndYobOfac(AttestationId.KYC, selfricaOutput.revealedDataPacked) + CircuitAttributeHandlerV2.getNameAndDobOfac(AttestationId.KYC, kycOutput.revealedDataPacked), + CircuitAttributeHandlerV2.getNameAndYobOfac(AttestationId.KYC, kycOutput.revealedDataPacked) ] }); diff --git a/contracts/contracts/libraries/ProofVerifierLib.sol b/contracts/contracts/libraries/ProofVerifierLib.sol index 12f1bf48a..19ab02f6c 100644 --- a/contracts/contracts/libraries/ProofVerifierLib.sol +++ b/contracts/contracts/libraries/ProofVerifierLib.sol @@ -5,7 +5,7 @@ import {AttestationId} from "../constants/AttestationId.sol"; import {GenericProofStruct} from "../interfaces/IRegisterCircuitVerifier.sol"; import {IVcAndDiscloseCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol"; import {IVcAndDiscloseAadhaarCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol"; -import {IVcAndDiscloseSelfricaCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol"; +import {IVcAndDiscloseKycCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol"; /** * @title ProofVerifierLib @@ -25,7 +25,7 @@ library ProofVerifierLib { * @dev Handles different attestation types with different public signal counts: * - E_PASSPORT and EU_ID_CARD: 21 public signals * - AADHAAR: 19 public signals - * - SELFRICA_ID_CARD: 28 public signals + * - KYC: 29 public signals * @param attestationId The type of attestation being verified * @param verifierAddress The address of the verifier contract * @param vcAndDiscloseProof The proof data including public signals @@ -73,7 +73,7 @@ library ProofVerifierLib { } if ( - !IVcAndDiscloseSelfricaCircuitVerifier(verifierAddress).verifyProof( + !IVcAndDiscloseKycCircuitVerifier(verifierAddress).verifyProof( vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, diff --git a/contracts/contracts/libraries/RegisterProofVerifierLib.sol b/contracts/contracts/libraries/RegisterProofVerifierLib.sol index 8580390f8..b8eeea98d 100644 --- a/contracts/contracts/libraries/RegisterProofVerifierLib.sol +++ b/contracts/contracts/libraries/RegisterProofVerifierLib.sol @@ -6,7 +6,7 @@ import {CircuitConstantsV2} from "../constants/CircuitConstantsV2.sol"; import {GenericProofStruct} from "../interfaces/IRegisterCircuitVerifier.sol"; import {IRegisterCircuitVerifier} from "../interfaces/IRegisterCircuitVerifier.sol"; import {IAadhaarRegisterCircuitVerifier} from "../interfaces/IRegisterCircuitVerifier.sol"; -import {ISelfricaRegisterCircuitVerifier} from "../interfaces/IRegisterCircuitVerifier.sol"; +import {IKycRegisterCircuitVerifier} from "../interfaces/IRegisterCircuitVerifier.sol"; import {IIdentityRegistryV1} from "../interfaces/IIdentityRegistryV1.sol"; import {IIdentityRegistryIdCardV1} from "../interfaces/IIdentityRegistryIdCardV1.sol"; import {IIdentityRegistryAadhaarV1} from "../interfaces/IIdentityRegistryAadhaarV1.sol"; @@ -100,7 +100,7 @@ library RegisterProofVerifierLib { } else if (attestationId == AttestationId.KYC) { if ( !IIdentityRegistryKycV1(registryAddress).checkPubkeyCommitment( - registerCircuitProof.pubSignals[CircuitConstantsV2.SELFRICA_PUBKEY_COMMITMENT_INDEX] + registerCircuitProof.pubSignals[CircuitConstantsV2.KYC_PUBKEY_COMMITMENT_INDEX] ) ) { revert InvalidPubkeyCommitment(); @@ -158,7 +158,7 @@ library RegisterProofVerifierLib { registerCircuitProof.pubSignals[3] ]; if ( - !ISelfricaRegisterCircuitVerifier(verifier).verifyProof( + !IKycRegisterCircuitVerifier(verifier).verifyProof( registerCircuitProof.a, registerCircuitProof.b, registerCircuitProof.c, diff --git a/contracts/contracts/registry/IdentityRegistrySelfricaImplV1.sol b/contracts/contracts/registry/IdentityRegistryKycImplV1.sol similarity index 98% rename from contracts/contracts/registry/IdentityRegistrySelfricaImplV1.sol rename to contracts/contracts/registry/IdentityRegistryKycImplV1.sol index 33afcdb57..437925cd1 100644 --- a/contracts/contracts/registry/IdentityRegistrySelfricaImplV1.sol +++ b/contracts/contracts/registry/IdentityRegistryKycImplV1.sol @@ -32,11 +32,11 @@ import {Formatter} from "../libraries/Formatter.sol"; */ /** - * @title IdentityRegistrySelfricaStorageV1 - * @dev Abstract contract for storage layout of IdentityRegistrySelfricaImplV1. + * @title IdentityRegistryKycStorageV1 + * @dev Abstract contract for storage layout of IdentityRegistryKycImplV1. * Inherits from ImplRoot to provide upgradeable functionality. */ -abstract contract IdentityRegistrySelfricaStorageV1 is ImplRoot { +abstract contract IdentityRegistryKycStorageV1 is ImplRoot { // ============================================= // Storage Variables // ============================================= @@ -56,7 +56,7 @@ abstract contract IdentityRegistrySelfricaStorageV1 is ImplRoot { /// @notice Mapping from nullifier to a boolean indicating registration. mapping(uint256 => bool) internal _nullifiers; - /// @notice Pubkey commitments registered for Selfrica. + /// @notice Pubkey commitments registered for KYC. mapping(uint256 => bool) internal _isRegisteredPubkeyCommitment; /// @notice Current name and date of birth OFAC root. @@ -110,11 +110,11 @@ interface IPCR0Manager { } /** - * @title IdentityRegistrySelfricaImplV1 + * @title IdentityRegistryKycImplV1 * @notice Provides functions to register and manage identity commitments using a Merkle tree structure. - * @dev Inherits from IdentityRegistrySelfricaStorageV1 and implements IIdentityRegistrySelfricaV1. + * @dev Inherits from IdentityRegistryKycStorageV1 and implements IIdentityRegistryKycV1. */ -contract IdentityRegistrySelfricaImplV1 is IdentityRegistrySelfricaStorageV1, IIdentityRegistryKycV1 { +contract IdentityRegistryKycImplV1 is IdentityRegistryKycStorageV1, IIdentityRegistryKycV1 { using InternalLeanIMT for LeanIMTData; // ==================================================== diff --git a/contracts/ignition/modules/hub/deployHubV2.ts b/contracts/ignition/modules/hub/deployHubV2.ts index 77bd91edf..48c54e777 100644 --- a/contracts/ignition/modules/hub/deployHubV2.ts +++ b/contracts/ignition/modules/hub/deployHubV2.ts @@ -38,7 +38,7 @@ function getHubImplV2InitializeData() { * - Verification configs via setVerificationConfigV2() * * Post-deployment configuration steps: - * 1. Set registry addresses for each attestation type (E_PASSPORT, EU_ID_CARD, AADHAAR, SELFRICA_ID_CARD) + * 1. Set registry addresses for each attestation type (E_PASSPORT, EU_ID_CARD, AADHAAR, KYC) * 2. Configure circuit verifiers for different signature types * 3. Set up verification configurations using setVerificationConfigV2() * 4. Transfer ownership to the appropriate address if needed diff --git a/contracts/test/utils/deploymentV2.ts b/contracts/test/utils/deploymentV2.ts index af92a1cfc..1607b8d1f 100644 --- a/contracts/test/utils/deploymentV2.ts +++ b/contracts/test/utils/deploymentV2.ts @@ -16,9 +16,8 @@ import RegisterVerifierArtifactLocal from "../../artifacts/contracts/verifiers/l import RegisterIdVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/register_id/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096_staging.sol/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096_staging.json"; import RegisterAadhaarVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/register/Verifier_register_aadhaar_staging.sol/Verifier_register_aadhaar_staging.json"; import DscVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/dsc/Verifier_dsc_sha256_rsa_65537_4096_staging.sol/Verifier_dsc_sha256_rsa_65537_4096_staging.json"; -import RegisterSelfricaVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/register/Verifier_register_kyc_staging.sol/Verifier_register_kyc_staging.json"; -// import GCPJWTVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/gcp_jwt_verifier/Verifier_gcp_jwt_verifier_staging.sol/Verifier_gcp_jwt_verifier_staging.json"; -import VcAndDiscloseSelfricaVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/disclose/Verifier_vc_and_disclose_kyc_staging.sol/Verifier_vc_and_disclose_kyc_staging.json"; +import RegisterKycVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/register/Verifier_register_kyc_staging.sol/Verifier_register_kyc_staging.json"; +import VcAndDiscloseKycVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/disclose/Verifier_vc_and_disclose_kyc_staging.sol/Verifier_vc_and_disclose_kyc_staging.json"; export async function deploySystemFixturesV2(): Promise { let identityVerificationHubV2: any; @@ -29,16 +28,16 @@ export async function deploySystemFixturesV2(): Promise { let identityRegistryIdImpl: any; let identityRegistryAadhaarImpl: any; let identityRegistryAadhaarProxy: any; - let identityRegistrySelfricaImpl: any; - let identityRegistrySelfricaProxy: any; + let identityRegistryKycImpl: any; + let identityRegistryKycProxy: any; let vcAndDiscloseVerifier: any; let vcAndDiscloseIdVerifier: any; let vcAndDiscloseAadhaarVerifier: any; - let vcAndDiscloseSelfricaVerifier: any; + let vcAndDiscloseKycVerifier: any; let registerVerifier: any; let registerIdVerifier: any; let registerAadhaarVerifier: any; - let registerSelfricaVerifier: any; + let registerKycVerifier: any; let dscVerifier: any; let testSelfVerificationRoot: any; let owner: HardhatEthersSigner; @@ -92,16 +91,16 @@ export async function deploySystemFixturesV2(): Promise { await vcAndDiscloseAadhaarVerifier.waitForDeployment(); } - let vcAndDiscloseSelfricaVerifierArtifact; - // Deploy VC and Disclose Selfrica verifier + let vcAndDiscloseKycVerifierArtifact; + // Deploy VC and Disclose KYC verifier { - vcAndDiscloseSelfricaVerifierArtifact = VcAndDiscloseSelfricaVerifierArtifactLocal; - const vcAndDiscloseSelfricaVerifierFactory = await ethers.getContractFactory( - vcAndDiscloseSelfricaVerifierArtifact.abi, - vcAndDiscloseSelfricaVerifierArtifact.bytecode, + vcAndDiscloseKycVerifierArtifact = VcAndDiscloseKycVerifierArtifactLocal; + const vcAndDiscloseKycVerifierFactory = await ethers.getContractFactory( + vcAndDiscloseKycVerifierArtifact.abi, + vcAndDiscloseKycVerifierArtifact.bytecode, ); - vcAndDiscloseSelfricaVerifier = await vcAndDiscloseSelfricaVerifierFactory.connect(owner).deploy(); - await vcAndDiscloseSelfricaVerifier.waitForDeployment(); + vcAndDiscloseKycVerifier = await vcAndDiscloseKycVerifierFactory.connect(owner).deploy(); + await vcAndDiscloseKycVerifier.waitForDeployment(); } // Deploy register verifier @@ -140,16 +139,16 @@ export async function deploySystemFixturesV2(): Promise { await registerAadhaarVerifier.waitForDeployment(); } - // Deploy register selfrica verifier - let registerSelfricaVerifierArtifact, registerSelfricaVerifierFactory; + // Deploy register kyc verifier + let registerKycVerifierArtifact, registerKycVerifierFactory; { - registerSelfricaVerifierArtifact = RegisterSelfricaVerifierArtifactLocal; - registerSelfricaVerifierFactory = await ethers.getContractFactory( - registerSelfricaVerifierArtifact.abi, - registerSelfricaVerifierArtifact.bytecode, + registerKycVerifierArtifact = RegisterKycVerifierArtifactLocal; + registerKycVerifierFactory = await ethers.getContractFactory( + registerKycVerifierArtifact.abi, + registerKycVerifierArtifact.bytecode, ); - registerSelfricaVerifier = await registerSelfricaVerifierFactory.connect(owner).deploy(); - await registerSelfricaVerifier.waitForDeployment(); + registerKycVerifier = await registerKycVerifierFactory.connect(owner).deploy(); + await registerKycVerifier.waitForDeployment(); } // Deploy dsc verifier @@ -257,16 +256,16 @@ export async function deploySystemFixturesV2(): Promise { await identityRegistryAadhaarImpl.waitForDeployment(); } - // Deploy IdentityRegistrySelfricaImplV1 for Selfrica - let IdentityRegistrySelfricaImplFactory; + // Deploy IdentityRegistryKycImplV1 for KYC + let IdentityRegistryKycImplFactory; { - IdentityRegistrySelfricaImplFactory = await ethers.getContractFactory("IdentityRegistrySelfricaImplV1", { + IdentityRegistryKycImplFactory = await ethers.getContractFactory("IdentityRegistryKycImplV1", { libraries: { PoseidonT3: poseidonT3.target, }, }); - identityRegistrySelfricaImpl = await IdentityRegistrySelfricaImplFactory.connect(owner).deploy(); - await identityRegistrySelfricaImpl.waitForDeployment(); + identityRegistryKycImpl = await IdentityRegistryKycImplFactory.connect(owner).deploy(); + await identityRegistryKycImpl.waitForDeployment(); } // Deploy IdentityVerificationHubImplV2 @@ -324,18 +323,18 @@ export async function deploySystemFixturesV2(): Promise { await identityRegistryAadhaarProxy.waitForDeployment(); } - // Deploy Selfrica registry with temporary hub address and local PCR0Manager - let registrySelfricaInitData, registrySelfricaProxyFactory; + // Deploy Kyc registry with temporary hub address and local PCR0Manager + let registryKycInitData, registryKycProxyFactory; { - registrySelfricaInitData = identityRegistrySelfricaImpl.interface.encodeFunctionData("initialize", [ + registryKycInitData = identityRegistryKycImpl.interface.encodeFunctionData("initialize", [ temporaryHubAddress, pcr0Manager.target, ]); - registrySelfricaProxyFactory = await ethers.getContractFactory("IdentityRegistry"); - identityRegistrySelfricaProxy = await registrySelfricaProxyFactory + registryKycProxyFactory = await ethers.getContractFactory("IdentityRegistry"); + identityRegistryKycProxy = await registryKycProxyFactory .connect(owner) - .deploy(identityRegistrySelfricaImpl.target, registrySelfricaInitData); - await identityRegistrySelfricaProxy.waitForDeployment(); + .deploy(identityRegistryKycImpl.target, registryKycInitData); + await identityRegistryKycProxy.waitForDeployment(); } // Deploy hub V2 with simple initialization (V2 has different initialization) @@ -374,17 +373,17 @@ export async function deploySystemFixturesV2(): Promise { await updateAadhaarHubTx.wait(); } - let registrySelfricaContract, updateSelfricaHubTx; + let registryKycContract, updateKycHubTx; { - registrySelfricaContract = await ethers.getContractAt( - "IdentityRegistrySelfricaImplV1", - identityRegistrySelfricaProxy.target, + registryKycContract = await ethers.getContractAt( + "IdentityRegistryKycImplV1", + identityRegistryKycProxy.target, ); - updateSelfricaHubTx = await registrySelfricaContract.updateHub(identityVerificationHubV2.target); - await updateSelfricaHubTx.wait(); + updateKycHubTx = await registryKycContract.updateHub(identityVerificationHubV2.target); + await updateKycHubTx.wait(); - // Configure GCP JWT verifier for Selfrica - await registrySelfricaContract.updateGCPJWTVerifier(gcpJwtVerifier.target); + // Configure GCP JWT verifier for Kyc + await registryKycContract.updateGCPJWTVerifier(gcpJwtVerifier.target); } let hubContract; @@ -412,8 +411,8 @@ export async function deploySystemFixturesV2(): Promise { nameAndYob_smt, nameDobAadhar_smt, nameYobAadhar_smt, - nameAndDob_selfrica_smt, - nameAndYob_selfrica_smt, + nameAndDob_kyc_smt, + nameAndYob_kyc_smt, } = getSMTs(); // Update passport roots @@ -429,27 +428,27 @@ export async function deploySystemFixturesV2(): Promise { await registryAadhaarContract.updateNameAndDobOfacRoot(nameDobAadhar_smt.root, { from: owner }); await registryAadhaarContract.updateNameAndYobOfacRoot(nameYobAadhar_smt.root, { from: owner }); - // Update Selfrica roots - await registrySelfricaContract.updateNameAndDobOfacRoot(nameAndDob_selfrica_smt.root, { from: owner }); - await registrySelfricaContract.updateNameAndYobOfacRoot(nameAndYob_selfrica_smt.root, { from: owner }); + // Update Kyc roots + await registryKycContract.updateNameAndDobOfacRoot(nameAndDob_kyc_smt.root, { from: owner }); + await registryKycContract.updateNameAndYobOfacRoot(nameAndYob_kyc_smt.root, { from: owner }); // Register verifiers with the hub const E_PASSPORT = ethers.hexlify(ethers.zeroPadValue(ethers.toBeHex(1), 32)); const EU_ID_CARD = ethers.hexlify(ethers.zeroPadValue(ethers.toBeHex(2), 32)); const AADHAAR = ethers.hexlify(ethers.zeroPadValue(ethers.toBeHex(3), 32)); - const SELFRICA = ethers.hexlify(ethers.zeroPadValue(ethers.toBeHex(4), 32)); + const Kyc = ethers.hexlify(ethers.zeroPadValue(ethers.toBeHex(4), 32)); // Update registries in the hub await hubContract.updateRegistry(E_PASSPORT, identityRegistryProxy.target); await hubContract.updateRegistry(EU_ID_CARD, identityRegistryIdProxy.target); await hubContract.updateRegistry(AADHAAR, identityRegistryAadhaarProxy.target); - await hubContract.updateRegistry(SELFRICA, identityRegistrySelfricaProxy.target); + await hubContract.updateRegistry(Kyc, identityRegistryKycProxy.target); // Update VC and Disclose verifiers await hubContract.updateVcAndDiscloseCircuit(E_PASSPORT, vcAndDiscloseVerifier.target); await hubContract.updateVcAndDiscloseCircuit(EU_ID_CARD, vcAndDiscloseIdVerifier.target); await hubContract.updateVcAndDiscloseCircuit(AADHAAR, vcAndDiscloseAadhaarVerifier.target); - await hubContract.updateVcAndDiscloseCircuit(SELFRICA, vcAndDiscloseSelfricaVerifier.target); + await hubContract.updateVcAndDiscloseCircuit(Kyc, vcAndDiscloseKycVerifier.target); // Update register verifiers await hubContract.updateRegisterCircuitVerifier( @@ -463,7 +462,7 @@ export async function deploySystemFixturesV2(): Promise { registerIdVerifier.target, ); await hubContract.updateRegisterCircuitVerifier(AADHAAR, 0, registerAadhaarVerifier.target); - await hubContract.updateRegisterCircuitVerifier(SELFRICA, 0, registerSelfricaVerifier.target); + await hubContract.updateRegisterCircuitVerifier(Kyc, 0, registerKycVerifier.target); // Update DSC verifiers await hubContract.updateDscVerifier(E_PASSPORT, DscVerifierId.dsc_sha256_rsa_65537_4096, dscVerifier.target); @@ -487,12 +486,12 @@ export async function deploySystemFixturesV2(): Promise { registryId: registryIdContract, registryAadhaarImpl: identityRegistryAadhaarImpl, registryAadhaar: registryAadhaarContract, - registrySelfrica: registrySelfricaContract, - registrySelfricaImpl: identityRegistrySelfricaImpl, + registryKyc: registryKycContract, + registryKycImpl: identityRegistryKycImpl, vcAndDisclose: vcAndDiscloseVerifier, vcAndDiscloseId: vcAndDiscloseIdVerifier, vcAndDiscloseAadhaar: vcAndDiscloseAadhaarVerifier, - vcAndDiscloseSelfrica: vcAndDiscloseSelfricaVerifier, + vcAndDiscloseKyc: vcAndDiscloseKycVerifier, aadhaarPubkey: aadhaarPubkeyCommitment, register: registerVerifier, registerId: RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096, diff --git a/contracts/test/utils/generateProof.ts b/contracts/test/utils/generateProof.ts index b1c6715f4..e41022a41 100644 --- a/contracts/test/utils/generateProof.ts +++ b/contracts/test/utils/generateProof.ts @@ -86,8 +86,8 @@ const vcAndDiscloseCircuitsAadhaar: CircuitArtifacts = { }, }; -const vcAndDiscloseCircuitsSelfrica: CircuitArtifacts = { - vc_and_disclose_selfrica: { +const vcAndDiscloseCircuitsKyc: CircuitArtifacts = { + vc_and_disclose_kyc: { wasm: "../circuits/build/disclose/vc_and_disclose_kyc/vc_and_disclose_kyc_js/vc_and_disclose_kyc.wasm", zkey: "../circuits/build/disclose/vc_and_disclose_kyc/vc_and_disclose_kyc_final.zkey", vkey: "../circuits/build/disclose/vc_and_disclose_kyc/vc_and_disclose_kyc_vkey.json", @@ -206,7 +206,7 @@ export async function generateRegisterAadhaarProof( return fixedProof; } -export async function generateRegisterSelfricaProof( +export async function generateRegisterKycProof( secret: string, //return type of prepareAadhaarTestData inputs: Awaited>, @@ -529,11 +529,11 @@ export async function generateVcAndDiscloseAadhaarProof( return fixedProof; } -export async function generateVcAndDiscloseSelfricaProof( +export async function generateVcAndDiscloseKycProof( inputs: ReturnType, ): Promise { - const circuitName = "vc_and_disclose_selfrica"; - const circuitArtifacts = vcAndDiscloseCircuitsSelfrica; + const circuitName = "vc_and_disclose_kyc"; + const circuitArtifacts = vcAndDiscloseCircuitsKyc; const artifactKey = circuitName; const vcAndDiscloseProof = await groth16.fullProve( @@ -545,7 +545,7 @@ export async function generateVcAndDiscloseSelfricaProof( const vKey = JSON.parse(fs.readFileSync(circuitArtifacts[artifactKey].vkey, "utf8")); const isValid = await groth16.verify(vKey, vcAndDiscloseProof.publicSignals, vcAndDiscloseProof.proof); if (!isValid) { - throw new Error("Generated VC and Disclose Selfrica proof verification failed"); + throw new Error("Generated VC and Disclose KYC proof verification failed"); } const rawCallData = await groth16.exportSolidityCallData(vcAndDiscloseProof.proof, vcAndDiscloseProof.publicSignals); @@ -589,11 +589,11 @@ export function getSMTs() { ) as typeof SMT; const nameAndDob_id_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndDobSMT_ID.json") as typeof SMT; const nameAndYob_id_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndYobSMT_ID.json") as typeof SMT; - const nameAndDob_selfrica_smt = importSMTFromJsonFile( - "../circuits/tests/consts/ofac/nameAndDobSelfricaSMT.json", + const nameAndDob_kyc_smt = importSMTFromJsonFile( + "../circuits/tests/consts/ofac/nameAndDobKycSMT.json", ) as typeof SMT; - const nameAndYob_selfrica_smt = importSMTFromJsonFile( - "../circuits/tests/consts/ofac/nameAndYobSelfricaSMT.json", + const nameAndYob_kyc_smt = importSMTFromJsonFile( + "../circuits/tests/consts/ofac/nameAndYobKycSMT.json", ) as typeof SMT; return { @@ -604,8 +604,8 @@ export function getSMTs() { nameAndYob_id_smt, nameDobAadhar_smt, nameYobAadhar_smt, - nameAndDob_selfrica_smt, - nameAndYob_selfrica_smt, + nameAndDob_kyc_smt, + nameAndYob_kyc_smt, }; } diff --git a/contracts/test/utils/types.ts b/contracts/test/utils/types.ts index 8a12ae945..497069397 100644 --- a/contracts/test/utils/types.ts +++ b/contracts/test/utils/types.ts @@ -10,12 +10,11 @@ import { IdentityRegistry, IdentityRegistryImplV1, IdentityRegistryIdCardImplV1, - IdentityRegistrySelfricaImplV1, TestSelfVerificationRoot, Verifier_vc_and_disclose_staging as LocalVerifier, Verifier_vc_and_disclose_id_staging as LocalIdCardVerifier, Verifier_vc_and_disclose_aadhaar_staging as LocalAadhaarVerifier, - Verifier_vc_and_disclose_selfrica_staging as LocalSelfricaVerifier, + Verifier_vc_and_disclose_kyc_staging as LocalKycVerifier, Verifier_vc_and_disclose as ProdVerifier, Verifier_vc_and_disclose_id as ProdIdCardVerifier, Verifier_register_sha256_sha256_sha256_rsa_65537_4096 as ProdRegisterVerifier, @@ -25,7 +24,7 @@ import { Verifier_dsc_sha256_rsa_65537_4096 as ProdDscVerifier, Verifier_dsc_sha256_rsa_65537_4096_staging as LocalDscVerifier, IIdentityVerificationHubV1, - IVcAndDiscloseSelfricaCircuitVerifier, + IVcAndDiscloseKycCircuitVerifier, IVcAndDiscloseAadhaarCircuitVerifier, IIdentityVerificationHubV2, IIdentityRegistryIdCardV1, @@ -35,6 +34,7 @@ import { IVcAndDiscloseCircuitVerifier, IdentityRegistryAadhaarImplV1, PCR0Manager, + IdentityRegistryKycImplV1, } from "../../typechain-types"; import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common"; @@ -82,11 +82,11 @@ export interface DeployedActorsV2 { registryId: IdentityRegistryIdCardImplV1; registryAadhaarImpl: IdentityRegistryAadhaarImplV1; registryAadhaar: IdentityRegistryAadhaarImplV1; - registrySelfrica: IdentityRegistrySelfricaImplV1; - registrySelfricaImpl: IdentityRegistrySelfricaImplV1; + registryKyc: IdentityRegistryKycImplV1; + registryKycImpl: IdentityRegistryKycImplV1; vcAndDisclose: VcAndDiscloseVerifier; vcAndDiscloseAadhaar: LocalAadhaarVerifier; - vcAndDiscloseSelfrica: LocalSelfricaVerifier; + vcAndDiscloseKyc: LocalKycVerifier; aadhaarPubkey: bigint; vcAndDiscloseId: VcAndDiscloseIdVerifier; register: RegisterVerifier; diff --git a/contracts/test/v2/discloseKyc.test.ts b/contracts/test/v2/discloseKyc.test.ts index 709ee81e5..18b141065 100644 --- a/contracts/test/v2/discloseKyc.test.ts +++ b/contracts/test/v2/discloseKyc.test.ts @@ -14,15 +14,15 @@ import { generateKycDiscloseInput } from "@selfxyz/common"; import { getSMTs } from "../utils/generateProof"; import { getPackedForbiddenCountries } from "@selfxyz/common/utils/contracts/forbiddenCountries"; import { BigNumberish } from "ethers"; -import { generateVcAndDiscloseSelfricaProof } from "../utils/generateProof"; +import { generateVcAndDiscloseKycProof } from "../utils/generateProof"; import { KYC_ATTESTATION_ID } from "@selfxyz/common/constants/constants"; import { poseidon2 } from "poseidon-lite"; -// Selfrica circuit indices - matches CircuitConstantsV2.getDiscloseIndices(SELFRICA_ID_CARD) +// KYC circuit indices - matches CircuitConstantsV2.getDiscloseIndices(KYC_ID_CARD) // See CircuitConstantsV2.sol for full layout documentation -const SELFRICA_CURRENT_DATE_INDEX = 21; +const KYC_CURRENT_DATE_INDEX = 21; -describe("Self Verification Flow V2 - Selfrica", () => { +describe("Self Verification Flow V2 - KYC", () => { let deployedActors: DeployedActorsV2; let snapshotId: string; let nullifier: any; @@ -51,8 +51,8 @@ describe("Self Verification Flow V2 - Selfrica", () => { const userData = "test-user-data-for-verification"; userIdentifierHash = BigInt(calculateUserIdentifierHash(destChainId, user1Address.slice(2), userData).toString()); - nameAndDob_smt = getSMTs().nameAndDob_selfrica_smt; - nameAndYob_smt = getSMTs().nameAndYob_selfrica_smt; + nameAndDob_smt = getSMTs().nameAndDob_kyc_smt; + nameAndYob_smt = getSMTs().nameAndYob_kyc_smt; const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); @@ -78,7 +78,7 @@ describe("Self Verification Flow V2 - Selfrica", () => { nullifier = packBytesAndPoseidon(nullifier); const commitment = poseidon2([BigInt(testInputs.secret), packBytesAndPoseidon(dataPadded)]); - await deployedActors.registrySelfrica.devAddIdentityCommitment(nullifier, commitment); + await deployedActors.registryKyc.devAddIdentityCommitment(nullifier, commitment); forbiddenCountriesList = [] as Country3LetterCode[]; forbiddenCountriesListPacked = getPackedForbiddenCountries(forbiddenCountriesList); @@ -97,7 +97,7 @@ describe("Self Verification Flow V2 - Selfrica", () => { }; await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); - baseVcAndDiscloseProof = await generateVcAndDiscloseSelfricaProof(testInputs); + baseVcAndDiscloseProof = await generateVcAndDiscloseKycProof(testInputs); snapshotId = await ethers.provider.send("evm_snapshot", []); }); @@ -302,7 +302,7 @@ describe("Self Verification Flow V2 - Selfrica", () => { const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(KYC_ATTESTATION_ID)), 32); const clonedPubSignal = structuredClone(baseVcAndDiscloseProof.pubSignals); - // scopeIndex for Selfrica is 16 + // scopeIndex for KYC is 16 clonedPubSignal[16] = 1n; const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( @@ -348,7 +348,7 @@ describe("Self Verification Flow V2 - Selfrica", () => { const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(KYC_ATTESTATION_ID)), 32); const clonedPubSignal = structuredClone(baseVcAndDiscloseProof.pubSignals); - // userIdentifierIndex for Selfrica is 20 + // userIdentifierIndex for KYC is 20 clonedPubSignal[20] = 1n; const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( @@ -395,8 +395,8 @@ describe("Self Verification Flow V2 - Selfrica", () => { const clonedPubSignal = structuredClone(baseVcAndDiscloseProof.pubSignals); // Modify current date at the correct index using BigInt for safe arithmetic - const currentDateValue = BigInt(clonedPubSignal[SELFRICA_CURRENT_DATE_INDEX]); - clonedPubSignal[SELFRICA_CURRENT_DATE_INDEX] = (currentDateValue + 2n).toString(); + const currentDateValue = BigInt(clonedPubSignal[KYC_CURRENT_DATE_INDEX]); + clonedPubSignal[KYC_CURRENT_DATE_INDEX] = (currentDateValue + 2n).toString(); const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[] pubSignals)"], @@ -443,8 +443,8 @@ describe("Self Verification Flow V2 - Selfrica", () => { const clonedPubSignal = structuredClone(baseVcAndDiscloseProof.pubSignals); // Modify current date at the correct index using BigInt for safe arithmetic - const currentDateValue = BigInt(clonedPubSignal[SELFRICA_CURRENT_DATE_INDEX]); - clonedPubSignal[SELFRICA_CURRENT_DATE_INDEX] = (currentDateValue - 1n).toString(); + const currentDateValue = BigInt(clonedPubSignal[KYC_CURRENT_DATE_INDEX]); + clonedPubSignal[KYC_CURRENT_DATE_INDEX] = (currentDateValue - 1n).toString(); const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[] pubSignals)"], @@ -733,7 +733,7 @@ describe("Self Verification Flow V2 - Selfrica", () => { KYC_ATTESTATION_ID, ); - const newProof = await generateVcAndDiscloseSelfricaProof(inputs); + const newProof = await generateVcAndDiscloseKycProof(inputs); const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(KYC_ATTESTATION_ID)), 32); const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[] pubSignals)"], diff --git a/contracts/test/v2/registerKyc.test.ts b/contracts/test/v2/registerKyc.test.ts index 3596a524d..e40eecb80 100644 --- a/contracts/test/v2/registerKyc.test.ts +++ b/contracts/test/v2/registerKyc.test.ts @@ -3,7 +3,7 @@ import { deploySystemFixturesV2 } from "../utils/deploymentV2"; import { DeployedActorsV2 } from "../utils/types"; import { KYC_ATTESTATION_ID } from "@selfxyz/common/constants/constants"; import { generateMockKycRegisterInput } from "@selfxyz/common/utils/kyc/generateInputs"; -import { generateRegisterSelfricaProof } from "../utils/generateProof"; +import { generateRegisterKycProof } from "../utils/generateProof"; import { expect } from "chai"; function getCurrentDateDigitsYYMMDDHHMMSS(hoursOffset: number = 0): bigint[] { @@ -46,7 +46,7 @@ function packUint256ToHexFields(value: bigint): [bigint, bigint, bigint] { return [p0, p1, p2]; } -describe("Selfrica Registration test", function () { +describe("KYC Registration test", function () { this.timeout(0); let deployedActors: DeployedActorsV2; @@ -60,10 +60,10 @@ describe("Selfrica Registration test", function () { attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(KYC_ATTESTATION_ID)), 32); // Set the owner as the TEE for all tests - await deployedActors.registrySelfrica.updateTEE(await deployedActors.owner.getAddress()); + await deployedActors.registryKyc.updateTEE(await deployedActors.owner.getAddress()); // Set the GCP root CA pubkey hash - await deployedActors.registrySelfrica.updateGCPRootCAPubkeyHash(GCP_ROOT_CA_PUBKEY_HASH); + await deployedActors.registryKyc.updateGCPRootCAPubkeyHash(GCP_ROOT_CA_PUBKEY_HASH); console.log("🎉 System deployment and initial setup completed!"); }); @@ -77,7 +77,7 @@ describe("Selfrica Registration test", function () { }); describe("Identity Commitment", () => { - let selfricaData: any; + let kycData: any; let registerProof: any; let registerSecret: string; let mockVerifier: any; @@ -87,14 +87,14 @@ describe("Selfrica Registration test", function () { before(async () => { registerSecret = "12345"; - selfricaData = await generateMockKycRegisterInput(undefined, true, registerSecret); - registerProof = await generateRegisterSelfricaProof(registerSecret, selfricaData); + kycData = await generateMockKycRegisterInput(undefined, true, registerSecret); + registerProof = await generateRegisterKycProof(registerSecret, kycData); // Deploy and set mock GCP JWT verifier const MockVerifierFactory = await ethers.getContractFactory("MockGCPJWTVerifier"); mockVerifier = await MockVerifierFactory.deploy(); await mockVerifier.waitForDeployment(); - await deployedActors.registrySelfrica.updateGCPJWTVerifier(mockVerifier.target); + await deployedActors.registryKyc.updateGCPJWTVerifier(mockVerifier.target); // Get the pubkey commitment from the register proof and pack as hex const pubkeyCommitment = registerProof.pubSignals[registerProof.pubSignals.length - 2]; @@ -145,7 +145,7 @@ describe("Selfrica Registration test", function () { }); it("should successfully register an identity commitment", async () => { - await deployedActors.registrySelfrica.registerPubkeyCommitment( + await deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, @@ -153,11 +153,11 @@ describe("Selfrica Registration test", function () { ); await expect(deployedActors.hub.registerCommitment(attestationIdBytes32, 0n, registerProof)).to.emit( - deployedActors.registrySelfrica, + deployedActors.registryKyc, "CommitmentRegistered", ); - const isRegistered = await deployedActors.registrySelfrica.nullifiers(registerProof.pubSignals[0]); + const isRegistered = await deployedActors.registryKyc.nullifiers(registerProof.pubSignals[0]); expect(isRegistered).to.be.true; }); @@ -168,7 +168,7 @@ describe("Selfrica Registration test", function () { }); it("should not register an identity commitment if the proof is invalid", async () => { - await deployedActors.registrySelfrica.registerPubkeyCommitment( + await deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, @@ -229,21 +229,21 @@ describe("Selfrica Registration test", function () { }; it("should have correct GCP root CA pubkey hash", async () => { - const contractHash = await deployedActors.registrySelfrica.gcpRootCAPubkeyHash(); + const contractHash = await deployedActors.registryKyc.gcpRootCAPubkeyHash(); expect(contractHash).to.equal(GCP_ROOT_CA_PUBKEY_HASH); }); it("should allow owner to update GCP root CA pubkey hash", async () => { const newHash = 12345n; - await deployedActors.registrySelfrica.updateGCPRootCAPubkeyHash(newHash); - const contractHash = await deployedActors.registrySelfrica.gcpRootCAPubkeyHash(); + await deployedActors.registryKyc.updateGCPRootCAPubkeyHash(newHash); + const contractHash = await deployedActors.registryKyc.gcpRootCAPubkeyHash(); expect(contractHash).to.equal(newHash); }); it("should not allow non-owner to update GCP root CA pubkey hash", async () => { await expect( - deployedActors.registrySelfrica.connect(deployedActors.user1).updateGCPRootCAPubkeyHash(12345n), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "AccessControlUnauthorizedAccount"); + deployedActors.registryKyc.connect(deployedActors.user1).updateGCPRootCAPubkeyHash(12345n), + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "AccessControlUnauthorizedAccount"); }); it("should fail with INVALID_IMAGE when image hash not in PCR0Manager", async () => { @@ -259,21 +259,21 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_IMAGE"); + deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_IMAGE"); }); it("should not allow non-owner to update GCP JWT verifier", async () => { await expect( - deployedActors.registrySelfrica + deployedActors.registryKyc .connect(deployedActors.user1) .updateGCPJWTVerifier(ethers.Wallet.createRandom().address), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "AccessControlUnauthorizedAccount"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "AccessControlUnauthorizedAccount"); }); it("should allow owner to update GCP JWT verifier", async () => { const newVerifier = ethers.Wallet.createRandom().address; - await deployedActors.registrySelfrica.updateGCPJWTVerifier(newVerifier); + await deployedActors.registryKyc.updateGCPJWTVerifier(newVerifier); }); describe("TEE Access Control", () => { @@ -290,28 +290,28 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica + deployedActors.registryKyc .connect(deployedActors.user1) .registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "ONLY_TEE_CAN_ACCESS"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "ONLY_TEE_CAN_ACCESS"); }); it("should not allow non-owner to update TEE", async () => { await expect( - deployedActors.registrySelfrica.connect(deployedActors.user1).updateTEE(ethers.Wallet.createRandom().address), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "AccessControlUnauthorizedAccount"); + deployedActors.registryKyc.connect(deployedActors.user1).updateTEE(ethers.Wallet.createRandom().address), + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "AccessControlUnauthorizedAccount"); }); it("should allow owner to update TEE", async () => { const newTee = ethers.Wallet.createRandom().address; - await deployedActors.registrySelfrica.updateTEE(newTee); - expect(await deployedActors.registrySelfrica.tee()).to.equal(newTee); + await deployedActors.registryKyc.updateTEE(newTee); + expect(await deployedActors.registryKyc.tee()).to.equal(newTee); }); it("should fail with TEE_NOT_SET when TEE address is zero", async () => { // Deploy minimal fresh registry to test uninitialized TEE state const freshImpl = await ( - await ethers.getContractFactory("IdentityRegistrySelfricaImplV1", { + await ethers.getContractFactory("IdentityRegistryKycImplV1", { libraries: { PoseidonT3: deployedActors.poseidonT3.target }, }) ).deploy(); @@ -324,7 +324,7 @@ describe("Selfrica Registration test", function () { await ethers.getContractFactory("IdentityRegistry") ).deploy(freshImpl.target, initData); - const freshRegistry = await ethers.getContractAt("IdentityRegistrySelfricaImplV1", freshProxy.target); + const freshRegistry = await ethers.getContractAt("IdentityRegistryKycImplV1", freshProxy.target); await freshRegistry.updateGCPJWTVerifier(deployedActors.gcpJwtVerifier.target); const mockPubSignals: bigint[] = [ @@ -373,13 +373,13 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment( + deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, mockPubSignalsPast, ), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_TIMESTAMP"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_TIMESTAMP"); // Create a timestamp 2 hours in the future (more than 1 hour threshold) const nextHourDate = getCurrentDateDigitsYYMMDDHHMMSS(2); @@ -396,13 +396,13 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment( + deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, mockPubSignalsFuture, ), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_TIMESTAMP"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_TIMESTAMP"); }); }); @@ -413,7 +413,7 @@ describe("Selfrica Registration test", function () { const MockVerifierFactory = await ethers.getContractFactory("MockGCPJWTVerifier"); mockVerifier = await MockVerifierFactory.deploy(); await mockVerifier.waitForDeployment(); - await deployedActors.registrySelfrica.updateGCPJWTVerifier(mockVerifier.target); + await deployedActors.registryKyc.updateGCPJWTVerifier(mockVerifier.target); }); afterEach(async () => { @@ -434,13 +434,13 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment( + deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, mockPubSignals, ), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_PROOF"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_PROOF"); }); it("should fail with INVALID_ROOT_CA when root CA hash does not match", async () => { @@ -456,13 +456,13 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment( + deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, mockPubSignals, ), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_ROOT_CA"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_ROOT_CA"); }); it("should fail with INVALID_IMAGE when image hash not in PCR0Manager", async () => { @@ -478,13 +478,13 @@ describe("Selfrica Registration test", function () { ]; await expect( - deployedActors.registrySelfrica.registerPubkeyCommitment( + deployedActors.registryKyc.registerPubkeyCommitment( mockProof.a, mockProof.b, mockProof.c, mockPubSignals, ), - ).to.be.revertedWithCustomError(deployedActors.registrySelfrica, "INVALID_IMAGE"); + ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_IMAGE"); }); }); }); From 8da076cf0d0a8e798d36de2927c4bcbca41d1d4f Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Wed, 28 Jan 2026 12:47:32 -0800 Subject: [PATCH 3/6] Bump Babel, TypeScript, React Native and assorted dependencies; refresh lockfile (#1606) * Update dependency versions * Fix gesture handler Android dependency (#1611) * Patch screens codegen type (#1609) * Downgrade Sentry React Native (#1612) * fix patches and packages * downgrade versions for gesture handler and screens * agent feedback * fix ios building * allow ios tets to pass * formatting * make cache more resilient * Address CodeRabbitAI review comments This commit addresses all 7 unresolved CodeRabbitAI comments on PR #1606: Patch-package error handling (comments #1, #2, #3): - stderr capture already implemented in both root and workspace patch runs - Add CI warning when patches fail silently instead of exiting with 0 - Log completion status in CI mode for visibility Critical Mixpanel dependency fix (comment #5): - Add explicit Mixpanel-swift pod declaration to fix E2E build failures - Ensures Mixpanel is available even when NFCPassportReader is skipped during E2E testing React-native-web validation (comment #4): - Verified no usage of deprecated findNodeHandle, pointerEvents: 'box-none', or createPortal - Safe to upgrade from 0.19 to 0.21.2 CI workflow improvements (comments #6, #7): - Create cache-sdk-build composite action for consistent SDK build artifact caching - Replace all direct actions/cache@v4 usage with cache-yarn composite action - Replace all direct actions/cache/restore@v4 and save@v4 with cache-sdk-build - Add nested require() validation step before tests to fail fast on problematic patterns All changes follow repository coding guidelines for CI caching and test memory optimization. * Extend cache composite actions to all SDK workflows This commit extends the caching standardization from PR #1606 to include mobile-sdk-ci.yml and core-sdk-ci.yml workflows. New composite actions created: - cache-mobile-sdk-build: For mobile SDK build artifacts - cache-core-sdk-build: For core SDK build artifacts Workflow updates: - mobile-sdk-ci.yml: Replaced 5 instances of direct actions/cache with cache-mobile-sdk-build - core-sdk-ci.yml: Replaced 4 instances of direct actions/cache with cache-core-sdk-build All SDK CI workflows now use consistent caching patterns via composite actions, following the AGENTS.md guideline: "Use shared composite actions from .github/actions for CI caching instead of calling actions/cache directly." Benefits: - Consistent caching across all SDK workflows (qrcode, mobile, core) - Centralized cache configuration - easier to maintain - Follows established patterns from qrcode-sdk-ci.yml * downgrade react-native-svg * update pod lock file * sort --- .../actions/cache-core-sdk-build/action.yml | 47 + .../actions/cache-mobile-sdk-build/action.yml | 47 + .github/actions/cache-sdk-build/action.yml | 43 + .github/workflows/core-sdk-ci.yml | 65 +- .github/workflows/mobile-sdk-ci.yml | 87 +- .github/workflows/qrcode-sdk-ci.yml | 99 +- app/ios/PassportReader.swift | 2 +- app/ios/Podfile | 7 +- app/ios/Podfile.lock | 28 +- app/ios/SelfAnalytics.swift | 2 +- app/package.json | 55 +- circuits/package.json | 7 +- common/package.json | 8 +- .../contracts/libraries/CustomVerifier.sol | 4 +- contracts/test/utils/deploymentV2.ts | 5 +- contracts/test/utils/generateProof.ts | 8 +- contracts/test/v2/registerKyc.test.ts | 35 +- package.json | 11 +- packages/mobile-sdk-alpha/package.json | 17 +- packages/mobile-sdk-demo/package.json | 14 +- ...react-native-mobilesdk-module+1.40.2.patch | 8 +- patches/ethereum-cryptography+2.2.1.patch | 44 - .../react-native-gesture-handler+2.30.0.patch | 15 + patches/react-native-svg+15.14.0.patch | 98 -- scripts/run-patch-package.cjs | 89 +- sdk/core/package.json | 4 +- sdk/qrcode-angular/package.json | 4 +- sdk/qrcode/package.json | 6 +- sdk/sdk-common/package.json | 2 +- yarn.lock | 932 +++++++++++++----- 30 files changed, 1143 insertions(+), 650 deletions(-) create mode 100644 .github/actions/cache-core-sdk-build/action.yml create mode 100644 .github/actions/cache-mobile-sdk-build/action.yml create mode 100644 .github/actions/cache-sdk-build/action.yml delete mode 100644 patches/ethereum-cryptography+2.2.1.patch create mode 100644 patches/react-native-gesture-handler+2.30.0.patch delete mode 100644 patches/react-native-svg+15.14.0.patch diff --git a/.github/actions/cache-core-sdk-build/action.yml b/.github/actions/cache-core-sdk-build/action.yml new file mode 100644 index 000000000..b4f9a7317 --- /dev/null +++ b/.github/actions/cache-core-sdk-build/action.yml @@ -0,0 +1,47 @@ +name: Cache Core SDK Build +description: Cache core SDK build artifacts (common, sdk/core) + +inputs: + mode: + description: "save or restore" + required: true + cache-version: + description: Cache version string + required: false + default: v1 + fail-on-cache-miss: + description: Fail if cache not found (restore mode only) + required: false + default: "false" + +outputs: + cache-hit: + description: Whether cache was hit + value: ${{ steps.restore.outputs.cache-hit }} + +runs: + using: composite + steps: + - id: restore + if: inputs.mode == 'restore' + uses: actions/cache/restore@v4 + with: + path: | + common/dist + sdk/core/dist + node_modules + sdk/core/node_modules + common/node_modules + key: core-sdk-build-${{ inputs.cache-version }}-${{ github.sha }} + fail-on-cache-miss: ${{ inputs.fail-on-cache-miss }} + - id: save + if: inputs.mode == 'save' + uses: actions/cache/save@v4 + with: + path: | + common/dist + sdk/core/dist + node_modules + sdk/core/node_modules + common/node_modules + key: core-sdk-build-${{ inputs.cache-version }}-${{ github.sha }} diff --git a/.github/actions/cache-mobile-sdk-build/action.yml b/.github/actions/cache-mobile-sdk-build/action.yml new file mode 100644 index 000000000..e7aa6db18 --- /dev/null +++ b/.github/actions/cache-mobile-sdk-build/action.yml @@ -0,0 +1,47 @@ +name: Cache Mobile SDK Build +description: Cache mobile SDK build artifacts (common, mobile-sdk-alpha) + +inputs: + mode: + description: "save or restore" + required: true + cache-version: + description: Cache version string + required: false + default: v1 + fail-on-cache-miss: + description: Fail if cache not found (restore mode only) + required: false + default: "false" + +outputs: + cache-hit: + description: Whether cache was hit + value: ${{ steps.restore.outputs.cache-hit }} + +runs: + using: composite + steps: + - id: restore + if: inputs.mode == 'restore' + uses: actions/cache/restore@v4 + with: + path: | + common/dist + packages/mobile-sdk-alpha/dist + node_modules + packages/mobile-sdk-alpha/node_modules + common/node_modules + key: mobile-sdk-alpha-build-${{ inputs.cache-version }}-${{ github.sha }} + fail-on-cache-miss: ${{ inputs.fail-on-cache-miss }} + - id: save + if: inputs.mode == 'save' + uses: actions/cache/save@v4 + with: + path: | + common/dist + packages/mobile-sdk-alpha/dist + node_modules + packages/mobile-sdk-alpha/node_modules + common/node_modules + key: mobile-sdk-alpha-build-${{ inputs.cache-version }}-${{ github.sha }} diff --git a/.github/actions/cache-sdk-build/action.yml b/.github/actions/cache-sdk-build/action.yml new file mode 100644 index 000000000..16305276f --- /dev/null +++ b/.github/actions/cache-sdk-build/action.yml @@ -0,0 +1,43 @@ +name: Cache SDK Build +description: Cache SDK build artifacts (common, sdk-common, qrcode) + +inputs: + mode: + description: "save or restore" + required: true + cache-version: + description: Cache version string + required: false + default: v1 + fail-on-cache-miss: + description: Fail if cache not found (restore mode only) + required: false + default: "false" + +outputs: + cache-hit: + description: Whether cache was hit + value: ${{ steps.restore.outputs.cache-hit }} + +runs: + using: composite + steps: + - id: restore + if: inputs.mode == 'restore' + uses: actions/cache/restore@v4 + with: + path: | + common/dist + sdk/sdk-common/dist + sdk/qrcode/dist + key: qrcode-sdk-build-${{ inputs.cache-version }}-${{ github.sha }} + fail-on-cache-miss: ${{ inputs.fail-on-cache-miss }} + - id: save + if: inputs.mode == 'save' + uses: actions/cache/save@v4 + with: + path: | + common/dist + sdk/sdk-common/dist + sdk/qrcode/dist + key: qrcode-sdk-build-${{ inputs.cache-version }}-${{ github.sha }} diff --git a/.github/workflows/core-sdk-ci.yml b/.github/workflows/core-sdk-ci.yml index 5d9166588..2df6f4601 100644 --- a/.github/workflows/core-sdk-ci.yml +++ b/.github/workflows/core-sdk-ci.yml @@ -22,15 +22,10 @@ jobs: yarn workspace @selfxyz/common build yarn workspace @selfxyz/core build - name: Cache build artifacts - uses: actions/cache/save@v4 + uses: ./.github/actions/cache-core-sdk-build with: - path: | - common/dist - sdk/core/dist - node_modules - sdk/core/node_modules - common/node_modules - key: core-sdk-build-${{ github.sha }} + mode: save + cache-version: v1 lint: runs-on: ubuntu-latest @@ -45,19 +40,19 @@ jobs: corepack prepare yarn@4.12.0 --activate - name: Restore build artifacts id: build-cache - uses: actions/cache/restore@v4 + uses: ./.github/actions/cache-core-sdk-build with: - path: | - common/dist - sdk/core/dist - node_modules - sdk/core/node_modules - common/node_modules - key: core-sdk-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false - name: Install Dependencies if: steps.build-cache.outputs.cache-hit != 'true' uses: ./.github/actions/yarn-install + - name: Build dependencies (fallback on cache miss) + if: steps.build-cache.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/core build - name: Run linter run: yarn workspace @selfxyz/core lint @@ -74,19 +69,19 @@ jobs: corepack prepare yarn@4.12.0 --activate - name: Restore build artifacts id: build-cache - uses: actions/cache/restore@v4 + uses: ./.github/actions/cache-core-sdk-build with: - path: | - common/dist - sdk/core/dist - node_modules - sdk/core/node_modules - common/node_modules - key: core-sdk-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false - name: Install Dependencies if: steps.build-cache.outputs.cache-hit != 'true' uses: ./.github/actions/yarn-install + - name: Build dependencies (fallback on cache miss) + if: steps.build-cache.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/core build - name: Type checking run: yarn workspace @selfxyz/core types @@ -103,18 +98,18 @@ jobs: corepack prepare yarn@4.12.0 --activate - name: Restore build artifacts id: build-cache - uses: actions/cache/restore@v4 + uses: ./.github/actions/cache-core-sdk-build with: - path: | - common/dist - sdk/core/dist - node_modules - sdk/core/node_modules - common/node_modules - key: core-sdk-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false - name: Install Dependencies if: steps.build-cache.outputs.cache-hit != 'true' uses: ./.github/actions/yarn-install + - name: Build dependencies (fallback on cache miss) + if: steps.build-cache.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/core build - name: Run tests run: yarn workspace @selfxyz/core test diff --git a/.github/workflows/mobile-sdk-ci.yml b/.github/workflows/mobile-sdk-ci.yml index e39e94407..2f8498952 100644 --- a/.github/workflows/mobile-sdk-ci.yml +++ b/.github/workflows/mobile-sdk-ci.yml @@ -21,15 +21,10 @@ jobs: yarn workspace @selfxyz/common build yarn workspace @selfxyz/mobile-sdk-alpha build - name: Cache build artifacts - uses: actions/cache/save@v4 + uses: ./.github/actions/cache-mobile-sdk-build with: - path: | - common/dist - packages/mobile-sdk-alpha/dist - node_modules - packages/mobile-sdk-alpha/node_modules - common/node_modules - key: mobile-sdk-alpha-build-${{ github.sha }} + mode: save + cache-version: v1 lint: runs-on: ubuntu-latest @@ -39,16 +34,17 @@ jobs: - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-mobile-sdk-build with: - path: | - common/dist - packages/mobile-sdk-alpha/dist - node_modules - packages/mobile-sdk-alpha/node_modules - common/node_modules - key: mobile-sdk-alpha-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/mobile-sdk-alpha build - name: Run linter run: yarn workspace @selfxyz/mobile-sdk-alpha lint @@ -60,16 +56,17 @@ jobs: - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-mobile-sdk-build with: - path: | - common/dist - packages/mobile-sdk-alpha/dist - node_modules - packages/mobile-sdk-alpha/node_modules - common/node_modules - key: mobile-sdk-alpha-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/mobile-sdk-alpha build - name: Check Prettier formatting run: yarn workspace @selfxyz/mobile-sdk-alpha prettier --check . @@ -81,16 +78,17 @@ jobs: - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-mobile-sdk-build with: - path: | - common/dist - packages/mobile-sdk-alpha/dist - node_modules - packages/mobile-sdk-alpha/node_modules - common/node_modules - key: mobile-sdk-alpha-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/mobile-sdk-alpha build - name: Type checking run: yarn workspace @selfxyz/mobile-sdk-alpha types @@ -102,15 +100,16 @@ jobs: - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-mobile-sdk-build with: - path: | - common/dist - packages/mobile-sdk-alpha/dist - node_modules - packages/mobile-sdk-alpha/node_modules - common/node_modules - key: mobile-sdk-alpha-build-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: v1 + fail-on-cache-miss: false + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/mobile-sdk-alpha build - name: Run tests run: yarn workspace @selfxyz/mobile-sdk-alpha test diff --git a/.github/workflows/qrcode-sdk-ci.yml b/.github/workflows/qrcode-sdk-ci.yml index 10202c07e..60f722bda 100644 --- a/.github/workflows/qrcode-sdk-ci.yml +++ b/.github/workflows/qrcode-sdk-ci.yml @@ -50,16 +50,14 @@ jobs: - name: Cache Yarn dependencies id: yarn-cache - uses: actions/cache@v4 + uses: ./.github/actions/cache-yarn with: path: | .yarn/cache node_modules sdk/qrcode/node_modules common/node_modules - key: ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn- + cache-version: ${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }} - name: Install Dependencies uses: ./.github/actions/yarn-install @@ -72,13 +70,10 @@ jobs: yarn workspace @selfxyz/qrcode build - name: Cache build artifacts - uses: actions/cache/save@v4 + uses: ./.github/actions/cache-sdk-build with: - path: | - common/dist - sdk/sdk-common/dist - sdk/qrcode/dist - key: qrcode-sdk-build-${{ env.GH_SDK_CACHE_VERSION }}-${{ github.sha }} + mode: save + cache-version: ${{ env.GH_SDK_CACHE_VERSION }} # Quality checks job quality-checks: @@ -110,29 +105,32 @@ jobs: - name: Cache Yarn dependencies id: yarn-cache - uses: actions/cache@v4 + uses: ./.github/actions/cache-yarn with: path: | .yarn/cache node_modules sdk/qrcode/node_modules common/node_modules - key: ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn- + cache-version: ${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }} - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-sdk-build with: - path: | - common/dist - sdk/sdk-common/dist - sdk/qrcode/dist - key: qrcode-sdk-build-${{ env.GH_SDK_CACHE_VERSION }}-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: ${{ env.GH_SDK_CACHE_VERSION }} + fail-on-cache-miss: false + + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/sdk-common build + yarn workspace @selfxyz/qrcode build - name: Run linter run: yarn workspace @selfxyz/qrcode lint:imports:check @@ -178,29 +176,32 @@ jobs: - name: Cache Yarn dependencies id: yarn-cache - uses: actions/cache@v4 + uses: ./.github/actions/cache-yarn with: path: | .yarn/cache node_modules sdk/qrcode/node_modules common/node_modules - key: ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn- + cache-version: ${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }} - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-sdk-build with: - path: | - common/dist - sdk/sdk-common/dist - sdk/qrcode/dist - key: qrcode-sdk-build-${{ env.GH_SDK_CACHE_VERSION }}-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: ${{ env.GH_SDK_CACHE_VERSION }} + fail-on-cache-miss: false + + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/sdk-common build + yarn workspace @selfxyz/qrcode build - name: Verify build artifacts run: | @@ -240,29 +241,41 @@ jobs: - name: Cache Yarn dependencies id: yarn-cache - uses: actions/cache@v4 + uses: ./.github/actions/cache-yarn with: path: | .yarn/cache node_modules sdk/qrcode/node_modules common/node_modules - key: ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn- + cache-version: ${{ env.GH_YARN_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }} - name: Install Dependencies uses: ./.github/actions/yarn-install - name: Restore build artifacts - uses: actions/cache/restore@v4 + id: restore-build + uses: ./.github/actions/cache-sdk-build with: - path: | - common/dist - sdk/sdk-common/dist - sdk/qrcode/dist - key: qrcode-sdk-build-${{ env.GH_SDK_CACHE_VERSION }}-${{ github.sha }} - fail-on-cache-miss: true + mode: restore + cache-version: ${{ env.GH_SDK_CACHE_VERSION }} + fail-on-cache-miss: false + + - name: Build dependencies (fallback on cache miss) + if: steps.restore-build.outputs.cache-hit != 'true' + run: | + yarn workspace @selfxyz/common build + yarn workspace @selfxyz/sdk-common build + yarn workspace @selfxyz/qrcode build + + - name: Check for nested require() in tests + run: | + # Check SDK tests for nested require patterns that cause OOM + if grep -rE "require\(['\"]react(-native)?['\"])" sdk/qrcode/src/ sdk/qrcode/tests/ 2>/dev/null; then + echo "❌ Found nested require() patterns that cause OOM in CI" + exit 1 + fi + echo "✅ No nested require() patterns found" - name: Run tests run: yarn workspace @selfxyz/qrcode test diff --git a/app/ios/PassportReader.swift b/app/ios/PassportReader.swift index 4a54c24d0..efbf1cec8 100644 --- a/app/ios/PassportReader.swift +++ b/app/ios/PassportReader.swift @@ -11,9 +11,9 @@ import Foundation import React #if !E2E_TESTING import NFCPassportReader +import Mixpanel #endif import Security -import Mixpanel import Sentry #if !E2E_TESTING diff --git a/app/ios/Podfile b/app/ios/Podfile index b08972387..e033f03f8 100755 --- a/app/ios/Podfile +++ b/app/ios/Podfile @@ -53,8 +53,6 @@ end target "Self" do # Native module exclusion for E2E testing is handled in react-native.config.cjs config = use_native_modules! - - use_frameworks! # Skip NFCPassportReader for e2e testing to avoid build issues unless ENV["E2E_TESTING"] == "1" # Check if we're running in a selfxyz repo or an external fork @@ -79,10 +77,13 @@ target "Self" do pod "NFCPassportReader", git: nfc_repo_url, commit: "9eff7c4e3a9037fdc1e03301584e0d5dcf14d76b" end + # Explicitly declare Mixpanel to ensure it's available even in E2E builds + # (NFCPassportReader also includes Mixpanel, but is skipped during E2E testing) + pod "Mixpanel-swift", :modular_headers => true + pod "QKMRZScanner" pod "lottie-ios" pod "SwiftQRScanner", :git => "https://github.com/vinodiOS/SwiftQRScanner" - pod "Mixpanel-swift", "~> 5.0.0" # RNReactNativeHapticFeedback is handled by autolinking use_react_native!( diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock index 57d0412d9..3a44a4f13 100644 --- a/app/ios/Podfile.lock +++ b/app/ios/Podfile.lock @@ -1558,7 +1558,7 @@ PODS: - React-Core - react-native-netinfo (11.4.1): - React-Core - - react-native-nfc-manager (3.16.3): + - react-native-nfc-manager (3.17.2): - React-Core - react-native-passkey (3.3.1): - DoubleConversion @@ -1984,7 +1984,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNDeviceInfo (14.1.1): + - RNDeviceInfo (15.0.1): - React-Core - RNFBApp (19.3.0): - Firebase/CoreOnly (= 10.24.0) @@ -2042,7 +2042,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNLocalize (3.6.0): + - RNLocalize (3.6.1): - DoubleConversion - glog - hermes-engine @@ -2129,7 +2129,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNSentry (7.0.1): + - RNSentry (7.0.0): - DoubleConversion - glog - hermes-engine @@ -2152,7 +2152,7 @@ PODS: - ReactCommon/turbomodule/core - Sentry/HybridSDK (= 8.53.2) - Yoga - - RNSVG (15.15.0): + - RNSVG (15.12.1): - DoubleConversion - glog - hermes-engine @@ -2172,9 +2172,9 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNSVG/common (= 15.15.0) + - RNSVG/common (= 15.12.1) - Yoga - - RNSVG/common (15.15.0): + - RNSVG/common (15.12.1): - DoubleConversion - glog - hermes-engine @@ -2223,7 +2223,7 @@ DEPENDENCIES: - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - lottie-ios - lottie-react-native (from `../node_modules/lottie-react-native`) - - Mixpanel-swift (~> 5.0.0) + - Mixpanel-swift - "NFCPassportReader (from `git@github.com:selfxyz/NFCPassportReader.git`, commit `9eff7c4e3a9037fdc1e03301584e0d5dcf14d76b`)" - QKMRZScanner - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -2626,7 +2626,7 @@ SPEC CHECKSUMS: react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba react-native-mobilesdk-module: 4770cb45fdd19dc4eed04615f0fcdab013b3dfe2 react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-nfc-manager: 66a00e5ddab9704efebe19d605b1b8afb0bb1bd7 + react-native-nfc-manager: c8891e460b4943b695d63f7f4effc6345bbefc83 react-native-passkey: 8853c3c635164864da68a6dbbcec7148506c3bcf react-native-safe-area-context: a7aad44fe544b55e2369a3086e16a01be60ce398 react-native-sqlite-storage: 0c84826214baaa498796c7e46a5ccc9a82e114ed @@ -2660,18 +2660,18 @@ SPEC CHECKSUMS: ReactCommon: b2eb96a61b826ff327a773a74357b302cf6da678 RNCAsyncStorage: 0003b916f1a69fe2d20b7910e0d08da3d32c7bd6 RNCClipboard: a4827e134e4774e97fa86f7f986694dd89320f13 - RNDeviceInfo: bcce8752b5043a623fe3c26789679b473f705d3c + RNDeviceInfo: 36d7f232bfe7c9b5c494cb7793230424ed32c388 RNFBApp: 4097f75673f8b42a7cd1ba17e6ea85a94b45e4d1 RNFBMessaging: 92325b0d5619ac90ef023a23cfd16fd3b91d0a88 RNFBRemoteConfig: a569bacaa410acfcaba769370e53a787f80fd13b RNGestureHandler: a63b531307e5b2e6ea21d053a1a7ad4cf9695c57 RNInAppBrowser: 6d3eb68d471b9834335c664704719b8be1bfdb20 RNKeychain: 471ceef8c13f15a5534c3cd2674dbbd9d0680e52 - RNLocalize: 4f5e4a46d2bccd04ccb96721e438dcb9de17c2e0 + RNLocalize: 2760999d1e2fc95fb7b7e5247631feb3c08156dc RNReactNativeHapticFeedback: e526ac4a7ca9fb23c7843ea4fd7d823166054c73 RNScreens: 806e1449a8ec63c2a4e4cf8a63cc80203ccda9b8 - RNSentry: 6ad982be2c8e32dab912afb4132b6a0d88484ea0 - RNSVG: 39476f26bbbe72ffe6194c6fc8f6acd588087957 + RNSentry: f79dd124cc49088445c16d23955860dd0d1db6f3 + RNSVG: 0c1fc3e7b147949dc15644845e9124947ac8c9bb segment-analytics-react-native: 0eae155b0e9fa560fa6b17d78941df64537c35b7 Sentry: 59993bffde4a1ac297ba6d268dc4bbce068d7c1b SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 @@ -2681,6 +2681,6 @@ SPEC CHECKSUMS: TwilioVideo: 9f51085d4e4fb3aff8e168b8215b31cb0f486a2f Yoga: 1259c7a8cbaccf7b4c3ddf8ee36ca11be9dee407 -PODFILE CHECKSUM: f03c12b5d96fb6e22afe20fba517840fef44e76f +PODFILE CHECKSUM: 8cfd84595c3e826f512f5c545d232a27f1850ff3 COCOAPODS: 1.16.2 diff --git a/app/ios/SelfAnalytics.swift b/app/ios/SelfAnalytics.swift index de0acfba1..b056e4dbe 100644 --- a/app/ios/SelfAnalytics.swift +++ b/app/ios/SelfAnalytics.swift @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11 import Foundation -import Mixpanel #if !E2E_TESTING +import Mixpanel import NFCPassportReader public class SelfAnalytics: Analytics { diff --git a/app/package.json b/app/package.json index e6fb8dca6..39b1fb5a4 100644 --- a/app/package.json +++ b/app/package.json @@ -85,13 +85,13 @@ "react-native-webview": "13.16.0" }, "dependencies": { - "@babel/runtime": "^7.28.3", - "@ethersproject/shims": "^5.7.0", + "@babel/runtime": "^7.28.6", + "@ethersproject/shims": "^5.8.0", "@noble/hashes": "^1.5.0", "@openpassport/zk-kit-imt": "^0.0.5", "@openpassport/zk-kit-lean-imt": "^0.0.6", "@openpassport/zk-kit-smt": "^0.0.1", - "@peculiar/x509": "^1.13.0", + "@peculiar/x509": "^1.14.3", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-clipboard/clipboard": "1.16.3", "@react-native-community/blur": "^4.4.1", @@ -108,7 +108,7 @@ "@selfxyz/euclid": "^0.6.1", "@selfxyz/mobile-sdk-alpha": "workspace:^", "@sentry/react": "^9.32.0", - "@sentry/react-native": "7.0.1", + "@sentry/react-native": "7.0.0", "@stablelib/cbor": "^2.0.1", "@sumsub/react-native-mobilesdk-module": "1.40.2", "@tamagui/animations-css": "1.126.14", @@ -122,7 +122,7 @@ "@turnkey/react-native-wallet-kit": "1.1.5", "@walletconnect/react-native-compat": "^2.23.0", "@xstate/react": "^5.0.3", - "asn1js": "^3.0.6", + "asn1js": "^3.0.7", "axios": "^1.13.2", "buffer": "^6.0.3", "country-emoji": "^1.5.6", @@ -136,8 +136,8 @@ "js-sha512": "^0.9.0", "lottie-react": "^2.4.1", "lottie-react-native": "7.2.2", - "node-forge": "^1.3.1", - "pkijs": "^3.2.5", + "node-forge": "^1.3.3", + "pkijs": "^3.3.3", "poseidon-lite": "^0.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -147,7 +147,7 @@ "react-native-blur-effect": "^1.1.3", "react-native-check-version": "^1.3.0", "react-native-cloud-storage": "^2.2.2", - "react-native-device-info": "^14.0.4", + "react-native-device-info": "^15.0.1", "react-native-dotenv": "^3.4.11", "react-native-edge-to-edge": "^1.7.0", "react-native-gesture-handler": "2.19.0", @@ -156,18 +156,18 @@ "react-native-inappbrowser-reborn": "^3.7.0", "react-native-keychain": "^10.0.0", "react-native-linear-gradient": "^2.8.3", - "react-native-localize": "^3.5.2", - "react-native-logs": "^5.3.0", - "react-native-nfc-manager": "3.16.3", - "react-native-passkey": "^3.3.1", + "react-native-localize": "^3.6.1", + "react-native-logs": "^5.5.0", + "react-native-nfc-manager": "3.17.2", + "react-native-passkey": "^3.3.2", "react-native-passport-reader": "1.0.3", - "react-native-safe-area-context": "^5.6.1", + "react-native-safe-area-context": "^5.6.2", "react-native-screens": "4.15.3", "react-native-sqlite-storage": "^6.0.1", - "react-native-svg": "15.15.0", + "react-native-svg": "15.12.1", "react-native-svg-web": "1.0.9", "react-native-url-polyfill": "^3.0.0", - "react-native-web": "^0.19.0", + "react-native-web": "^0.21.2", "react-native-webview": "^13.16.0", "react-qr-barcode-scanner": "^2.1.8", "socket.io-client": "^4.8.3", @@ -177,14 +177,14 @@ "zustand": "^4.5.2" }, "devDependencies": { - "@babel/core": "^7.28.3", - "@babel/plugin-syntax-flow": "^7.27.1", - "@babel/plugin-transform-classes": "^7.27.1", + "@babel/core": "^7.28.6", + "@babel/plugin-syntax-flow": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-flow-strip-types": "^7.27.1", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/preset-env": "^7.28.6", + "@babel/preset-react": "^7.28.5", "@react-native-community/cli": "^16.0.3", "@react-native/babel-preset": "0.76.9", "@react-native/eslint-config": "0.76.9", @@ -210,11 +210,11 @@ "@types/react-test-renderer": "^18", "@typescript-eslint/eslint-plugin": "^8.39.0", "@typescript-eslint/parser": "^8.39.0", - "@vitejs/plugin-react-swc": "^3.10.2", + "@vitejs/plugin-react-swc": "^4.2.2", "babel-plugin-module-resolver": "^5.0.2", "babel-plugin-transform-remove-console": "^6.9.4", "constants-browserify": "^1.0.0", - "dompurify": "^3.2.6", + "dompurify": "^3.3.1", "eslint": "^8.57.0", "eslint-config-prettier": "10.1.8", "eslint-import-resolver-typescript": "^3.7.0", @@ -229,14 +229,15 @@ "jest": "^30.2.0", "path-browserify": "^1.0.1", "prettier": "^3.5.3", - "react-native-svg-transformer": "^1.5.1", + "prop-types": "^15.8.1", + "react-native-svg-transformer": "^1.5.2", "react-test-renderer": "^18.3.1", - "rollup-plugin-visualizer": "^6.0.3", + "rollup-plugin-visualizer": "^6.0.5", "stream-browserify": "^3.0.0", "ts-morph": "^22.0.0", "ts-node": "^10.9.2", - "typescript": "^5.9.2", - "vite": "^7.0.0", + "typescript": "^5.9.3", + "vite": "^7.3.1", "vite-plugin-svgr": "^4.5.0" }, "packageManager": "yarn@4.12.0", diff --git a/circuits/package.json b/circuits/package.json index 82db68cb0..a63ffa256 100644 --- a/circuits/package.json +++ b/circuits/package.json @@ -23,8 +23,8 @@ "test-custom-hasher": "yarn test-base 'tests/other_circuits/custom_hasher.test.ts' --exit", "test-disclose": "yarn test-base 'tests/disclose/vc_and_disclose.test.ts' --exit", "test-disclose-aadhaar": "yarn test-base 'tests/disclose/vc_and_disclose_aadhaar.test.ts' --exit", - "test-disclose-kyc": "yarn test-base 'tests/disclose/vc_and_disclose_kyc.test.ts' --exit", "test-disclose-id": "yarn test-base 'tests/disclose/vc_and_disclose_id.test.ts' --exit", + "test-disclose-kyc": "yarn test-base 'tests/disclose/vc_and_disclose_kyc.test.ts' --exit", "test-dsc": "yarn test-base --max-old-space-size=51200 'tests/dsc/dsc.test.ts' --exit", "test-ecdsa": "yarn test-base 'tests/utils/ecdsa.test.ts' --exit", "test-gcp-jwt-verifier": "yarn test-base 'tests/gcp_jwt_verifier/gcp_jwt_verifier.test.ts' --exit", @@ -35,8 +35,8 @@ "test-qr-extractor": "yarn test-base 'tests/other_circuits/qrdata_extractor.test.ts' --exit", "test-register": "yarn test-base --max-old-space-size=40960 'tests/register/register.test.ts' --exit", "test-register-aadhaar": "yarn test-base 'tests/register/register_aadhaar.test.ts' --exit", - "test-register-kyc": "yarn test-base 'tests/register/register_kyc.test.ts' --exit", "test-register-id": "yarn test-base --max-old-space-size=40960 'tests/register_id/register_id.test.ts' --exit", + "test-register-kyc": "yarn test-base 'tests/register/register_kyc.test.ts' --exit", "test-rsa": "yarn test-base 'tests/utils/rsaPkcs1v1_5.test.ts' --exit", "test-rsa-pss": "yarn test-base 'tests/utils/rsapss.test.ts' --exit" }, @@ -77,6 +77,7 @@ "snarkjs": "^0.7.1" }, "devDependencies": { + "@babel/core": "^7.28.6", "@types/chai": "4.3.11", "@types/chai-as-promised": "^7.1.6", "@types/circomlibjs": "^0.1.6", @@ -85,6 +86,8 @@ "@types/node-forge": "^1.3.5", "@yarnpkg/sdks": "^3.2.0", "chai": "^4.4.1", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.31.0", "mocha": "^10.7.3", "prettier": "^3.5.3", "ts-mocha": "^10.0.0", diff --git a/common/package.json b/common/package.json index 4c0108708..4f54e8371 100644 --- a/common/package.json +++ b/common/package.json @@ -685,12 +685,12 @@ "@openpassport/zk-kit-imt": "^0.0.5", "@openpassport/zk-kit-lean-imt": "^0.0.6", "@openpassport/zk-kit-smt": "^0.0.1", - "@peculiar/x509": "^1.12.3", + "@peculiar/x509": "^1.14.3", "@stablelib/cbor": "^2.0.1", "@zk-kit/baby-jubjub": "^1.0.3", "@zk-kit/eddsa-poseidon": "^1.1.0", "asn1.js": "^5.4.1", - "asn1js": "^3.0.5", + "asn1js": "^3.0.7", "axios": "^1.7.2", "buffer": "^6.0.3", "country-emoji": "^1.5.6", @@ -706,7 +706,7 @@ "jsrsasign": "^11.1.0", "node-forge": "github:remicolin/forge#17a11a632dd0e50343b3b8393245a2696f78afbb", "path": "^0.12.7", - "pkijs": "^3.2.4", + "pkijs": "^3.3.3", "poseidon-lite": "^0.2.0", "snarkjs": "^0.7.5", "typescript-parser": "^2.6.1", @@ -727,7 +727,7 @@ "eslint-plugin-sort-exports": "^0.9.1", "prettier": "^3.5.3", "tsup": "^8.5.0", - "typescript": "^5.9.2", + "typescript": "^5.9.3", "vitest": "^2.1.8" }, "packageManager": "yarn@4.12.0", diff --git a/contracts/contracts/libraries/CustomVerifier.sol b/contracts/contracts/libraries/CustomVerifier.sol index c9f18ce29..9e6d3cd2c 100644 --- a/contracts/contracts/libraries/CustomVerifier.sol +++ b/contracts/contracts/libraries/CustomVerifier.sol @@ -323,9 +323,7 @@ library CustomVerifier { if (verificationConfig.forbiddenCountriesEnabled) { for (uint256 i = 0; i < 4; i++) { - if ( - kycOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i] - ) { + if (kycOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i]) { revert InvalidForbiddenCountries(); } } diff --git a/contracts/test/utils/deploymentV2.ts b/contracts/test/utils/deploymentV2.ts index 1607b8d1f..ec5691f2f 100644 --- a/contracts/test/utils/deploymentV2.ts +++ b/contracts/test/utils/deploymentV2.ts @@ -375,10 +375,7 @@ export async function deploySystemFixturesV2(): Promise { let registryKycContract, updateKycHubTx; { - registryKycContract = await ethers.getContractAt( - "IdentityRegistryKycImplV1", - identityRegistryKycProxy.target, - ); + registryKycContract = await ethers.getContractAt("IdentityRegistryKycImplV1", identityRegistryKycProxy.target); updateKycHubTx = await registryKycContract.updateHub(identityVerificationHubV2.target); await updateKycHubTx.wait(); diff --git a/contracts/test/utils/generateProof.ts b/contracts/test/utils/generateProof.ts index e41022a41..5473f212f 100644 --- a/contracts/test/utils/generateProof.ts +++ b/contracts/test/utils/generateProof.ts @@ -589,12 +589,8 @@ export function getSMTs() { ) as typeof SMT; const nameAndDob_id_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndDobSMT_ID.json") as typeof SMT; const nameAndYob_id_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndYobSMT_ID.json") as typeof SMT; - const nameAndDob_kyc_smt = importSMTFromJsonFile( - "../circuits/tests/consts/ofac/nameAndDobKycSMT.json", - ) as typeof SMT; - const nameAndYob_kyc_smt = importSMTFromJsonFile( - "../circuits/tests/consts/ofac/nameAndYobKycSMT.json", - ) as typeof SMT; + const nameAndDob_kyc_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndDobKycSMT.json") as typeof SMT; + const nameAndYob_kyc_smt = importSMTFromJsonFile("../circuits/tests/consts/ofac/nameAndYobKycSMT.json") as typeof SMT; return { passportNo_smt, diff --git a/contracts/test/v2/registerKyc.test.ts b/contracts/test/v2/registerKyc.test.ts index e40eecb80..96e3775bc 100644 --- a/contracts/test/v2/registerKyc.test.ts +++ b/contracts/test/v2/registerKyc.test.ts @@ -145,12 +145,7 @@ describe("KYC Registration test", function () { }); it("should successfully register an identity commitment", async () => { - await deployedActors.registryKyc.registerPubkeyCommitment( - mockProof.a, - mockProof.b, - mockProof.c, - mockPubSignals, - ); + await deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals); await expect(deployedActors.hub.registerCommitment(attestationIdBytes32, 0n, registerProof)).to.emit( deployedActors.registryKyc, @@ -168,12 +163,7 @@ describe("KYC Registration test", function () { }); it("should not register an identity commitment if the proof is invalid", async () => { - await deployedActors.registryKyc.registerPubkeyCommitment( - mockProof.a, - mockProof.b, - mockProof.c, - mockPubSignals, - ); + await deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals); const invalidRegisterProof = structuredClone(registerProof); invalidRegisterProof.pubSignals[1] = 0n; @@ -434,12 +424,7 @@ describe("KYC Registration test", function () { ]; await expect( - deployedActors.registryKyc.registerPubkeyCommitment( - mockProof.a, - mockProof.b, - mockProof.c, - mockPubSignals, - ), + deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_PROOF"); }); @@ -456,12 +441,7 @@ describe("KYC Registration test", function () { ]; await expect( - deployedActors.registryKyc.registerPubkeyCommitment( - mockProof.a, - mockProof.b, - mockProof.c, - mockPubSignals, - ), + deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_ROOT_CA"); }); @@ -478,12 +458,7 @@ describe("KYC Registration test", function () { ]; await expect( - deployedActors.registryKyc.registerPubkeyCommitment( - mockProof.a, - mockProof.b, - mockProof.c, - mockPubSignals, - ), + deployedActors.registryKyc.registerPubkeyCommitment(mockProof.a, mockProof.b, mockProof.c, mockPubSignals), ).to.be.revertedWithCustomError(deployedActors.registryKyc, "INVALID_IMAGE"); }); }); diff --git a/package.json b/package.json index ff4ca06d0..ac43b47c7 100644 --- a/package.json +++ b/package.json @@ -37,16 +37,17 @@ "types": "yarn workspaces foreach --topological-dev --parallel --exclude @selfxyz/contracts --exclude @selfxyz/common --exclude @selfxyz/mobile-app -i --all run types" }, "resolutions": { - "@babel/core": "^7.28.4", - "@babel/runtime": "^7.28.4", + "@babel/core": "^7.28.6", + "@babel/runtime": "^7.28.6", "@noble/curves": "1.9.7", "@noble/hashes": "1.8.0", - "ethereum-cryptography": "3.2.0", "@swc/core": "1.7.36", "@tamagui/animations-react-native": "1.126.14", "@tamagui/toast": "1.126.14", "@types/node": "^22.18.3", "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "ethereum-cryptography": "3.2.0", "punycode": "npm:punycode.js@^2.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -56,7 +57,7 @@ "react-native-webview": "13.16.0" }, "dependencies": { - "@babel/runtime": "^7.28.3", + "@babel/runtime": "^7.28.6", "js-sha1": "^0.7.0", "react": "^18.3.1", "react-native": "0.76.9", @@ -71,7 +72,7 @@ "patch-package": "^8.0.0", "prettier": "^3.6.2", "tsx": "^4.21.0", - "typescript": "^5.9.2" + "typescript": "^5.9.3" }, "packageManager": "yarn@4.12.0", "engines": { diff --git a/packages/mobile-sdk-alpha/package.json b/packages/mobile-sdk-alpha/package.json index a5a77be84..e14606e71 100644 --- a/packages/mobile-sdk-alpha/package.json +++ b/packages/mobile-sdk-alpha/package.json @@ -149,14 +149,14 @@ "watch": "pkill -f 'tsup.*--watch' 2>/dev/null || true && tsup && yarn postbuild && tsup --watch" }, "dependencies": { - "@babel/runtime": "^7.28.3", + "@babel/runtime": "^7.28.6", "@selfxyz/common": "workspace:^", "@selfxyz/euclid": "^0.6.1", "@xstate/react": "^5.0.5", - "node-forge": "^1.3.1", - "react-native-nfc-manager": "^3.17.1", + "node-forge": "^1.3.3", + "react-native-nfc-manager": "^3.17.2", "react-native-svg-circle-country-flags": "^0.2.2", - "socket.io-client": "^4.8.1", + "socket.io-client": "^4.8.3", "uuid": "^11.1.0", "xstate": "^5.20.2", "zustand": "^4.5.2" @@ -183,11 +183,14 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-native": "0.76.9", + "react-native-blur-effect": "^1.1.3", "react-native-haptic-feedback": "^2.3.3", - "react-native-localize": "^3.5.2", - "react-native-web": "^0.21.1", + "react-native-localize": "^3.6.1", + "react-native-svg": "15.15.1", + "react-native-web": "^0.21.2", + "react-native-webview": "13.16.0", "tsup": "^8.0.1", - "typescript": "^5.9.2", + "typescript": "^5.9.3", "vitest": "^2.1.8" }, "peerDependencies": { diff --git a/packages/mobile-sdk-demo/package.json b/packages/mobile-sdk-demo/package.json index 713669dd2..9a9a9a281 100644 --- a/packages/mobile-sdk-demo/package.json +++ b/packages/mobile-sdk-demo/package.json @@ -28,7 +28,7 @@ "types": "yarn prebuild && tsc --noEmit" }, "dependencies": { - "@babel/runtime": "^7.28.3", + "@babel/runtime": "^7.28.6", "@faker-js/faker": "^10.0.0", "@noble/hashes": "^1.5.0", "@react-native-async-storage/async-storage": "^2.2.0", @@ -46,16 +46,16 @@ "react-native-get-random-values": "^1.11.0", "react-native-haptic-feedback": "^2.3.3", "react-native-keychain": "^10.0.0", - "react-native-localize": "^3.5.4", - "react-native-safe-area-context": "^5.6.1", - "react-native-svg": "15.12.1", + "react-native-localize": "^3.6.1", + "react-native-safe-area-context": "^5.6.2", + "react-native-svg": "15.15.1", "react-native-vector-icons": "^10.3.0", "react-native-webview": "13.16.0", "stream-browserify": "^3.0.0", "util": "^0.12.5" }, "devDependencies": { - "@babel/core": "^7.28.3", + "@babel/core": "^7.28.6", "@react-native-community/cli": "^16.0.3", "@react-native/gradle-plugin": "0.76.9", "@react-native/metro-config": "0.76.9", @@ -83,8 +83,8 @@ "metro-react-native-babel-preset": "0.76.9", "prettier": "^3.6.2", "react-dom": "^18.3.1", - "react-native-svg-transformer": "^1.5.1", - "typescript": "^5.9.2", + "react-native-svg-transformer": "^1.5.2", + "typescript": "^5.9.3", "vitest": "^2.1.8" } } diff --git a/patches/@sumsub+react-native-mobilesdk-module+1.40.2.patch b/patches/@sumsub+react-native-mobilesdk-module+1.40.2.patch index 8b514d876..fccb8e539 100644 --- a/patches/@sumsub+react-native-mobilesdk-module+1.40.2.patch +++ b/patches/@sumsub+react-native-mobilesdk-module+1.40.2.patch @@ -1,8 +1,8 @@ diff --git a/node_modules/@sumsub/react-native-mobilesdk-module/android/build.gradle b/node_modules/@sumsub/react-native-mobilesdk-module/android/build.gradle -index 1234567..abcdefg 100644 +index 0000000..0000001 100644 --- a/node_modules/@sumsub/react-native-mobilesdk-module/android/build.gradle +++ b/node_modules/@sumsub/react-native-mobilesdk-module/android/build.gradle -@@ -69,9 +69,9 @@ dependencies { +@@ -77,11 +77,11 @@ dependencies { implementation "com.sumsub.sns:idensic-mobile-sdk:1.40.2" // remove comment to enable Device Intelligence @@ -12,3 +12,7 @@ index 1234567..abcdefg 100644 - // implementation "com.sumsub.sns:idensic-mobile-sdk-videoident:1.40.2" + implementation "com.sumsub.sns:idensic-mobile-sdk-videoident:1.40.2" // remove comment if you need EID support + // implementation "com.sumsub.sns:idensic-mobile-sdk-eid:1.40.2" + // remove comment if you need NFC support + // implementation "com.sumsub.sns:idensic-mobile-sdk-nfc:1.40.2" + } diff --git a/patches/ethereum-cryptography+2.2.1.patch b/patches/ethereum-cryptography+2.2.1.patch deleted file mode 100644 index 3ba0a2381..000000000 --- a/patches/ethereum-cryptography+2.2.1.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/node_modules/ethereum-cryptography/utils.js b/node_modules/ethereum-cryptography/utils.js -index cedfa36..b494c49 100644 ---- a/node_modules/ethereum-cryptography/utils.js -+++ b/node_modules/ethereum-cryptography/utils.js -@@ -8,11 +8,18 @@ exports.bytesToUtf8 = bytesToUtf8; - exports.hexToBytes = hexToBytes; - exports.equalsBytes = equalsBytes; - exports.wrapHash = wrapHash; --const _assert_1 = __importDefault(require("@noble/hashes/_assert")); -+const assertModule = __importDefault(require("@noble/hashes/_assert")); - const utils_1 = require("@noble/hashes/utils"); --const assertBool = _assert_1.default.bool; -+const assertBool = (assertModule.default && assertModule.default.bool) || -+ assertModule.bool || -+ ((value) => { -+ if (typeof value !== "boolean") -+ throw new TypeError(`Expected boolean, not ${value}`); -+ }); - exports.assertBool = assertBool; --const assertBytes = _assert_1.default.bytes; -+const assertBytes = (assertModule.default && assertModule.default.bytes) || -+ assertModule.bytes || -+ assertModule.abytes; - exports.assertBytes = assertBytes; - var utils_2 = require("@noble/hashes/utils"); - Object.defineProperty(exports, "bytesToHex", { enumerable: true, get: function () { return utils_2.bytesToHex; } }); -diff --git a/node_modules/ethereum-cryptography/esm/utils.js b/node_modules/ethereum-cryptography/esm/utils.js -index 8e771ea..b3eed9d 100644 ---- a/node_modules/ethereum-cryptography/esm/utils.js -+++ b/node_modules/ethereum-cryptography/esm/utils.js -@@ -1,7 +1,11 @@ - import assert from "@noble/hashes/_assert"; - import { hexToBytes as _hexToBytes } from "@noble/hashes/utils"; --const assertBool = assert.bool; --const assertBytes = assert.bytes; -+const assertBool = (assert?.bool) || -+ ((value) => { -+ if (typeof value !== "boolean") -+ throw new TypeError(`Expected boolean, not ${value}`); -+ }); -+const assertBytes = assert.bytes || assert.abytes; - export { assertBool, assertBytes }; - export { bytesToHex, bytesToHex as toHex, concatBytes, createView, utf8ToBytes } from "@noble/hashes/utils"; - // buf.toString('utf8') -> bytesToUtf8(buf) diff --git a/patches/react-native-gesture-handler+2.30.0.patch b/patches/react-native-gesture-handler+2.30.0.patch new file mode 100644 index 000000000..05cb86259 --- /dev/null +++ b/patches/react-native-gesture-handler+2.30.0.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/react-native-gesture-handler/android/build.gradle b/node_modules/react-native-gesture-handler/android/build.gradle +--- a/node_modules/react-native-gesture-handler/android/build.gradle ++++ b/node_modules/react-native-gesture-handler/android/build.gradle +@@ -229,9 +229,10 @@ + } + + def kotlin_version = safeExtGet('kotlinVersion', project.properties['RNGH_kotlinVersion']) ++def reactNativeDependency = safeExtGet("reactNativeDependency", "com.facebook.react:react-android") + + dependencies { +- implementation 'com.facebook.react:react-native:+' // from node_modules ++ implementation reactNativeDependency + + + if (shouldUseCommonInterfaceFromReanimated()) { diff --git a/patches/react-native-svg+15.14.0.patch b/patches/react-native-svg+15.14.0.patch deleted file mode 100644 index 18f7e025e..000000000 --- a/patches/react-native-svg+15.14.0.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/node_modules/react-native-svg/android/.project b/node_modules/react-native-svg/android/.project -new file mode 100644 -index 0000000..dd0da62 ---- /dev/null -+++ b/node_modules/react-native-svg/android/.project -@@ -0,0 +1,28 @@ -+ -+ -+ react-native-svg -+ Project OpenPassport-android-react-native-svg created by Buildship. -+ -+ -+ -+ -+ org.eclipse.buildship.core.gradleprojectbuilder -+ -+ -+ -+ -+ -+ org.eclipse.buildship.core.gradleprojectnature -+ -+ -+ -+ 1759738232589 -+ -+ 30 -+ -+ org.eclipse.core.resources.regexFilterMatcher -+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ -+ -+ -+ -+ -diff --git a/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp b/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp -index 11718dd..fe993b3 100644 ---- a/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp -+++ b/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp -@@ -28,8 +28,8 @@ void RNSVGLayoutableShadowNode::setZeroDimensions() { - // views in the layout inspector when Yoga attempts to interpret SVG - // properties like width when viewBox scale is set. - auto style = yogaNode_.style(); -- style.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(0)); -- style.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(0)); -+ style.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(0)); -+ style.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(0)); - yogaNode_.setStyle(style); - } - -diff --git a/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp.bak b/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp.bak -new file mode 100644 -index 0000000..11718dd ---- /dev/null -+++ b/node_modules/react-native-svg/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp.bak -@@ -0,0 +1,43 @@ -+#include "RNSVGLayoutableShadowNode.h" -+#include -+ -+namespace facebook::react { -+ -+RNSVGLayoutableShadowNode::RNSVGLayoutableShadowNode( -+ const ShadowNodeFragment &fragment, -+ const ShadowNodeFamily::Shared &family, -+ ShadowNodeTraits traits) -+ : YogaLayoutableShadowNode(fragment, family, traits) { -+ if (std::strcmp(this->getComponentName(), "RNSVGGroup") != 0) { -+ setZeroDimensions(); -+ } -+} -+ -+RNSVGLayoutableShadowNode::RNSVGLayoutableShadowNode( -+ const ShadowNode &sourceShadowNode, -+ const ShadowNodeFragment &fragment) -+ : YogaLayoutableShadowNode(sourceShadowNode, fragment) { -+ if (std::strcmp(this->getComponentName(), "RNSVGGroup") != 0) { -+ setZeroDimensions(); -+ } -+} -+ -+void RNSVGLayoutableShadowNode::setZeroDimensions() { -+ // SVG handles its layout manually on the native side and does not depend on -+ // the Yoga layout. Setting the dimensions to 0 eliminates randomly positioned -+ // views in the layout inspector when Yoga attempts to interpret SVG -+ // properties like width when viewBox scale is set. -+ auto style = yogaNode_.style(); -+ style.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(0)); -+ style.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(0)); -+ yogaNode_.setStyle(style); -+} -+ -+void RNSVGLayoutableShadowNode::layout(LayoutContext layoutContext) { -+ auto affectedNodes = layoutContext.affectedNodes; -+ layoutContext.affectedNodes = nullptr; -+ YogaLayoutableShadowNode::layout(layoutContext); -+ layoutContext.affectedNodes = affectedNodes; -+} -+ -+} // namespace facebook::react diff --git a/scripts/run-patch-package.cjs b/scripts/run-patch-package.cjs index a5fb6503f..088673fef 100644 --- a/scripts/run-patch-package.cjs +++ b/scripts/run-patch-package.cjs @@ -88,30 +88,45 @@ if (!isExecutableAvailableOnPath('patch-package')) { process.exit(0); } +// Workspaces with isolated node_modules due to nmHoistingLimits: workspaces +// Most packages are in workspace node_modules, not root +const workspaceRoots = [ + { name: 'app', path: path.join(repositoryRootPath, 'app') }, + { name: 'contracts', path: path.join(repositoryRootPath, 'contracts') } +]; + // Run patch-package with better error handling try { - const rootPatchRun = spawnSync('patch-package', ['--patch-dir', 'patches'], { - cwd: repositoryRootPath, - shell: true, - stdio: isCI ? 'pipe' : 'inherit', - timeout: 30000 - }); - if (rootPatchRun.status === 0) { - if (!isCI) console.log('✓ Patches applied to root workspace'); - } else { - const errorOutput = rootPatchRun.stderr?.toString() || rootPatchRun.stdout?.toString() || ''; - console.error(`patch-package failed for root workspace (exit code ${rootPatchRun.status})`); - if (errorOutput) console.error(errorOutput); - if (!isCI) process.exit(1); + let anyPatchApplied = false; + let anyPatchFailed = false; + + // Try root node_modules first (some packages may be hoisted here) + const rootNodeModules = path.join(repositoryRootPath, 'node_modules'); + if (fs.existsSync(rootNodeModules)) { + const rootPatchRun = spawnSync('patch-package', ['--patch-dir', 'patches'], { + cwd: repositoryRootPath, + shell: true, + stdio: 'pipe', // Always capture output to check for real errors vs missing packages + timeout: 30000 + }); + const output = rootPatchRun.stdout?.toString() || ''; + const stderrOutput = rootPatchRun.stderr?.toString() || ''; + const hasRealError = (output.includes('**ERROR**') && !output.includes('which is not present at')) || + (stderrOutput.length > 0 && rootPatchRun.status !== 0); + + if (rootPatchRun.status === 0) { + if (!isCI) console.log('✓ Patches applied to root workspace'); + anyPatchApplied = true; + } else if (hasRealError) { + console.error(`patch-package failed for root workspace`); + console.error(output); + if (stderrOutput) console.error(stderrOutput); + anyPatchFailed = true; + } + // If packages are just missing (not hoisted to root), that's expected - continue to workspace patches } - // Also patch app/node_modules if it exists - // Workspaces with isolated node_modules due to limited hoisting - const workspaceRoots = [ - { name: 'app', path: path.join(repositoryRootPath, 'app') }, - { name: 'contracts', path: path.join(repositoryRootPath, 'contracts') } - ]; - + // Apply patches to workspace node_modules (where most packages are with nmHoistingLimits) for (const workspace of workspaceRoots) { const workspaceNodeModules = path.join(workspace.path, 'node_modules'); if (!fs.existsSync(workspaceNodeModules)) continue; @@ -119,19 +134,41 @@ try { const workspacePatchRun = spawnSync('patch-package', ['--patch-dir', '../patches'], { cwd: workspace.path, shell: true, - stdio: isCI ? 'pipe' : 'inherit', + stdio: 'pipe', timeout: 30000 }); + const output = workspacePatchRun.stdout?.toString() || ''; + const stderrOutput = workspacePatchRun.stderr?.toString() || ''; + const hasRealError = (output.includes('**ERROR**') && !output.includes('which is not present at')) || + (stderrOutput.length > 0 && workspacePatchRun.status !== 0); + if (workspacePatchRun.status === 0) { if (!isCI) console.log(`✓ Patches applied to ${workspace.name} workspace`); - } else { - const errorOutput = workspacePatchRun.stderr?.toString() || workspacePatchRun.stdout?.toString() || ''; - console.error(`patch-package failed for ${workspace.name} workspace (exit code ${workspacePatchRun.status})`); - if (errorOutput) console.error(errorOutput); - if (!isCI) process.exit(1); + anyPatchApplied = true; + } else if (hasRealError) { + console.error(`patch-package failed for ${workspace.name} workspace`); + console.error(output); + if (stderrOutput) console.error(stderrOutput); + anyPatchFailed = true; } } + + if (anyPatchFailed && !isCI) { + console.error('Some patches failed to apply. Check if patch versions match installed package versions.'); + process.exit(1); + } + if (anyPatchFailed && isCI) { + console.warn('⚠️ CI Warning: Some patches failed to apply. Review patch compatibility.'); + } + + if (anyPatchApplied) { + if (!isCI) console.log('✓ patch-package completed'); + else console.log('patch-package completed'); + } else { + if (!isCI) console.log('patch-package: no patches applied (packages may be in different locations)'); + else console.log('patch-package: no patches applied'); + } } catch (error) { if (isCI) { console.log('patch-package: error during execution (CI mode):', error.message); diff --git a/sdk/core/package.json b/sdk/core/package.json index 2a232711a..d4a06479f 100644 --- a/sdk/core/package.json +++ b/sdk/core/package.json @@ -51,7 +51,7 @@ "js-sha1": "^0.7.0", "js-sha256": "^0.11.0", "js-sha512": "^0.9.0", - "node-forge": "^1.3.1", + "node-forge": "^1.3.3", "poseidon-lite": "^0.3.0", "snarkjs": "^0.7.4", "uuid": "^11.1.0" @@ -72,7 +72,7 @@ "ts-node": "^10.9.2", "tsup": "^8.5.0", "typechain": "^8.3.2", - "typescript": "^5.9.2", + "typescript": "^5.9.3", "webpack": "^5.95.0" }, "engines": { diff --git a/sdk/qrcode-angular/package.json b/sdk/qrcode-angular/package.json index 6971072f7..79881e045 100644 --- a/sdk/qrcode-angular/package.json +++ b/sdk/qrcode-angular/package.json @@ -38,7 +38,7 @@ "dependencies": { "angularx-qrcode": "^20.0.0", "lottie-web": "^5.12.2", - "socket.io-client": "^4.8.1", + "socket.io-client": "^4.8.3", "uuid": "^11.1.0" }, "devDependencies": { @@ -68,7 +68,7 @@ "prettier": "^3.5.3", "rxjs": "^7.8.0", "tslib": "^2.6.0", - "typescript": "~5.9.0", + "typescript": "~5.9.3", "zone.js": "^0.15.0" }, "peerDependencies": { diff --git a/sdk/qrcode/package.json b/sdk/qrcode/package.json index 315280460..921a4c687 100644 --- a/sdk/qrcode/package.json +++ b/sdk/qrcode/package.json @@ -72,11 +72,11 @@ "js-sha256": "^0.11.0", "js-sha512": "^0.9.0", "lottie-react": "^2.4.0", - "node-forge": "^1.3.1", + "node-forge": "^1.3.3", "poseidon-lite": "^0.3.0", "qrcode.react": "^4.1.0", "react-spinners": "^0.14.1", - "socket.io-client": "^4.8.1", + "socket.io-client": "^4.8.3", "uuid": "^11.1.0" }, "devDependencies": { @@ -104,7 +104,7 @@ "ts-mocha": "^10.0.0", "ts-node": "^10.9.2", "tsup": "^8.5.0", - "typescript": "^5.9.2", + "typescript": "^5.9.3", "webpack": "^5.95.0" }, "peerDependencies": { diff --git a/sdk/sdk-common/package.json b/sdk/sdk-common/package.json index 7eb7520e2..44bcc8027 100644 --- a/sdk/sdk-common/package.json +++ b/sdk/sdk-common/package.json @@ -32,6 +32,6 @@ "uuid": "^13.0.0" }, "devDependencies": { - "typescript": "^5.9.2" + "typescript": "^5.9.3" } } diff --git a/yarn.lock b/yarn.lock index a80c25d33..4b27c31c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1298,33 +1298,51 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0, @babel/compat-data@npm:^7.28.5": +"@babel/code-frame@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/code-frame@npm:7.28.6" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.28.5" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/ed5d57f99455e3b1c23e75ebb8430c6b9800b4ecd0121b4348b97cecb65406a47778d6db61f0d538a4958bb01b4b277e90348a68d39bd3beff1d7c940ed6dd66 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0": version: 7.28.5 resolution: "@babel/compat-data@npm:7.28.5" checksum: 10c0/702a25de73087b0eba325c1d10979eed7c9b6662677386ba7b5aa6eace0fc0676f78343bae080a0176ae26f58bd5535d73b9d0fbb547fef377692e8b249353a7 languageName: node linkType: hard -"@babel/core@npm:^7.28.4": - version: 7.28.5 - resolution: "@babel/core@npm:7.28.5" +"@babel/compat-data@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/compat-data@npm:7.28.6" + checksum: 10c0/2d047431041281eaf33e9943d1a269d3374dbc9b498cafe6a18f5ee9aee7bb96f7f6cac0304eab4d13c41fc4db00fe4ca16c7aa44469ca6a211b8b6343b78fc4 + languageName: node + linkType: hard + +"@babel/core@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/core@npm:7.28.6" dependencies: - "@babel/code-frame": "npm:^7.27.1" - "@babel/generator": "npm:^7.28.5" - "@babel/helper-compilation-targets": "npm:^7.27.2" - "@babel/helper-module-transforms": "npm:^7.28.3" - "@babel/helpers": "npm:^7.28.4" - "@babel/parser": "npm:^7.28.5" - "@babel/template": "npm:^7.27.2" - "@babel/traverse": "npm:^7.28.5" - "@babel/types": "npm:^7.28.5" + "@babel/code-frame": "npm:^7.28.6" + "@babel/generator": "npm:^7.28.6" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helpers": "npm:^7.28.6" + "@babel/parser": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" "@jridgewell/remapping": "npm:^2.3.5" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/535f82238027621da6bdffbdbe896ebad3558b311d6f8abc680637a9859b96edbf929ab010757055381570b29cf66c4a295b5618318d27a4273c0e2033925e72 + checksum: 10c0/716b88b1ab057aa53ffa40f2b2fb7e4ab7a35cd6a065fa60e55ca13d2a666672592329f7ea9269aec17e90cc7ce29f42eda566d07859bfd998329a9f283faadb languageName: node linkType: hard @@ -1368,6 +1386,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/generator@npm:7.28.6" + dependencies: + "@babel/parser": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/162fa358484a9a18e8da1235d998f10ea77c63bab408c8d3e327d5833f120631a77ff022c5ed1d838ee00523f8bb75df1f08196d3657d0bca9f2cfeb8503cc12 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:7.27.3, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" @@ -1390,6 +1421,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-compilation-targets@npm:7.28.6" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/3fcdf3b1b857a1578e99d20508859dbd3f22f3c87b8a0f3dc540627b4be539bae7f6e61e49d931542fe5b557545347272bbdacd7f58a5c77025a18b745593a50 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3, @babel/helper-create-class-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" @@ -1407,7 +1451,24 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": +"@babel/helper-create-class-features-plugin@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/0b62b46717891f4366006b88c9b7f277980d4f578c4c3789b7a4f5a2e09e121de4cda9a414ab403986745cd3ad1af3fe2d948c9f78ab80d4dc085afc9602af50 + languageName: node + linkType: hard + +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1, @babel/helper-create-regexp-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" dependencies: @@ -1471,6 +1532,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-imports@npm:7.28.6" + dependencies: + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/b49d8d8f204d9dbfd5ac70c54e533e5269afb3cea966a9d976722b13e9922cc773a653405f53c89acb247d5aebdae4681d631a3ae3df77ec046b58da76eda2ac + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": version: 7.28.3 resolution: "@babel/helper-module-transforms@npm:7.28.3" @@ -1484,6 +1555,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-transforms@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/6f03e14fc30b287ce0b839474b5f271e72837d0cafe6b172d759184d998fbee3903a035e81e07c2c596449e504f453463d58baa65b6f40a37ded5bec74620b2b + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" @@ -1500,6 +1584,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-plugin-utils@npm:7.28.6" + checksum: 10c0/3f5f8acc152fdbb69a84b8624145ff4f9b9f6e776cb989f9f968f8606eb7185c5c3cfcf3ba08534e37e1e0e1c118ac67080610333f56baa4f7376c99b5f1143d + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.18.9, @babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" @@ -1526,6 +1617,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-replace-supers@npm:7.28.6" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/04663c6389551b99b8c3e7ba4e2638b8ca2a156418c26771516124c53083aa8e74b6a45abe5dd46360af79709a0e9c6b72c076d0eab9efecdd5aaf836e79d8d5 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -1577,13 +1681,13 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/helpers@npm:7.28.4" +"@babel/helpers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helpers@npm:7.28.6" dependencies: - "@babel/template": "npm:^7.27.2" - "@babel/types": "npm:^7.28.4" - checksum: 10c0/aaa5fb8098926dfed5f223adf2c5e4c7fbba4b911b73dfec2d7d3083f8ba694d201a206db673da2d9b3ae8c01793e795767654558c450c8c14b4c2175b4fcb44 + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/c4a779c66396bb0cf619402d92f1610601ff3832db2d3b86b9c9dd10983bf79502270e97ac6d5280cea1b1a37de2f06ecbac561bd2271545270407fbe64027cb languageName: node linkType: hard @@ -1598,6 +1702,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/parser@npm:7.28.6" + dependencies: + "@babel/types": "npm:^7.28.6" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/d6bfe8aa8e067ef58909e9905496157312372ca65d8d2a4f2b40afbea48d59250163755bba8ae626a615da53d192b084bcfc8c9dad8b01e315b96967600de581 + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1, @babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.28.5" @@ -1657,6 +1772,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/f1a9194e8d1742081def7af748e9249eb5082c25d0ced292720a1f054895f99041c764a05f45af669a2c8898aeb79266058aedb0d3e1038963ad49be8288918a + languageName: node + linkType: hard + "@babel/plugin-proposal-async-generator-functions@npm:^7.0.0": version: 7.20.7 resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.20.7" @@ -1844,6 +1971,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-flow@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-flow@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/a00114adcbbdaef07638f6a2e8c3ea63d65b3d27f088e8e53c5f35b8dc50813c0e1006fac4fb109782f9cdd41ad2f1cb9838359fecbb3d1f6141b4002358f52c + languageName: node + linkType: hard + "@babel/plugin-syntax-import-assertions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1" @@ -1855,6 +1993,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-assertions@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f3b8bdccb9b4d3e3b9226684ca518e055399d05579da97dfe0160a38d65198cfe7dce809e73179d6463a863a040f980de32425a876d88efe4eda933d0d95982c + languageName: node + linkType: hard + "@babel/plugin-syntax-import-attributes@npm:^7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" @@ -1866,6 +2015,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-attributes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1be160e2c426faa74e5be2e30e39e8d0d8c543063bd5d06cd804f8751b8fbcb82ce824ca7f9ce4b09c003693f6c06a11ce503b7e34d85e1a259631e4c3f72ad2 + languageName: node + linkType: hard + "@babel/plugin-syntax-import-meta@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" @@ -2034,6 +2194,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-generator-functions@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/eddb94b0b990d8057c9c3587db3453eb586d1835626a9d683e6e8bef0ac5f708a76002951fb9cca80c902b3074b21b3a81b8af9090492561d9179862ce5716d8 + languageName: node + linkType: hard + "@babel/plugin-transform-async-to-generator@npm:7.27.1, @babel/plugin-transform-async-to-generator@npm:^7.20.0, @babel/plugin-transform-async-to-generator@npm:^7.24.7, @babel/plugin-transform-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" @@ -2047,6 +2220,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-to-generator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2eb0826248587df6e50038f36194a138771a7df22581020451c7779edeaf9ef39bf47c5b7a20ae2645af6416e8c896feeca273317329652e84abd79a4ab920ad + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" @@ -2058,7 +2244,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.0.0, @babel/plugin-transform-block-scoping@npm:^7.25.0, @babel/plugin-transform-block-scoping@npm:^7.28.0, @babel/plugin-transform-block-scoping@npm:^7.28.5": +"@babel/plugin-transform-block-scoping@npm:^7.0.0, @babel/plugin-transform-block-scoping@npm:^7.25.0, @babel/plugin-transform-block-scoping@npm:^7.28.0": version: 7.28.5 resolution: "@babel/plugin-transform-block-scoping@npm:7.28.5" dependencies: @@ -2069,6 +2255,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoping@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2e3e09e1f9770b56cef4dcbffddf262508fd03416072f815ac66b2b224a3a12cd285cfec12fc067f1add414e7db5ce6dafb5164a6e0fb1a728e6a97d0c6f6e9d + languageName: node + linkType: hard + "@babel/plugin-transform-class-properties@npm:^7.25.4, @babel/plugin-transform-class-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" @@ -2081,6 +2278,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-properties@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c4327fcd730c239d9f173f9b695b57b801729e273b4848aef1f75818069dfd31d985d75175db188d947b9b1bbe5353dae298849042026a5e4fcf07582ff3f9f1 + languageName: node + linkType: hard + "@babel/plugin-transform-class-static-block@npm:^7.28.3": version: 7.28.3 resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" @@ -2093,7 +2302,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.27.1, @babel/plugin-transform-classes@npm:^7.28.3, @babel/plugin-transform-classes@npm:^7.28.4": +"@babel/plugin-transform-class-static-block@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-static-block@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 10c0/dbe9b1fd302ae41b73186e17ac8d8ecf625ebc2416a91f2dc8013977a1bdf21e6ea288a83f084752b412242f3866e789d4fddeb428af323fe35b60e0fae4f98c + languageName: node + linkType: hard + +"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.28.3": version: 7.28.4 resolution: "@babel/plugin-transform-classes@npm:7.28.4" dependencies: @@ -2109,6 +2330,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-classes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-classes@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/dc22f1f6eadab17305128fbf9cc5f30e87a51a77dd0a6d5498097994e8a9b9a90ab298c11edf2342acbeaac9edc9c601cad72eedcf4b592cd465a787d7f41490 + languageName: node + linkType: hard + "@babel/plugin-transform-computed-properties@npm:^7.0.0, @babel/plugin-transform-computed-properties@npm:^7.24.7, @babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" @@ -2121,6 +2358,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-computed-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-computed-properties@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1e9893503ae6d651125701cc29450e87c0b873c8febebff19da75da9c40cfb7968c52c28bf948244e461110aeb7b3591f2cc199b7406ff74a24c50c7a5729f39 + languageName: node + linkType: hard + "@babel/plugin-transform-destructuring@npm:^7.20.0, @babel/plugin-transform-destructuring@npm:^7.24.8, @babel/plugin-transform-destructuring@npm:^7.28.0, @babel/plugin-transform-destructuring@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-destructuring@npm:7.28.5" @@ -2145,6 +2394,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dotall-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e2fb76b7ae99087cf4212013a3ca9dee07048f90f98fd6264855080fb6c3f169be11c9b8c9d8b26cf9a407e4d0a5fa6e103f7cef433a542b75cf7127c99d4f97 + languageName: node + linkType: hard + "@babel/plugin-transform-duplicate-keys@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" @@ -2168,6 +2429,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/a1b4161ed6a4a5e78f802035b38efd71db6691fc1b2b2a1aea49fcb449077105b4925f0c4670f117231462f5cb0a35df4ad297f7b1fac38ec76e89635f8dc51d + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" @@ -2191,7 +2464,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1, @babel/plugin-transform-exponentiation-operator@npm:^7.28.5": +"@babel/plugin-transform-explicit-resource-management@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e6ea28c26e058fe61ada3e70b0def1992dd5a44f5fc14d8e2c6a3a512fb4d4c6dc96a3e1d0b466d83db32a9101e0b02df94051e48d3140da115b8ea9f8a31f37 + languageName: node + linkType: hard + +"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": version: 7.28.5 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.5" dependencies: @@ -2202,6 +2487,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-exponentiation-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4572d955a50dbc9a652a19431b4bb822cb479ee6045f4e6df72659c499c13036da0a2adf650b07ca995f2781e80aa868943bea1e7bff1de3169ec3f0a73a902e + languageName: node + linkType: hard + "@babel/plugin-transform-export-namespace-from@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" @@ -2261,6 +2557,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-json-strings@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-json-strings@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/ab1091798c58e6c0bb8a864ee2b727c400924592c6ed69797a26b4c205f850a935de77ad516570be0419c279a3d9f7740c2aa448762eb8364ea77a6a357a9653 + languageName: node + linkType: hard + "@babel/plugin-transform-literals@npm:^7.0.0, @babel/plugin-transform-literals@npm:^7.25.2, @babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" @@ -2272,7 +2579,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7, @babel/plugin-transform-logical-assignment-operators@npm:^7.27.1, @babel/plugin-transform-logical-assignment-operators@npm:^7.28.5": +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7, @babel/plugin-transform-logical-assignment-operators@npm:^7.27.1": version: 7.28.5 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.5" dependencies: @@ -2283,6 +2590,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-logical-assignment-operators@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4632a35453d2131f0be466681d0a33e3db44d868ff51ec46cd87e0ebd1e47c6a39b894f7d1c9b06f931addf6efa9d30e60c4cdedeb4f69d426f683e11f8490cf + languageName: node + linkType: hard + "@babel/plugin-transform-member-expression-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" @@ -2318,6 +2636,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.28.6" + dependencies: + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/7c45992797c6150644c8552feff4a016ba7bd6d59ff2b039ed969a9c5b20a6804cd9d21db5045fc8cca8ca7f08262497e354e93f8f2be6a1cdf3fbfa8c31a9b6 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.27.1, @babel/plugin-transform-modules-systemjs@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.28.5" @@ -2378,6 +2708,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/6607f2201d66ccb688f0b1db09475ef995837df19f14705da41f693b669f834c206147a854864ab107913d7b4f4748878b0cd9fe9ca8bfd1bee0c206fc027b49 + languageName: node + linkType: hard + "@babel/plugin-transform-numeric-separator@npm:^7.24.7, @babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" @@ -2389,7 +2730,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.7, @babel/plugin-transform-object-rest-spread@npm:^7.28.0, @babel/plugin-transform-object-rest-spread@npm:^7.28.4": +"@babel/plugin-transform-numeric-separator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/191097d8d2753cdd16d1acca65a945d1645ab20b65655c2f5b030a9e38967a52e093dcb21ebf391e342222705c6ffe5dea15dafd6257f7b51b77fb64a830b637 + languageName: node + linkType: hard + +"@babel/plugin-transform-object-rest-spread@npm:^7.24.7, @babel/plugin-transform-object-rest-spread@npm:^7.28.0": version: 7.28.4 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" dependencies: @@ -2404,6 +2756,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-rest-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.6" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f55334352d4fcde385f2e8a58836687e71ff668c9b6e4c34d52575bf2789cdde92d9d3116edba13647ac0bc3e51fb2a6d1e8fb822dce7e8123334b82600bc4c3 + languageName: node + linkType: hard + "@babel/plugin-transform-object-super@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-object-super@npm:7.27.1" @@ -2427,7 +2794,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.8, @babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.5": +"@babel/plugin-transform-optional-catch-binding@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/36e8face000ee65e478a55febf687ce9be7513ad498c60dfe585851555565e0c28e7cb891b3c59709318539ce46f7697d5f42130eb18f385cd47e47cfa297446 + languageName: node + linkType: hard + +"@babel/plugin-transform-optional-chaining@npm:^7.24.8, @babel/plugin-transform-optional-chaining@npm:^7.27.1": version: 7.28.5 resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.5" dependencies: @@ -2439,6 +2817,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-chaining@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c159cc74115c2266be21791f192dd079e2aeb65c8731157e53b80fcefa41e8e28ad370021d4dfbdb31f25e5afa0322669a8eb2d032cd96e65ac37e020324c763 + languageName: node + linkType: hard + "@babel/plugin-transform-parameters@npm:^7.0.0, @babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" @@ -2462,6 +2852,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-methods@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-methods@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/fb504e2bfdcf3f734d2a90ab20d61427c58385f57f950d3de6ff4e6d12dd4aa7d552147312d218367e129b7920dccfc3230ba554de861986cda38921bad84067 + languageName: node + linkType: hard + "@babel/plugin-transform-private-property-in-object@npm:^7.24.7, @babel/plugin-transform-private-property-in-object@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.27.1" @@ -2475,6 +2877,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-property-in-object@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/0f6bbc6ec3f93b556d3de7d56bf49335255fc4c43488e51a5025d6ee0286183fd3cf950ffcac1bbeed8a45777f860a49996455c8d3b4a04c3b1a5f28e697fe31 + languageName: node + linkType: hard + "@babel/plugin-transform-property-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" @@ -2557,7 +2972,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.24.7, @babel/plugin-transform-regenerator@npm:^7.28.3, @babel/plugin-transform-regenerator@npm:^7.28.4": +"@babel/plugin-transform-regenerator@npm:^7.24.7, @babel/plugin-transform-regenerator@npm:^7.28.3": version: 7.28.4 resolution: "@babel/plugin-transform-regenerator@npm:7.28.4" dependencies: @@ -2568,6 +2983,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regenerator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-regenerator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/dbb65b7444548807aee558cdaf23996e7a0f6c3bced09c6b5d177734b3addcaf417532186e330341758979651e2af8cb98ae572f794f05c0e2e201e5593a5ffe + languageName: node + linkType: hard + "@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" @@ -2580,6 +3006,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regexp-modifiers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/97e36b086800f71694fa406abc00192e3833662f2bdd5f51c018bd0c95eef247c4ae187417c207d03a9c5374342eac0bb65a39112c431a9b23b09b1eda1562e5 + languageName: node + linkType: hard + "@babel/plugin-transform-reserved-words@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" @@ -2646,6 +3084,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-spread@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/bcac50e558d6f0c501cbce19ec197af558cef51fe3b3a6eba27276e323e57a5be28109b4264a5425ac12a67bf95d6af9c2a42b05e79c522ce913fb9529259d76 + languageName: node + linkType: hard + "@babel/plugin-transform-sticky-regex@npm:^7.0.0, @babel/plugin-transform-sticky-regex@npm:^7.24.7, @babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" @@ -2717,6 +3167,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-property-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b25f8cde643f4f47e0fa4f7b5c552e2dfbb6ad0ce07cf40f7e8ae40daa9855ad855d76d4d6d010153b74e48c8794685955c92ca637c0da152ce5f0fa9e7c90fa + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.0.0, @babel/plugin-transform-unicode-regex@npm:^7.24.7, @babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" @@ -2741,6 +3203,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-sets-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/c03c8818736b138db73d1f7a96fbfa22d1994639164d743f0f00e6383d3b7b3144d333de960ff4afad0bddd0baaac257295e3316969eba995b1b6a1b4dec933e + languageName: node + linkType: hard + "@babel/preset-env@npm:7.28.3": version: 7.28.3 resolution: "@babel/preset-env@npm:7.28.3" @@ -2821,74 +3295,74 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:^7.28.3": - version: 7.28.5 - resolution: "@babel/preset-env@npm:7.28.5" +"@babel/preset-env@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/preset-env@npm:7.28.6" dependencies: - "@babel/compat-data": "npm:^7.28.5" - "@babel/helper-compilation-targets": "npm:^7.27.2" - "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" "@babel/helper-validator-option": "npm:^7.27.1" "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.28.5" "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.27.1" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.27.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.27.1" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.28.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.28.6" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.27.1" - "@babel/plugin-syntax-import-attributes": "npm:^7.27.1" + "@babel/plugin-syntax-import-assertions": "npm:^7.28.6" + "@babel/plugin-syntax-import-attributes": "npm:^7.28.6" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" - "@babel/plugin-transform-async-generator-functions": "npm:^7.28.0" - "@babel/plugin-transform-async-to-generator": "npm:^7.27.1" + "@babel/plugin-transform-async-generator-functions": "npm:^7.28.6" + "@babel/plugin-transform-async-to-generator": "npm:^7.28.6" "@babel/plugin-transform-block-scoped-functions": "npm:^7.27.1" - "@babel/plugin-transform-block-scoping": "npm:^7.28.5" - "@babel/plugin-transform-class-properties": "npm:^7.27.1" - "@babel/plugin-transform-class-static-block": "npm:^7.28.3" - "@babel/plugin-transform-classes": "npm:^7.28.4" - "@babel/plugin-transform-computed-properties": "npm:^7.27.1" + "@babel/plugin-transform-block-scoping": "npm:^7.28.6" + "@babel/plugin-transform-class-properties": "npm:^7.28.6" + "@babel/plugin-transform-class-static-block": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" + "@babel/plugin-transform-computed-properties": "npm:^7.28.6" "@babel/plugin-transform-destructuring": "npm:^7.28.5" - "@babel/plugin-transform-dotall-regex": "npm:^7.27.1" + "@babel/plugin-transform-dotall-regex": "npm:^7.28.6" "@babel/plugin-transform-duplicate-keys": "npm:^7.27.1" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.28.6" "@babel/plugin-transform-dynamic-import": "npm:^7.27.1" - "@babel/plugin-transform-explicit-resource-management": "npm:^7.28.0" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.28.5" + "@babel/plugin-transform-explicit-resource-management": "npm:^7.28.6" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.28.6" "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" "@babel/plugin-transform-for-of": "npm:^7.27.1" "@babel/plugin-transform-function-name": "npm:^7.27.1" - "@babel/plugin-transform-json-strings": "npm:^7.27.1" + "@babel/plugin-transform-json-strings": "npm:^7.28.6" "@babel/plugin-transform-literals": "npm:^7.27.1" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.28.5" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.28.6" "@babel/plugin-transform-member-expression-literals": "npm:^7.27.1" "@babel/plugin-transform-modules-amd": "npm:^7.27.1" - "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.28.6" "@babel/plugin-transform-modules-systemjs": "npm:^7.28.5" "@babel/plugin-transform-modules-umd": "npm:^7.27.1" "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.27.1" "@babel/plugin-transform-new-target": "npm:^7.27.1" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.27.1" - "@babel/plugin-transform-numeric-separator": "npm:^7.27.1" - "@babel/plugin-transform-object-rest-spread": "npm:^7.28.4" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.28.6" + "@babel/plugin-transform-numeric-separator": "npm:^7.28.6" + "@babel/plugin-transform-object-rest-spread": "npm:^7.28.6" "@babel/plugin-transform-object-super": "npm:^7.27.1" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.27.1" - "@babel/plugin-transform-optional-chaining": "npm:^7.28.5" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.28.6" + "@babel/plugin-transform-optional-chaining": "npm:^7.28.6" "@babel/plugin-transform-parameters": "npm:^7.27.7" - "@babel/plugin-transform-private-methods": "npm:^7.27.1" - "@babel/plugin-transform-private-property-in-object": "npm:^7.27.1" + "@babel/plugin-transform-private-methods": "npm:^7.28.6" + "@babel/plugin-transform-private-property-in-object": "npm:^7.28.6" "@babel/plugin-transform-property-literals": "npm:^7.27.1" - "@babel/plugin-transform-regenerator": "npm:^7.28.4" - "@babel/plugin-transform-regexp-modifiers": "npm:^7.27.1" + "@babel/plugin-transform-regenerator": "npm:^7.28.6" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.28.6" "@babel/plugin-transform-reserved-words": "npm:^7.27.1" "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" - "@babel/plugin-transform-spread": "npm:^7.27.1" + "@babel/plugin-transform-spread": "npm:^7.28.6" "@babel/plugin-transform-sticky-regex": "npm:^7.27.1" "@babel/plugin-transform-template-literals": "npm:^7.27.1" "@babel/plugin-transform-typeof-symbol": "npm:^7.27.1" "@babel/plugin-transform-unicode-escapes": "npm:^7.27.1" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.28.6" "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.28.6" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.14" babel-plugin-polyfill-corejs3: "npm:^0.13.0" @@ -2897,7 +3371,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d1b730158de290f1c54ed7db0f4fed3f82db5f868ab0a4cb3fc2ea76ed683b986ae136f6e7eb0b44b91bc9a99039a2559851656b4fd50193af1a815a3e32e524 + checksum: 10c0/a08f007c5e8c95beb10a4ab8ad8fdbd823c8ace5f24f491f69a10b6cad079825d39cd1bc9dd312680bbd5aa5f95095cce7d01f51e31bae6720039b11e8105ace languageName: node linkType: hard @@ -2927,7 +3401,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:^7.27.1": +"@babel/preset-react@npm:^7.28.5": version: 7.28.5 resolution: "@babel/preset-react@npm:7.28.5" dependencies: @@ -2973,10 +3447,10 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/runtime@npm:7.28.4" - checksum: 10c0/792ce7af9750fb9b93879cc9d1db175701c4689da890e6ced242ea0207c9da411ccf16dc04e689cc01158b28d7898c40d75598f4559109f761c12ce01e959bf7 +"@babel/runtime@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/runtime@npm:7.28.6" + checksum: 10c0/358cf2429992ac1c466df1a21c1601d595c46930a13c1d4662fde908d44ee78ec3c183aaff513ecb01ef8c55c3624afe0309eeeb34715672dbfadb7feedb2c0d languageName: node linkType: hard @@ -2991,6 +3465,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/template@npm:7.28.6" + dependencies: + "@babel/code-frame": "npm:^7.28.6" + "@babel/parser": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/66d87225ed0bc77f888181ae2d97845021838c619944877f7c4398c6748bcf611f216dfd6be74d39016af502bca876e6ce6873db3c49e4ac354c56d34d57e9f5 + languageName: node + linkType: hard + "@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3, @babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.25.4, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5": version: 7.28.5 resolution: "@babel/traverse@npm:7.28.5" @@ -3006,7 +3491,22 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.1.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/traverse@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/traverse@npm:7.28.6" + dependencies: + "@babel/code-frame": "npm:^7.28.6" + "@babel/generator": "npm:^7.28.6" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + debug: "npm:^4.3.1" + checksum: 10c0/ed5deb9c3f03e2d1ad2d44b9c92c84cce24593245c3f7871ce27ee1b36d98034e6cd895fa98a94eb44ebabe1d22f51b10b09432939d1c51a0fcaab98f17a97bc + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.1.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" dependencies: @@ -3016,6 +3516,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/types@npm:7.28.6" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/54a6a9813e48ef6f35aa73c03b3c1572cad7fa32b61b35dd07e4230bc77b559194519c8a4d8106a041a27cc7a94052579e238a30a32d5509aa4da4d6fd83d990 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -4281,7 +4791,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/shims@npm:^5.7.0": +"@ethersproject/shims@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/shims@npm:5.8.0" checksum: 10c0/4cb851dd366928694cfe186c782bf19015f5650758ba88541e0e50ec8188f82d6d5dfb7e22813989f1f46ebb2b19c30407b83639bba0aae9e9e131d2e046ea3e @@ -7001,9 +7511,9 @@ __metadata: languageName: node linkType: hard -"@peculiar/x509@npm:^1.12.3, @peculiar/x509@npm:^1.13.0": - version: 1.14.2 - resolution: "@peculiar/x509@npm:1.14.2" +"@peculiar/x509@npm:^1.14.3": + version: 1.14.3 + resolution: "@peculiar/x509@npm:1.14.3" dependencies: "@peculiar/asn1-cms": "npm:^2.6.0" "@peculiar/asn1-csr": "npm:^2.6.0" @@ -7016,7 +7526,7 @@ __metadata: reflect-metadata: "npm:^0.2.2" tslib: "npm:^2.8.1" tsyringe: "npm:^4.10.0" - checksum: 10c0/b62ecca8d7a3364f3541f8db811198877001480deca25fd90df77409e7c0bcaa08c7f12ce4401835b70e03014e8410fcc17a4fc49a09546dea5e55d7d1c61187 + checksum: 10c0/949231ca9daf84534bfe255f28a856df497302fed294d227c6a28e50f5cfb67ed1d91afe6db787b88294ce042295243dbcb44455fe2efa5ed07428a74392eec9 languageName: node linkType: hard @@ -7691,10 +8201,10 @@ __metadata: languageName: node linkType: hard -"@rolldown/pluginutils@npm:1.0.0-beta.27": - version: 1.0.0-beta.27 - resolution: "@rolldown/pluginutils@npm:1.0.0-beta.27" - checksum: 10c0/9658f235b345201d4f6bfb1f32da9754ca164f892d1cb68154fe5f53c1df42bd675ecd409836dff46884a7847d6c00bdc38af870f7c81e05bba5c2645eb4ab9c +"@rolldown/pluginutils@npm:1.0.0-beta.47": + version: 1.0.0-beta.47 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.47" + checksum: 10c0/eb0cfa7334d66f090c47eaac612174936b05f26e789352428cb6e03575b590f355de30d26b42576ea4e613d8887b587119d19b2e4b3a8909ceb232ca1cf746c8 languageName: node linkType: hard @@ -8232,6 +8742,7 @@ __metadata: resolution: "@selfxyz/circuits@workspace:circuits" dependencies: "@anon-aadhaar/core": "npm:@selfxyz/anon-aadhaar-core@^0.0.1" + "@babel/core": "npm:^7.28.6" "@noble/curves": "npm:^1.4.2" "@openpassport/zk-email-circuits": "npm:^6.1.2" "@openpassport/zk-kit-imt": "npm:^0.0.4" @@ -8266,6 +8777,8 @@ __metadata: crypto: "npm:^1.0.1" dotenv: "npm:^16.4.7" elliptic: "npm:^6.5.5" + eslint: "npm:^8.57.0" + eslint-plugin-import: "npm:^2.31.0" hash.js: "npm:^1.1.7" js-sha256: "npm:^0.10.1" jsrsasign: "npm:^11.1.0" @@ -8291,7 +8804,7 @@ __metadata: "@openpassport/zk-kit-imt": "npm:^0.0.5" "@openpassport/zk-kit-lean-imt": "npm:^0.0.6" "@openpassport/zk-kit-smt": "npm:^0.0.1" - "@peculiar/x509": "npm:^1.12.3" + "@peculiar/x509": "npm:^1.14.3" "@stablelib/cbor": "npm:^2.0.1" "@types/js-sha1": "npm:^0.6.3" "@types/node": "npm:^22.18.3" @@ -8302,7 +8815,7 @@ __metadata: "@zk-kit/baby-jubjub": "npm:^1.0.3" "@zk-kit/eddsa-poseidon": "npm:^1.1.0" asn1.js: "npm:^5.4.1" - asn1js: "npm:^3.0.5" + asn1js: "npm:^3.0.7" axios: "npm:^1.7.2" buffer: "npm:^6.0.3" country-emoji: "npm:^1.5.6" @@ -8324,12 +8837,12 @@ __metadata: jsrsasign: "npm:^11.1.0" node-forge: "github:remicolin/forge#17a11a632dd0e50343b3b8393245a2696f78afbb" path: "npm:^0.12.7" - pkijs: "npm:^3.2.4" + pkijs: "npm:^3.3.3" poseidon-lite: "npm:^0.2.0" prettier: "npm:^3.5.3" snarkjs: "npm:^0.7.5" tsup: "npm:^8.5.0" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" typescript-parser: "npm:^2.6.1" uuid: "npm:^11.1.0" vitest: "npm:^2.1.8" @@ -8416,7 +8929,7 @@ __metadata: js-sha1: "npm:^0.7.0" js-sha256: "npm:^0.11.0" js-sha512: "npm:^0.9.0" - node-forge: "npm:^1.3.1" + node-forge: "npm:^1.3.3" poseidon-lite: "npm:^0.3.0" prettier: "npm:^3.5.3" snarkjs: "npm:^0.7.4" @@ -8424,7 +8937,7 @@ __metadata: ts-node: "npm:^10.9.2" tsup: "npm:^8.5.0" typechain: "npm:^8.3.2" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^11.1.0" webpack: "npm:^5.95.0" languageName: unknown @@ -8447,21 +8960,21 @@ __metadata: version: 0.0.0-use.local resolution: "@selfxyz/mobile-app@workspace:app" dependencies: - "@babel/core": "npm:^7.28.3" - "@babel/plugin-syntax-flow": "npm:^7.27.1" - "@babel/plugin-transform-classes": "npm:^7.27.1" + "@babel/core": "npm:^7.28.6" + "@babel/plugin-syntax-flow": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" "@babel/plugin-transform-flow-strip-types": "npm:^7.27.1" - "@babel/plugin-transform-private-methods": "npm:^7.27.1" - "@babel/preset-env": "npm:^7.28.3" - "@babel/preset-react": "npm:^7.27.1" - "@babel/runtime": "npm:^7.28.3" - "@ethersproject/shims": "npm:^5.7.0" + "@babel/plugin-transform-private-methods": "npm:^7.28.6" + "@babel/preset-env": "npm:^7.28.6" + "@babel/preset-react": "npm:^7.28.5" + "@babel/runtime": "npm:^7.28.6" + "@ethersproject/shims": "npm:^5.8.0" "@noble/hashes": "npm:^1.5.0" "@openpassport/zk-kit-imt": "npm:^0.0.5" "@openpassport/zk-kit-lean-imt": "npm:^0.0.6" "@openpassport/zk-kit-smt": "npm:^0.0.1" - "@peculiar/x509": "npm:^1.13.0" + "@peculiar/x509": "npm:^1.14.3" "@react-native-async-storage/async-storage": "npm:^2.2.0" "@react-native-clipboard/clipboard": "npm:1.16.3" "@react-native-community/blur": "npm:^4.4.1" @@ -8484,7 +8997,7 @@ __metadata: "@selfxyz/euclid": "npm:^0.6.1" "@selfxyz/mobile-sdk-alpha": "workspace:^" "@sentry/react": "npm:^9.32.0" - "@sentry/react-native": "npm:7.0.1" + "@sentry/react-native": "npm:7.0.0" "@stablelib/cbor": "npm:^2.0.1" "@sumsub/react-native-mobilesdk-module": "npm:1.40.2" "@tamagui/animations-css": "npm:1.126.14" @@ -8515,17 +9028,17 @@ __metadata: "@types/react-test-renderer": "npm:^18" "@typescript-eslint/eslint-plugin": "npm:^8.39.0" "@typescript-eslint/parser": "npm:^8.39.0" - "@vitejs/plugin-react-swc": "npm:^3.10.2" + "@vitejs/plugin-react-swc": "npm:^4.2.2" "@walletconnect/react-native-compat": "npm:^2.23.0" "@xstate/react": "npm:^5.0.3" - asn1js: "npm:^3.0.6" + asn1js: "npm:^3.0.7" axios: "npm:^1.13.2" babel-plugin-module-resolver: "npm:^5.0.2" babel-plugin-transform-remove-console: "npm:^6.9.4" buffer: "npm:^6.0.3" constants-browserify: "npm:^1.0.0" country-emoji: "npm:^1.5.6" - dompurify: "npm:^3.2.6" + dompurify: "npm:^3.3.1" elliptic: "npm:^6.6.1" eslint: "npm:^8.57.0" eslint-config-prettier: "npm:10.1.8" @@ -8548,11 +9061,12 @@ __metadata: js-sha512: "npm:^0.9.0" lottie-react: "npm:^2.4.1" lottie-react-native: "npm:7.2.2" - node-forge: "npm:^1.3.1" + node-forge: "npm:^1.3.3" path-browserify: "npm:^1.0.1" - pkijs: "npm:^3.2.5" + pkijs: "npm:^3.3.3" poseidon-lite: "npm:^0.2.0" prettier: "npm:^3.5.3" + prop-types: "npm:^15.8.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-native: "npm:0.76.9" @@ -8561,7 +9075,7 @@ __metadata: react-native-blur-effect: "npm:^1.1.3" react-native-check-version: "npm:^1.3.0" react-native-cloud-storage: "npm:^2.2.2" - react-native-device-info: "npm:^14.0.4" + react-native-device-info: "npm:^15.0.1" react-native-dotenv: "npm:^3.4.11" react-native-edge-to-edge: "npm:^1.7.0" react-native-gesture-handler: "npm:2.19.0" @@ -8570,31 +9084,31 @@ __metadata: react-native-inappbrowser-reborn: "npm:^3.7.0" react-native-keychain: "npm:^10.0.0" react-native-linear-gradient: "npm:^2.8.3" - react-native-localize: "npm:^3.5.2" - react-native-logs: "npm:^5.3.0" - react-native-nfc-manager: "npm:3.16.3" - react-native-passkey: "npm:^3.3.1" + react-native-localize: "npm:^3.6.1" + react-native-logs: "npm:^5.5.0" + react-native-nfc-manager: "npm:3.17.2" + react-native-passkey: "npm:^3.3.2" react-native-passport-reader: "npm:1.0.3" - react-native-safe-area-context: "npm:^5.6.1" + react-native-safe-area-context: "npm:^5.6.2" react-native-screens: "npm:4.15.3" react-native-sqlite-storage: "npm:^6.0.1" - react-native-svg: "npm:15.15.0" - react-native-svg-transformer: "npm:^1.5.1" + react-native-svg: "npm:15.12.1" + react-native-svg-transformer: "npm:^1.5.2" react-native-svg-web: "npm:1.0.9" react-native-url-polyfill: "npm:^3.0.0" - react-native-web: "npm:^0.19.0" + react-native-web: "npm:^0.21.2" react-native-webview: "npm:^13.16.0" react-qr-barcode-scanner: "npm:^2.1.8" react-test-renderer: "npm:^18.3.1" - rollup-plugin-visualizer: "npm:^6.0.3" + rollup-plugin-visualizer: "npm:^6.0.5" socket.io-client: "npm:^4.8.3" stream-browserify: "npm:^3.0.0" tamagui: "npm:1.126.14" ts-morph: "npm:^22.0.0" ts-node: "npm:^10.9.2" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^11.1.0" - vite: "npm:^7.0.0" + vite: "npm:^7.3.1" vite-plugin-svgr: "npm:^4.5.0" xstate: "npm:^5.20.2" zustand: "npm:^4.5.2" @@ -8605,7 +9119,7 @@ __metadata: version: 0.0.0-use.local resolution: "@selfxyz/mobile-sdk-alpha@workspace:packages/mobile-sdk-alpha" dependencies: - "@babel/runtime": "npm:^7.28.3" + "@babel/runtime": "npm:^7.28.6" "@openpassport/zk-kit-lean-imt": "npm:^0.0.6" "@selfxyz/common": "workspace:^" "@selfxyz/euclid": "npm:^0.6.1" @@ -8625,20 +9139,23 @@ __metadata: eslint-plugin-sort-exports: "npm:^0.9.1" jsdom: "npm:^25.0.1" lottie-react-native: "npm:7.2.2" - node-forge: "npm:^1.3.1" + node-forge: "npm:^1.3.3" poseidon-lite: "npm:^0.3.0" prettier: "npm:^3.5.3" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-native: "npm:0.76.9" + react-native-blur-effect: "npm:^1.1.3" react-native-haptic-feedback: "npm:^2.3.3" - react-native-localize: "npm:^3.5.2" - react-native-nfc-manager: "npm:^3.17.1" + react-native-localize: "npm:^3.6.1" + react-native-nfc-manager: "npm:^3.17.2" + react-native-svg: "npm:15.15.1" react-native-svg-circle-country-flags: "npm:^0.2.2" - react-native-web: "npm:^0.21.1" - socket.io-client: "npm:^4.8.1" + react-native-web: "npm:^0.21.2" + react-native-webview: "npm:13.16.0" + socket.io-client: "npm:^4.8.3" tsup: "npm:^8.0.1" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^11.1.0" vitest: "npm:^2.1.8" xstate: "npm:^5.20.2" @@ -8686,9 +9203,9 @@ __metadata: ngx-lottie: "npm:^20.0.0" prettier: "npm:^3.5.3" rxjs: "npm:^7.8.0" - socket.io-client: "npm:^4.8.1" + socket.io-client: "npm:^4.8.3" tslib: "npm:^2.6.0" - typescript: "npm:~5.9.0" + typescript: "npm:~5.9.3" uuid: "npm:^11.1.0" zone.js: "npm:^0.15.0" peerDependencies: @@ -8725,7 +9242,7 @@ __metadata: js-sha512: "npm:^0.9.0" lottie-react: "npm:^2.4.0" mocha: "npm:^10.7.3" - node-forge: "npm:^1.3.1" + node-forge: "npm:^1.3.3" poseidon-lite: "npm:^0.3.0" prettier: "npm:^3.5.3" qrcode.react: "npm:^4.1.0" @@ -8733,12 +9250,12 @@ __metadata: react-dom: "npm:>=18.0.0 <20.0.0" react-spinners: "npm:^0.14.1" size-limit: "npm:^11.2.0" - socket.io-client: "npm:^4.8.1" + socket.io-client: "npm:^4.8.3" ts-loader: "npm:^9.5.1" ts-mocha: "npm:^10.0.0" ts-node: "npm:^10.9.2" tsup: "npm:^8.5.0" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^11.1.0" webpack: "npm:^5.95.0" peerDependencies: @@ -8752,7 +9269,7 @@ __metadata: version: 0.0.0-use.local resolution: "@selfxyz/sdk-common@workspace:sdk/sdk-common" dependencies: - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^13.0.0" languageName: unknown linkType: soft @@ -8833,10 +9350,10 @@ __metadata: languageName: node linkType: hard -"@sentry/babel-plugin-component-annotate@npm:4.3.0": - version: 4.3.0 - resolution: "@sentry/babel-plugin-component-annotate@npm:4.3.0" - checksum: 10c0/3b75b9fe408d777f2a1601c636c980bec46cbca7d80715b5cb4a32c51173d8b400886637ef1453627408dc10884289c7e186267775737e08a23851ed9485c956 +"@sentry/babel-plugin-component-annotate@npm:4.2.0": + version: 4.2.0 + resolution: "@sentry/babel-plugin-component-annotate@npm:4.2.0" + checksum: 10c0/595a46e9436665371c668a7522ca59ee1b37bf72ac79d762de6e148f7ca2c6e7f67cee0cb07c3f42c35286401b0dd74e85e1a29368812befa8e66d3b35b83b50 languageName: node linkType: hard @@ -9028,11 +9545,11 @@ __metadata: languageName: node linkType: hard -"@sentry/react-native@npm:7.0.1": - version: 7.0.1 - resolution: "@sentry/react-native@npm:7.0.1" +"@sentry/react-native@npm:7.0.0": + version: 7.0.0 + resolution: "@sentry/react-native@npm:7.0.0" dependencies: - "@sentry/babel-plugin-component-annotate": "npm:4.3.0" + "@sentry/babel-plugin-component-annotate": "npm:4.2.0" "@sentry/browser": "npm:10.8.0" "@sentry/cli": "npm:2.53.0" "@sentry/core": "npm:10.8.0" @@ -9047,7 +9564,7 @@ __metadata: optional: true bin: sentry-expo-upload-sourcemaps: scripts/expo-upload-sourcemaps.js - checksum: 10c0/c8d877c8a64d01777ba68ae75594140ee1795b53cbe6130bc1319bab56ce92a63404fe346231efa42e030ecf05f969a02d40eb175495553bc3c32c1853d1f8b6 + checksum: 10c0/3b74712c9d79467aea969394b5bda1b2d954ac94997274abb686b0ba299341cfd3e96032eee71951e6e6627c02d3f6c947f617bae317ef2050618a04730a3c5b languageName: node linkType: hard @@ -13835,16 +14352,7 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:>=18.0.0 <20.0.0": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" - peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 - languageName: node - linkType: hard - -"@types/react-dom@npm:^18.0.0, @types/react-dom@npm:^18.3.0": +"@types/react-dom@npm:^18.3.0": version: 18.3.7 resolution: "@types/react-dom@npm:18.3.7" peerDependencies: @@ -14548,15 +15056,15 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-react-swc@npm:^3.10.2": - version: 3.11.0 - resolution: "@vitejs/plugin-react-swc@npm:3.11.0" +"@vitejs/plugin-react-swc@npm:^4.2.2": + version: 4.2.2 + resolution: "@vitejs/plugin-react-swc@npm:4.2.2" dependencies: - "@rolldown/pluginutils": "npm:1.0.0-beta.27" - "@swc/core": "npm:^1.12.11" + "@rolldown/pluginutils": "npm:1.0.0-beta.47" + "@swc/core": "npm:^1.13.5" peerDependencies: vite: ^4 || ^5 || ^6 || ^7 - checksum: 10c0/0d12ee81f8c8acb74b35e7acfc45d23ecc2714ab3a0f6060e4bd900a6a739dd5a9be9c6bc842388f3c406f475f2a83e7ff3ade04ec6df9172faa1242e4faa424 + checksum: 10c0/fe6346df2659007fab2b4840716b8b15cb1e33aa23865998e0295750a98eaf6090c6b04d90e9f1efd91bc71d057a7bb89fbd008476b727fd20b68e06cac75fa0 languageName: node linkType: hard @@ -16222,7 +16730,7 @@ __metadata: languageName: node linkType: hard -"asn1js@npm:^3.0.5, asn1js@npm:^3.0.6": +"asn1js@npm:^3.0.5, asn1js@npm:^3.0.6, asn1js@npm:^3.0.7": version: 3.0.7 resolution: "asn1js@npm:3.0.7" dependencies: @@ -19264,7 +19772,7 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:*, dompurify@npm:^3.2.6": +"dompurify@npm:*, dompurify@npm:^3.3.1": version: 3.3.1 resolution: "dompurify@npm:3.3.1" dependencies: @@ -21319,13 +21827,6 @@ __metadata: languageName: node linkType: hard -"fast-loops@npm:^1.1.3": - version: 1.1.4 - resolution: "fast-loops@npm:1.1.4" - checksum: 10c0/25e8a608fccc0d84c1d037efa715ab1e6f21576e1070931b3ed966657204c47ed2b1cba16e5c46ddde2d62aba0b4100d86616d995318b7367fa0a902a78ed885 - languageName: node - linkType: hard - "fast-text-encoding@npm:1.0.6": version: 1.0.6 resolution: "fast-text-encoding@npm:1.0.6" @@ -23352,16 +23853,6 @@ __metadata: languageName: node linkType: hard -"inline-style-prefixer@npm:^6.0.1": - version: 6.0.4 - resolution: "inline-style-prefixer@npm:6.0.4" - dependencies: - css-in-js-utils: "npm:^3.1.0" - fast-loops: "npm:^1.1.3" - checksum: 10c0/d3d42bf0c48d621ea4bcfb077b5d370b106995422300a3a472674f96c9b489d96b4aac6f29dea3bb26ff2dfd7293e4752098bc2b53407769eafdb66c6c4c1764 - languageName: node - linkType: hard - "inline-style-prefixer@npm:^7.0.1": version: 7.0.1 resolution: "inline-style-prefixer@npm:7.0.1" @@ -26808,8 +27299,8 @@ __metadata: version: 0.0.0-use.local resolution: "mobile-sdk-demo@workspace:packages/mobile-sdk-demo" dependencies: - "@babel/core": "npm:^7.28.3" - "@babel/runtime": "npm:^7.28.3" + "@babel/core": "npm:^7.28.6" + "@babel/runtime": "npm:^7.28.6" "@faker-js/faker": "npm:^10.0.0" "@noble/hashes": "npm:^1.5.0" "@react-native-async-storage/async-storage": "npm:^2.2.0" @@ -26854,14 +27345,14 @@ __metadata: react-native-get-random-values: "npm:^1.11.0" react-native-haptic-feedback: "npm:^2.3.3" react-native-keychain: "npm:^10.0.0" - react-native-localize: "npm:^3.5.4" - react-native-safe-area-context: "npm:^5.6.1" - react-native-svg: "npm:15.12.1" - react-native-svg-transformer: "npm:^1.5.1" + react-native-localize: "npm:^3.6.1" + react-native-safe-area-context: "npm:^5.6.2" + react-native-svg: "npm:15.15.1" + react-native-svg-transformer: "npm:^1.5.2" react-native-vector-icons: "npm:^10.3.0" react-native-webview: "npm:13.16.0" stream-browserify: "npm:^3.0.0" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" util: "npm:^0.12.5" vitest: "npm:^2.1.8" languageName: unknown @@ -27343,7 +27834,7 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1, node-forge@npm:^1.3.1": +"node-forge@npm:^1, node-forge@npm:^1.3.1, node-forge@npm:^1.3.3": version: 1.3.3 resolution: "node-forge@npm:1.3.3" checksum: 10c0/9c6f53b0ebb34865872cf62a35b0aef8fb337e2efc766626c2e3a0040f4c02933bf29a62ba999eb44a2aca73bd512c4eda22705a47b94654b9fb8ed53db9a1db @@ -28767,7 +29258,7 @@ __metadata: languageName: node linkType: hard -"pkijs@npm:^3.2.4, pkijs@npm:^3.2.5": +"pkijs@npm:^3.3.3": version: 3.3.3 resolution: "pkijs@npm:3.3.3" dependencies: @@ -29597,12 +30088,12 @@ __metadata: languageName: node linkType: hard -"react-native-device-info@npm:^14.0.4": - version: 14.1.1 - resolution: "react-native-device-info@npm:14.1.1" +"react-native-device-info@npm:^15.0.1": + version: 15.0.1 + resolution: "react-native-device-info@npm:15.0.1" peerDependencies: react-native: "*" - checksum: 10c0/38ae82b2364b8af5b5cfdd142842bb7dd53b2e37b7225b375ac2f5ebf9272c5250fec2fb08cb58af494339c2341de617393717fc5488c575a5b9d817237d7f54 + checksum: 10c0/f33a28b44bc9a67939f2c837ea55c6f59f3096323b5ccc834093bece941d343bad3d86b0faa9340004c2e657abe47fac6cee539d9274f5fabfb5745bfdc77c92 languageName: node linkType: hard @@ -29701,9 +30192,9 @@ __metadata: languageName: node linkType: hard -"react-native-localize@npm:^3.5.2, react-native-localize@npm:^3.5.4": - version: 3.6.0 - resolution: "react-native-localize@npm:3.6.0" +"react-native-localize@npm:^3.6.1": + version: 3.6.1 + resolution: "react-native-localize@npm:3.6.1" peerDependencies: "@expo/config-plugins": "*" react: "*" @@ -29714,30 +30205,18 @@ __metadata: optional: true react-native-macos: optional: true - checksum: 10c0/3ab63261152f56a9ef9d7413f206b50615483d2fa2f0f07b4fda34b3f95bd66d54c1ec35c8eb445326252855db0299ff6fdb7167422711bb0337994d9605a94d + checksum: 10c0/d36f00c07d390aa86e72064266d4b21924920a900647bb99175aeccc7f67aad8e4fcebc7c4a932f3faf97221a0e3df78bd08f204bd4ba6fc5afc8386c8d4be71 languageName: node linkType: hard -"react-native-logs@npm:^5.3.0": +"react-native-logs@npm:^5.5.0": version: 5.5.0 resolution: "react-native-logs@npm:5.5.0" checksum: 10c0/38b011a5cff39c672821baa15bf09e6a98caeab0b64cf6778fcf765f89382799b04dcb604399d016940796106d4187411add84d1de485dd38655c5dc9fc078c9 languageName: node linkType: hard -"react-native-nfc-manager@npm:3.16.3": - version: 3.16.3 - resolution: "react-native-nfc-manager@npm:3.16.3" - peerDependencies: - "@expo/config-plugins": 9 || 10 - peerDependenciesMeta: - "@expo/config-plugins": - optional: true - checksum: 10c0/11f86b564cbd9b2cc8d8f54b069d2985b2eb491cf815136583641c8d10fcf19fc3c49b2c467de40a5324ba24daf83aed587b32bb04975e795ede0a76bd718e74 - languageName: node - linkType: hard - -"react-native-nfc-manager@npm:^3.17.1": +"react-native-nfc-manager@npm:3.17.2, react-native-nfc-manager@npm:^3.17.2": version: 3.17.2 resolution: "react-native-nfc-manager@npm:3.17.2" peerDependencies: @@ -29766,7 +30245,7 @@ __metadata: languageName: node linkType: hard -"react-native-safe-area-context@npm:^5.6.1": +"react-native-safe-area-context@npm:^5.6.2": version: 5.6.2 resolution: "react-native-safe-area-context@npm:5.6.2" peerDependencies: @@ -29810,7 +30289,7 @@ __metadata: languageName: node linkType: hard -"react-native-svg-transformer@npm:^1.5.1": +"react-native-svg-transformer@npm:^1.5.2": version: 1.5.2 resolution: "react-native-svg-transformer@npm:1.5.2" dependencies: @@ -29850,9 +30329,9 @@ __metadata: languageName: node linkType: hard -"react-native-svg@npm:15.15.0": - version: 15.15.0 - resolution: "react-native-svg@npm:15.15.0" +"react-native-svg@npm:15.15.1": + version: 15.15.1 + resolution: "react-native-svg@npm:15.15.1" dependencies: css-select: "npm:^5.1.0" css-tree: "npm:^1.1.3" @@ -29860,7 +30339,7 @@ __metadata: peerDependencies: react: "*" react-native: "*" - checksum: 10c0/0da39529fedcc84d2deaad19e261453069675520cb446a08d97eebc10f1205ce0393a9760ad58bc7b80feaa60e94c30d2d5b90d3111451f260b3888a4fbc2e06 + checksum: 10c0/9e047e8afdd5121296a3402c5c37363b9b37fbddc41f7b0b49b923ac4d2898954c8b57a6784a625321236987e494ee54f594e22f9de815f807e03a3433d7fefd languageName: node linkType: hard @@ -29901,25 +30380,6 @@ __metadata: languageName: node linkType: hard -"react-native-web@npm:^0.19.0": - version: 0.19.13 - resolution: "react-native-web@npm:0.19.13" - dependencies: - "@babel/runtime": "npm:^7.18.6" - "@react-native/normalize-colors": "npm:^0.74.1" - fbjs: "npm:^3.0.4" - inline-style-prefixer: "npm:^6.0.1" - memoize-one: "npm:^6.0.0" - nullthrows: "npm:^1.1.1" - postcss-value-parser: "npm:^4.2.0" - styleq: "npm:^0.1.3" - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: 10c0/55e82a6f656843b2b4f6e4c4006a82ae8feed548e880e9fa3c2623da415d3abd9399c91c5360b71d5f24f47c5cbe30872a3ad785fa1a32cf152383d595f8ebd5 - languageName: node - linkType: hard - "react-native-web@npm:^0.20.0": version: 0.20.0 resolution: "react-native-web@npm:0.20.0" @@ -29939,7 +30399,7 @@ __metadata: languageName: node linkType: hard -"react-native-web@npm:^0.21.1": +"react-native-web@npm:^0.21.2": version: 0.21.2 resolution: "react-native-web@npm:0.21.2" dependencies: @@ -30702,7 +31162,7 @@ __metadata: languageName: node linkType: hard -"rollup-plugin-visualizer@npm:^6.0.3": +"rollup-plugin-visualizer@npm:^6.0.5": version: 6.0.5 resolution: "rollup-plugin-visualizer@npm:6.0.5" dependencies: @@ -31154,7 +31614,7 @@ __metadata: version: 0.0.0-use.local resolution: "self-workspace-root@workspace:." dependencies: - "@babel/runtime": "npm:^7.28.3" + "@babel/runtime": "npm:^7.28.6" "@react-native-community/cli-server-api": "npm:^16.0.3" "@types/node": "npm:^22.18.3" gitleaks: "npm:1.0.0" @@ -31166,7 +31626,7 @@ __metadata: react: "npm:^18.3.1" react-native: "npm:0.76.9" tsx: "npm:^4.21.0" - typescript: "npm:^5.9.2" + typescript: "npm:^5.9.3" uuid: "npm:^13.0.0" languageName: unknown linkType: soft @@ -31792,7 +32252,7 @@ __metadata: languageName: node linkType: hard -"socket.io-client@npm:^4.8.1, socket.io-client@npm:^4.8.3": +"socket.io-client@npm:^4.8.3": version: 4.8.3 resolution: "socket.io-client@npm:4.8.3" dependencies: @@ -33759,7 +34219,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.8.2, typescript@npm:^5.9.2, typescript@npm:~5.9.0": +"typescript@npm:^5.8.2, typescript@npm:^5.9.2, typescript@npm:^5.9.3, typescript@npm:~5.9.3": version: 5.9.3 resolution: "typescript@npm:5.9.3" bin: @@ -33779,7 +34239,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.8.2#optional!builtin, typescript@patch:typescript@npm%3A^5.9.2#optional!builtin, typescript@patch:typescript@npm%3A~5.9.0#optional!builtin": +"typescript@patch:typescript@npm%3A^5.8.2#optional!builtin, typescript@patch:typescript@npm%3A^5.9.2#optional!builtin, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin, typescript@patch:typescript@npm%3A~5.9.3#optional!builtin": version: 5.9.3 resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" bin: @@ -34498,9 +34958,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^7.0.0": - version: 7.3.0 - resolution: "vite@npm:7.3.0" +"vite@npm:^7.3.1": + version: 7.3.1 + resolution: "vite@npm:7.3.1" dependencies: esbuild: "npm:^0.27.0" fdir: "npm:^6.5.0" @@ -34549,7 +35009,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/0457c196cdd5761ec351c0f353945430fbad330e615b9eeab729c8ae163334f18acdc1d9cd7d9d673dbf111f07f6e4f0b25d4ac32360e65b4a6df9991046f3ff + checksum: 10c0/5c7548f5f43a23533e53324304db4ad85f1896b1bfd3ee32ae9b866bac2933782c77b350eb2b52a02c625c8ad1ddd4c000df077419410650c982cd97fde8d014 languageName: node linkType: hard From c7c9985d915c1b9cfb1270b675be04808eff7099 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Wed, 28 Jan 2026 20:10:50 -0800 Subject: [PATCH 4/6] SELF-1889: Initiate Sumsub during onboarding error flows (#1662) * integrate sumsub into error flows * formatting * fix test * format * clean up * udpate flows * agent feedback * updates * save wip updates * clean up design * updates * lint * agent feedback * formatting * fix --- app/metro.config.cjs | 3 + app/src/hooks/useErrorInjection.ts | 27 ++ app/src/hooks/useSumsubLauncher.ts | 127 +++++++ app/src/navigation/documents.ts | 12 + app/src/navigation/index.tsx | 11 + app/src/providers/selfClientProvider.tsx | 103 +++++- app/src/screens/app/LoadingScreen.tsx | 4 +- app/src/screens/dev/DevSettingsScreen.tsx | 162 +++++++++ .../scanning/DocumentCameraTroubleScreen.tsx | 40 ++- .../scanning/DocumentNFCScanScreen.tsx | 37 +- .../scanning/DocumentNFCTroubleScreen.tsx | 32 +- .../scanning/RegistrationFallbackScreen.tsx | 326 ++++++++++++++++++ app/src/stores/errorInjectionStore.ts | 103 ++++++ app/tests/src/navigation.test.tsx | 1 + packages/mobile-sdk-alpha/src/client.ts | 2 + .../mobile-sdk-alpha/src/config/defaults.ts | 2 +- packages/mobile-sdk-alpha/src/config/merge.ts | 5 +- .../src/flows/onboarding/read-mrz.ts | 29 +- packages/mobile-sdk-alpha/src/index.ts | 1 + packages/mobile-sdk-alpha/src/types/public.ts | 15 + .../mobile-sdk-alpha/tests/config.test.ts | 2 +- 21 files changed, 1006 insertions(+), 38 deletions(-) create mode 100644 app/src/hooks/useErrorInjection.ts create mode 100644 app/src/hooks/useSumsubLauncher.ts create mode 100644 app/src/screens/documents/scanning/RegistrationFallbackScreen.tsx create mode 100644 app/src/stores/errorInjectionStore.ts diff --git a/app/metro.config.cjs b/app/metro.config.cjs index 24797c027..f86597c98 100644 --- a/app/metro.config.cjs +++ b/app/metro.config.cjs @@ -72,6 +72,9 @@ const config = { new RegExp( 'packages/mobile-sdk-alpha/node_modules/react-native-svg(/|$)', ), + new RegExp( + 'packages/mobile-sdk-alpha/node_modules/react-native-webview(/|$)', + ), new RegExp('packages/mobile-sdk-demo/node_modules/react(/|$)'), new RegExp('packages/mobile-sdk-demo/node_modules/react-dom(/|$)'), new RegExp('packages/mobile-sdk-demo/node_modules/react-native(/|$)'), diff --git a/app/src/hooks/useErrorInjection.ts b/app/src/hooks/useErrorInjection.ts new file mode 100644 index 000000000..763e1954a --- /dev/null +++ b/app/src/hooks/useErrorInjection.ts @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import { useCallback } from 'react'; + +import type { InjectedErrorType } from '@/stores/errorInjectionStore'; +import { useErrorInjectionStore } from '@/stores/errorInjectionStore'; +import { IS_DEV_MODE } from '@/utils/devUtils'; + +/** + * Hook for checking if a specific error should be injected + * Only active in dev mode + */ +export function useErrorInjection() { + const injectedErrors = useErrorInjectionStore(state => state.injectedErrors); + + const shouldInjectError = useCallback( + (errorType: InjectedErrorType): boolean => { + if (!IS_DEV_MODE) return false; + return injectedErrors.includes(errorType); + }, + [injectedErrors], + ); + + return { shouldInjectError }; +} diff --git a/app/src/hooks/useSumsubLauncher.ts b/app/src/hooks/useSumsubLauncher.ts new file mode 100644 index 000000000..c5cad2260 --- /dev/null +++ b/app/src/hooks/useSumsubLauncher.ts @@ -0,0 +1,127 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import { useCallback, useState } from 'react'; +import { useNavigation } from '@react-navigation/native'; +import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; + +import { sanitizeErrorMessage } from '@selfxyz/mobile-sdk-alpha'; + +import { fetchAccessToken, launchSumsub } from '@/integrations/sumsub'; +import type { SumsubResult } from '@/integrations/sumsub/types'; +import type { RootStackParamList } from '@/navigation'; + +export type FallbackErrorSource = + | 'mrz_scan_failed' + | 'nfc_scan_failed' + | 'sumsub_initialization' + | 'sumsub_verification'; + +export interface UseSumsubLauncherOptions { + /** + * Country code for the user's document + */ + countryCode: string; + /** + * Error source to track where the Sumsub launch was initiated from + */ + errorSource: FallbackErrorSource; + /** + * Optional callback to handle successful verification + */ + onSuccess?: (result: SumsubResult) => void | Promise; + /** + * Optional callback to handle user cancellation + */ + onCancel?: () => void | Promise; + /** + * Optional callback to handle verification failure + */ + onError?: (error: unknown, result?: SumsubResult) => void | Promise; +} + +/** + * Custom hook for launching Sumsub verification with consistent error handling. + * + * Abstracts the common pattern of: + * 1. Fetching access token + * 2. Launching Sumsub SDK + * 3. Handling errors by navigating to fallback screen + * 4. Managing loading state + * + * @example + * ```tsx + * const { launchSumsubVerification, isLoading } = useSumsubLauncher({ + * countryCode: 'US', + * errorSource: 'nfc_scan_failed', + * }); + * + * + * ``` + */ +export const useSumsubLauncher = (options: UseSumsubLauncherOptions) => { + const { countryCode, errorSource, onSuccess, onCancel, onError } = options; + const navigation = + useNavigation>(); + const [isLoading, setIsLoading] = useState(false); + + const launchSumsubVerification = useCallback(async () => { + setIsLoading(true); + try { + const accessToken = await fetchAccessToken(); + const result = await launchSumsub({ accessToken: accessToken.token }); + + // Handle user cancellation + if (!result.success && result.status === 'Interrupted') { + await onCancel?.(); + return; + } + + // Handle verification failure + if (!result.success) { + const error = result.errorMsg || result.errorType || 'Unknown error'; + const safeError = sanitizeErrorMessage(error); + console.error('Sumsub verification failed:', safeError); + + // Call custom error handler if provided, otherwise navigate to fallback screen + if (onError) { + await onError(safeError, result); + } else { + navigation.navigate('RegistrationFallback', { + errorSource, + countryCode, + }); + } + return; + } + + // Handle success + await onSuccess?.(result); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error); + const safeError = sanitizeErrorMessage(errorMessage); + console.error('Error launching alternative verification:', safeError); + + // Call custom error handler if provided, otherwise navigate to fallback screen + if (onError) { + await onError(safeError); + } else { + navigation.navigate('RegistrationFallback', { + errorSource, + countryCode, + }); + } + } finally { + setIsLoading(false); + } + }, [navigation, countryCode, errorSource, onSuccess, onCancel, onError]); + + return { + launchSumsubVerification, + isLoading, + }; +}; diff --git a/app/src/navigation/documents.ts b/app/src/navigation/documents.ts index ed9faeab4..a80aaeecc 100644 --- a/app/src/navigation/documents.ts +++ b/app/src/navigation/documents.ts @@ -19,6 +19,7 @@ import DocumentCameraTroubleScreen from '@/screens/documents/scanning/DocumentCa import DocumentNFCMethodSelectionScreen from '@/screens/documents/scanning/DocumentNFCMethodSelectionScreen'; import DocumentNFCScanScreen from '@/screens/documents/scanning/DocumentNFCScanScreen'; import DocumentNFCTroubleScreen from '@/screens/documents/scanning/DocumentNFCTroubleScreen'; +import RegistrationFallbackScreen from '@/screens/documents/scanning/RegistrationFallbackScreen'; import ConfirmBelongingScreen from '@/screens/documents/selection/ConfirmBelongingScreen'; import CountryPickerScreen from '@/screens/documents/selection/CountryPickerScreen'; import DocumentOnboardingScreen from '@/screens/documents/selection/DocumentOnboardingScreen'; @@ -155,6 +156,17 @@ const documentsScreens = { errorType: 'general', }, }, + RegistrationFallback: { + screen: RegistrationFallbackScreen, + options: { + title: 'REGISTRATION', + headerShown: false, + } as NativeStackNavigationOptions, + initialParams: { + errorSource: 'sumsub_initialization', + countryCode: '', + }, + }, }; export default documentsScreens; diff --git a/app/src/navigation/index.tsx b/app/src/navigation/index.tsx index 67273f933..65d68e114 100644 --- a/app/src/navigation/index.tsx +++ b/app/src/navigation/index.tsx @@ -79,6 +79,7 @@ export type RootStackParamList = Omit< | 'Home' | 'IDPicker' | 'IdDetails' + | 'RegistrationFallback' | 'Loading' | 'Modal' | 'MockDataDeepLink' @@ -127,6 +128,16 @@ export type RootStackParamList = Omit< errorType: string; }; + // Registration Fallback screens + RegistrationFallback: { + errorSource: + | 'mrz_scan_failed' + | 'nfc_scan_failed' + | 'sumsub_initialization' + | 'sumsub_verification'; + countryCode: string; + }; + // Account/Recovery screens AccountRecovery: | { diff --git a/app/src/providers/selfClientProvider.tsx b/app/src/providers/selfClientProvider.tsx index 94ca68aff..106133216 100644 --- a/app/src/providers/selfClientProvider.tsx +++ b/app/src/providers/selfClientProvider.tsx @@ -13,9 +13,11 @@ import { type LogLevel, type NFCScanContext, reactNativeScannerAdapter, + sanitizeErrorMessage, SdkEvents, SelfClientProvider as SDKSelfClientProvider, type TrackEventParams, + useMRZStore, webNFCScannerShim, type WsConn, } from '@selfxyz/mobile-sdk-alpha'; @@ -33,7 +35,12 @@ import { setPassportKeychainErrorCallback, } from '@/providers/passportDataProvider'; import { trackEvent, trackNfcEvent } from '@/services/analytics'; +import { + type InjectedErrorType, + useErrorInjectionStore, +} from '@/stores/errorInjectionStore'; import { useSettingStore } from '@/stores/settingStore'; +import { IS_DEV_MODE } from '@/utils/devUtils'; import { registerModalCallbacks, unregisterModalCallbacks, @@ -68,7 +75,20 @@ function navigateIfReady( } export const SelfClientProvider = ({ children }: PropsWithChildren) => { - const config = useMemo(() => ({}), []); + const config = useMemo( + () => ({ + devConfig: IS_DEV_MODE + ? { + shouldTrigger: (errorType: string) => { + return useErrorInjectionStore + .getState() + .shouldTrigger(errorType as InjectedErrorType); + }, + } + : undefined, + }), + [], + ); const adapters: Adapters = useMemo( () => ({ scanner: @@ -167,6 +187,9 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => { const appListeners = useMemo(() => { const { map, addListener } = createListenersMap(); + // Track current countryCode for error navigation + let currentCountryCode = ''; + addListener(SdkEvents.PROVING_PASSPORT_DATA_NOT_FOUND, () => { if (navigationRef.isReady()) { navigationRef.navigate('DocumentDataNotFound'); @@ -261,7 +284,10 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => { }); addListener(SdkEvents.DOCUMENT_MRZ_READ_FAILURE, () => { - navigateIfReady('DocumentCameraTrouble'); + navigateIfReady('RegistrationFallback', { + errorSource: 'mrz_scan_failed', + countryCode: currentCountryCode, + }); }); addListener(SdkEvents.PROVING_AADHAAR_UPLOAD_SUCCESS, () => { @@ -280,6 +306,9 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => { countryCode: string; documentTypes: string[]; }) => { + currentCountryCode = countryCode; + // Store country code early so it's available for Sumsub fallback flows + useMRZStore.getState().update({ countryCode }); navigateIfReady('IDPicker', { countryCode, documentTypes }); }, ); @@ -300,14 +329,68 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => { } break; case 'kyc': - fetchAccessToken() - .then(accessToken => { - launchSumsub({ accessToken: accessToken.token }); - }) - // TODO: show sumsub error screen - .catch(error => { - console.error('Error launching Sumsub:', error); - }); + (async () => { + try { + // Dev-only: Check for injected initialization error + if ( + useErrorInjectionStore + .getState() + .shouldTrigger('sumsub_initialization') + ) { + console.log('[DEV] Injecting Sumsub initialization error'); + throw new Error( + 'Injected Sumsub initialization error for testing', + ); + } + + const accessToken = await fetchAccessToken(); + const result = await launchSumsub({ + accessToken: accessToken.token, + }); + + // User cancelled - return silently + if (!result.success && result.status === 'Interrupted') { + return; + } + + // Dev-only: Check for injected verification error + const shouldInjectVerificationError = useErrorInjectionStore + .getState() + .shouldTrigger('sumsub_verification'); + + // Actual error from provider + if (!result.success || shouldInjectVerificationError) { + if (shouldInjectVerificationError) { + console.log('[DEV] Injecting Sumsub verification error'); + } else { + const safeError = sanitizeErrorMessage( + result.errorMsg || result.errorType || 'unknown_error', + ); + console.error('KYC provider failed:', safeError); + } + // Guard navigation call after async operations + if (navigationRef.isReady()) { + navigationRef.navigate('RegistrationFallback', { + errorSource: 'sumsub_verification', + countryCode, + }); + } + } + // success case: provider handles its own success UI + } catch (error) { + const safeInitError = sanitizeErrorMessage( + error instanceof Error ? error.message : String(error), + ); + console.error('Error in KYC flow:', safeInitError); + // Guard navigation call after async operations + if (navigationRef.isReady()) { + navigationRef.navigate('RegistrationFallback', { + errorSource: 'sumsub_initialization', + countryCode, + }); + } + } + })(); break; default: if (countryCode) { diff --git a/app/src/screens/app/LoadingScreen.tsx b/app/src/screens/app/LoadingScreen.tsx index 9d9e9deae..1920f760d 100644 --- a/app/src/screens/app/LoadingScreen.tsx +++ b/app/src/screens/app/LoadingScreen.tsx @@ -107,8 +107,8 @@ const LoadingScreen: React.FC = ({ route }) => { } else { await init(selfClient, 'dsc', true); } - } catch { - console.error('Error loading selected document:'); + } catch (error) { + console.error('Error loading selected document:', error); await init(selfClient, 'dsc', true); } finally { setIsInitializing(false); diff --git a/app/src/screens/dev/DevSettingsScreen.tsx b/app/src/screens/dev/DevSettingsScreen.tsx index ea4e58bc1..22f80fff9 100644 --- a/app/src/screens/dev/DevSettingsScreen.tsx +++ b/app/src/screens/dev/DevSettingsScreen.tsx @@ -44,6 +44,12 @@ import { subscribeToTopics, unsubscribeFromTopics, } from '@/services/notifications/notificationService'; +import type { InjectedErrorType } from '@/stores/errorInjectionStore'; +import { + ERROR_GROUPS, + ERROR_LABELS, + useErrorInjectionStore, +} from '@/stores/errorInjectionStore'; import { usePointEventStore } from '@/stores/pointEventStore'; import { useSettingStore } from '@/stores/settingStore'; import { IS_DEV_MODE } from '@/utils/devUtils'; @@ -390,6 +396,152 @@ const LogLevelSelector = ({ ); }; +const ErrorInjectionSelector = () => { + const injectedErrors = useErrorInjectionStore(state => state.injectedErrors); + const setInjectedErrors = useErrorInjectionStore( + state => state.setInjectedErrors, + ); + const clearAllErrors = useErrorInjectionStore(state => state.clearAllErrors); + const [open, setOpen] = useState(false); + + // Single error selection - replace instead of toggle + const selectError = (errorType: InjectedErrorType) => { + // If clicking the same error, clear it; otherwise set the new one + if (injectedErrors.length === 1 && injectedErrors[0] === errorType) { + clearAllErrors(); + } else { + setInjectedErrors([errorType]); + } + // Close the sheet after selection + setOpen(false); + }; + + const currentError = injectedErrors.length > 0 ? injectedErrors[0] : null; + const currentErrorLabel = currentError ? ERROR_LABELS[currentError] : null; + + return ( + + + + {currentError && ( + + )} + + + + + + + + Onboarding Error Testing + + + + + {Object.entries(ERROR_GROUPS).map(([groupName, errors]) => ( + + + {groupName} + + {errors.map((errorType: InjectedErrorType) => ( + selectError(errorType)} + > + + + {ERROR_LABELS[errorType]} + + {currentError === errorType && ( + + )} + + + ))} + + ))} + + + + + + ); +}; + const DevSettingsScreen: React.FC = ({}) => { const { clearDocumentCatalogForMigrationTesting } = usePassport(); const clearPointEvents = usePointEventStore(state => state.clearEvents); @@ -779,6 +931,16 @@ const DevSettingsScreen: React.FC = ({}) => { /> + {IS_DEV_MODE && ( + } + title="Onboarding Error Testing" + description="Test onboarding error flows" + > + + + )} + {Platform.OS === 'android' && ( } diff --git a/app/src/screens/documents/scanning/DocumentCameraTroubleScreen.tsx b/app/src/screens/documents/scanning/DocumentCameraTroubleScreen.tsx index e9d0a2c10..c99d5e242 100644 --- a/app/src/screens/documents/scanning/DocumentCameraTroubleScreen.tsx +++ b/app/src/screens/documents/scanning/DocumentCameraTroubleScreen.tsx @@ -3,9 +3,11 @@ // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. import React, { useEffect } from 'react'; +import { YStack } from 'tamagui'; -import { Caption } from '@selfxyz/mobile-sdk-alpha/components'; -import { slate500 } from '@selfxyz/mobile-sdk-alpha/constants/colors'; +import { useSelfClient } from '@selfxyz/mobile-sdk-alpha'; +import { Caption, SecondaryButton } from '@selfxyz/mobile-sdk-alpha/components'; +import { slate500, slate700 } from '@selfxyz/mobile-sdk-alpha/constants/colors'; import Activity from '@/assets/icons/activity.svg'; import PassportCameraBulb from '@/assets/icons/passport_camera_bulb.svg'; @@ -15,6 +17,7 @@ import Star from '@/assets/icons/star.svg'; import type { TipProps } from '@/components/Tips'; import Tips from '@/components/Tips'; import useHapticNavigation from '@/hooks/useHapticNavigation'; +import { useSumsubLauncher } from '@/hooks/useSumsubLauncher'; import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout'; import { flush as flushAnalytics } from '@/services/analytics'; @@ -48,6 +51,13 @@ const tips: TipProps[] = [ const DocumentCameraTroubleScreen: React.FC = () => { const go = useHapticNavigation('DocumentCamera', { action: 'cancel' }); + const selfClient = useSelfClient(); + const { useMRZStore } = selfClient; + const { countryCode } = useMRZStore(); + const { launchSumsubVerification, isLoading } = useSumsubLauncher({ + countryCode, + errorSource: 'sumsub_initialization', + }); // error screen, flush analytics useEffect(() => { @@ -64,10 +74,28 @@ const DocumentCameraTroubleScreen: React.FC = () => { } footer={ - - Following these steps should help your phone's camera capture the ID - page quickly and clearly! - + + + Following these steps should help your phone's camera capture the ID + page quickly and clearly! + + + + Or try an alternative verification method: + + + + {isLoading ? 'Loading...' : 'Try Alternative Verification'} + + } > diff --git a/app/src/screens/documents/scanning/DocumentNFCScanScreen.tsx b/app/src/screens/documents/scanning/DocumentNFCScanScreen.tsx index 72f1845aa..4f95a70d2 100644 --- a/app/src/screens/documents/scanning/DocumentNFCScanScreen.tsx +++ b/app/src/screens/documents/scanning/DocumentNFCScanScreen.tsx @@ -54,6 +54,7 @@ import { dinot } from '@selfxyz/mobile-sdk-alpha/constants/fonts'; import passportVerifyAnimation from '@/assets/animations/passport_verify.json'; import NFC_IMAGE from '@/assets/images/nfc.png'; import { logNFCEvent } from '@/config/sentry'; +import { useErrorInjection } from '@/hooks/useErrorInjection'; import { useFeedbackAutoHide } from '@/hooks/useFeedbackAutoHide'; import useHapticNavigation from '@/hooks/useHapticNavigation'; import { @@ -106,8 +107,9 @@ const DocumentNFCScanScreen: React.FC = () => { const navigation = useNavigation>(); const route = useRoute(); - const { showModal } = useFeedback(); + useFeedback(); useFeedbackAutoHide(); + const { shouldInjectError } = useErrorInjection(); const { passportNumber, dateOfBirth, @@ -189,18 +191,12 @@ const DocumentNFCScanScreen: React.FC = () => { }, { message: sanitizeErrorMessage(message) }, ); - showModal({ - titleText: 'NFC Scan Error', - bodyText: message, - buttonText: SUPPORT_FORM_BUTTON_TEXT, - secondaryButtonText: 'Help', - preventDismiss: false, - onButtonPress: openSupportForm, - onSecondaryButtonPress: goToNFCTrouble, - onModalDismiss: () => {}, + navigation.navigate('RegistrationFallback', { + errorSource: 'nfc_scan_failed', + countryCode, }); }, - [baseContext, showModal, goToNFCTrouble], + [baseContext, navigation, countryCode], ); const checkNfcSupport = useCallback(async () => { @@ -324,6 +320,18 @@ const DocumentNFCScanScreen: React.FC = () => { }, 30000); try { + // Dev-only: Check for injected timeout error + if (shouldInjectError('nfc_timeout')) { + console.log('[DEV] Injecting NFC timeout error'); + throw new Error('Injected timeout error for testing'); + } + + // Dev-only: Check for injected module unavailable error + if (shouldInjectError('nfc_module_unavailable')) { + console.log('[DEV] Injecting NFC module unavailable error'); + throw new Error('NFC scanning is currently unavailable'); + } + const { canNumber, useCan, @@ -376,6 +384,12 @@ const DocumentNFCScanScreen: React.FC = () => { ); let passportData: PassportData | null = null; try { + // Dev-only: Check for injected parse failure error + if (shouldInjectError('nfc_parse_failure')) { + console.log('[DEV] Injecting NFC parse failure error'); + throw new Error('Failed to parse NFC response'); + } + passportData = parseScanResponse(scanResponse); } catch (e: unknown) { console.error('Parsing NFC Response Unsuccessful'); @@ -452,6 +466,7 @@ const DocumentNFCScanScreen: React.FC = () => { navigation, openErrorModal, trackEvent, + shouldInjectError, ]); const navigateToHome = useHapticNavigation('Home', { diff --git a/app/src/screens/documents/scanning/DocumentNFCTroubleScreen.tsx b/app/src/screens/documents/scanning/DocumentNFCTroubleScreen.tsx index ab7d76326..0af2728d0 100644 --- a/app/src/screens/documents/scanning/DocumentNFCTroubleScreen.tsx +++ b/app/src/screens/documents/scanning/DocumentNFCTroubleScreen.tsx @@ -7,13 +7,15 @@ import { View } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { YStack } from 'tamagui'; +import { useSelfClient } from '@selfxyz/mobile-sdk-alpha'; import { Caption, SecondaryButton } from '@selfxyz/mobile-sdk-alpha/components'; -import { slate500 } from '@selfxyz/mobile-sdk-alpha/constants/colors'; +import { slate500, slate700 } from '@selfxyz/mobile-sdk-alpha/constants/colors'; import type { TipProps } from '@/components/Tips'; import Tips from '@/components/Tips'; import { useFeedbackAutoHide } from '@/hooks/useFeedbackAutoHide'; import useHapticNavigation from '@/hooks/useHapticNavigation'; +import { useSumsubLauncher } from '@/hooks/useSumsubLauncher'; import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout'; import { flushAllAnalytics } from '@/services/analytics'; import { openSupportForm, SUPPORT_FORM_BUTTON_TEXT } from '@/services/support'; @@ -50,6 +52,13 @@ const DocumentNFCTroubleScreen: React.FC = () => { const goToNFCMethodSelection = useHapticNavigation( 'DocumentNFCMethodSelection', ); + const selfClient = useSelfClient(); + const { useMRZStore } = selfClient; + const { countryCode } = useMRZStore(); + const { launchSumsubVerification, isLoading } = useSumsubLauncher({ + countryCode, + errorSource: 'sumsub_initialization', + }); useFeedbackAutoHide(); // error screen, flush analytics @@ -71,9 +80,24 @@ const DocumentNFCTroubleScreen: React.FC = () => { secondaryButtonText="Open NFC Options" onSecondaryButtonPress={goToNFCMethodSelection} footer={ - - {SUPPORT_FORM_BUTTON_TEXT} - + + + {SUPPORT_FORM_BUTTON_TEXT} + + + + {isLoading ? 'Loading...' : 'Try Alternative Verification'} + + } > , + string +>; + +const getHeaderTitle = (errorSource: FallbackErrorSource): string => { + switch (errorSource) { + case 'mrz_scan_failed': + return 'MRZ SCAN'; + case 'nfc_scan_failed': + return 'NFC SCAN'; + default: + return 'REGISTRATION'; + } +}; + +const getCurrentStep = (errorSource: FallbackErrorSource): number => { + switch (errorSource) { + case 'mrz_scan_failed': + return 1; // Step 1: MRZ scanning + case 'nfc_scan_failed': + return 2; // Step 2: NFC reading + case 'sumsub_initialization': + case 'sumsub_verification': + return 3; // Step 3: Proving/verification + default: + return 1; + } +}; + +const getRetryButtonText = (errorSource: FallbackErrorSource): string => { + switch (errorSource) { + case 'mrz_scan_failed': + return 'Try scanning again'; + case 'nfc_scan_failed': + return 'Try reading again'; + default: + return 'Try again'; + } +}; + +const getErrorMessages = ( + errorSource: FallbackErrorSource, +): { title: string; description: string; canRetryOriginal: boolean } => { + switch (errorSource) { + case 'mrz_scan_failed': + return { + title: 'There was a problem scanning your document', + description: 'Make sure the document is clearly visible and try again', + canRetryOriginal: true, + }; + case 'nfc_scan_failed': + return { + title: 'There was a problem reading the chip', + description: 'Make sure NFC is enabled and try again', + canRetryOriginal: true, + }; + case 'sumsub_initialization': + return { + title: 'Connection Error', + description: + 'Unable to connect to verification service. Please check your internet connection and try again.', + canRetryOriginal: false, + }; + case 'sumsub_verification': + return { + title: 'Verification Error', + description: + 'Something went wrong during the verification process. Please try again.', + canRetryOriginal: false, + }; + } +}; + +const RegistrationFallbackScreen: React.FC = () => { + const insets = useSafeAreaInsets(); + const paddingBottom = useSafeBottomPadding(extraYPadding + 35); + const navigation = + useNavigation>(); + const route = useRoute(); + const selfClient = useSelfClient(); + const { trackEvent, useMRZStore } = selfClient; + const storeCountryCode = useMRZStore(state => state.countryCode); + + const errorSource = route.params?.errorSource || 'sumsub_initialization'; + // Use country code from route params, or fall back to MRZ store + const countryCode = route.params?.countryCode || storeCountryCode || ''; + + const headerTitle = getHeaderTitle(errorSource); + const retryButtonText = getRetryButtonText(errorSource); + const currentStep = getCurrentStep(errorSource); + const { title, description, canRetryOriginal } = + getErrorMessages(errorSource); + + const { launchSumsubVerification, isLoading: isRetrying } = useSumsubLauncher( + { + countryCode, + errorSource, + onCancel: () => { + navigation.goBack(); + }, + onError: (_error, _result) => { + // Stay on this screen - user can try again + // Error is already logged in the hook + }, + onSuccess: () => { + // Success - provider handles its own success UI + // The screen will be navigated away by the provider's flow + }, + }, + ); + + const handleClose = useCallback(() => { + buttonTap(); + navigation.goBack(); + }, [navigation]); + + const handleTryAlternative = useCallback(async () => { + trackEvent('REGISTRATION_FALLBACK_TRY_ALTERNATIVE', { errorSource }); + await launchSumsubVerification(); + }, [errorSource, launchSumsubVerification, trackEvent]); + + const handleRetryOriginal = useCallback(() => { + trackEvent('REGISTRATION_FALLBACK_RETRY_ORIGINAL', { errorSource }); + + // Navigate back to the appropriate screen based on error source + if (errorSource === 'mrz_scan_failed') { + navigation.navigate('DocumentCamera'); + } else if (errorSource === 'nfc_scan_failed') { + navigation.navigate('DocumentNFCScan', {}); + } else if (errorSource === 'sumsub_initialization') { + // Go back to ID Picker + navigation.goBack(); + } + // TODO: Handle 'sumsub_verification' case - currently falls through without action + // which could leave users stuck when tapping "Try again" after Sumsub verification failure. + // Consider: calling launchSumsubVerification() or navigating to appropriate retry screen. + // Need to determine the correct retry behavior for failed Sumsub verifications. + }, [errorSource, navigation, trackEvent]); + + return ( + + {/* Header */} + + + + + + {headerTitle} + + + + + + {/* Progress Bar */} + + + {[1, 2, 3, 4].map(step => ( + + ))} + + + + + {/* Warning Icon */} + + + + + + + {/* Error Message */} + + + {title} + + + {description} + + + + {/* Top Button - Retry */} + {canRetryOriginal && ( + + + {retryButtonText} + + + )} + + {/* Bottom Section with Grey Line Separator */} + + + {isRetrying ? 'Loading...' : 'Try a different method'} + + + {/* Footer Text */} + + Registering with alternative methods may take longer to verify your + document. + + + + ); +}; + +export default RegistrationFallbackScreen; diff --git a/app/src/stores/errorInjectionStore.ts b/app/src/stores/errorInjectionStore.ts new file mode 100644 index 000000000..6090a6617 --- /dev/null +++ b/app/src/stores/errorInjectionStore.ts @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import { create } from 'zustand'; +import { createJSONStorage, persist } from 'zustand/middleware'; +import AsyncStorage from '@react-native-async-storage/async-storage'; + +import { IS_DEV_MODE } from '@/utils/devUtils'; + +export type InjectedErrorType = + | 'mrz_invalid_format' + | 'mrz_unknown_error' + | 'nfc_timeout' + | 'nfc_module_unavailable' + | 'nfc_parse_failure' + | 'api_network_error' + | 'api_timeout' + | 'sumsub_initialization' + | 'sumsub_verification'; + +export const ERROR_GROUPS = { + MRZ: ['mrz_invalid_format', 'mrz_unknown_error'] as InjectedErrorType[], + NFC: [ + 'nfc_timeout', + 'nfc_module_unavailable', + 'nfc_parse_failure', + ] as InjectedErrorType[], + API: ['api_network_error', 'api_timeout'] as InjectedErrorType[], + Sumsub: [ + 'sumsub_initialization', + 'sumsub_verification', + ] as InjectedErrorType[], +}; + +export const ERROR_LABELS: Record = { + mrz_invalid_format: 'MRZ: Invalid format', + mrz_unknown_error: 'MRZ: Unknown error', + nfc_timeout: 'NFC: Timeout', + nfc_module_unavailable: 'NFC: Module unavailable', + nfc_parse_failure: 'NFC: Parse failure', + api_network_error: 'API: Network error', + api_timeout: 'API: Timeout', + sumsub_initialization: 'Sumsub: Initialization', + sumsub_verification: 'Sumsub: Verification', +}; + +interface ErrorInjectionState { + injectedErrors: InjectedErrorType[]; + // Actions + setInjectedErrors: (errors: InjectedErrorType[]) => void; + toggleError: (error: InjectedErrorType) => void; + clearError: (error: InjectedErrorType) => void; + clearAllErrors: () => void; + shouldTrigger: (error: InjectedErrorType) => boolean; +} + +export const useErrorInjectionStore = create()( + persist( + (set, get) => ({ + injectedErrors: [], + + setInjectedErrors: (errors: InjectedErrorType[]) => { + if (!IS_DEV_MODE) return; + set({ injectedErrors: errors }); + }, + + toggleError: (error: InjectedErrorType) => { + if (!IS_DEV_MODE) return; + set(state => { + const hasError = state.injectedErrors.includes(error); + return { + injectedErrors: hasError + ? state.injectedErrors.filter(e => e !== error) + : [...state.injectedErrors, error], + }; + }); + }, + + clearError: (error: InjectedErrorType) => { + if (!IS_DEV_MODE) return; + set(state => ({ + injectedErrors: state.injectedErrors.filter(e => e !== error), + })); + }, + + clearAllErrors: () => { + if (!IS_DEV_MODE) return; + set({ injectedErrors: [] }); + }, + + shouldTrigger: (error: InjectedErrorType) => { + if (!IS_DEV_MODE) return false; + const state = get(); + return state.injectedErrors.includes(error); + }, + }), + { + name: 'error-injection-storage', + storage: createJSONStorage(() => AsyncStorage), + }, + ), +); diff --git a/app/tests/src/navigation.test.tsx b/app/tests/src/navigation.test.tsx index 6723984c9..4c9a7ef26 100644 --- a/app/tests/src/navigation.test.tsx +++ b/app/tests/src/navigation.test.tsx @@ -101,6 +101,7 @@ describe('navigation', () => { 'QRCodeViewFinder', 'RecoverWithPhrase', 'Referral', + 'RegistrationFallback', 'SaveRecoveryPhrase', 'Settings', 'ShowRecoveryPhrase', diff --git a/packages/mobile-sdk-alpha/src/client.ts b/packages/mobile-sdk-alpha/src/client.ts index 5903a7b8f..7c1dd5251 100644 --- a/packages/mobile-sdk-alpha/src/client.ts +++ b/packages/mobile-sdk-alpha/src/client.ts @@ -224,5 +224,7 @@ export function createSelfClient({ useSelfAppStore, useProtocolStore, useMRZStore, + // Expose config for internal SDK use + config: cfg, }; } diff --git a/packages/mobile-sdk-alpha/src/config/defaults.ts b/packages/mobile-sdk-alpha/src/config/defaults.ts index cb45caa43..2ceb76ec0 100644 --- a/packages/mobile-sdk-alpha/src/config/defaults.ts +++ b/packages/mobile-sdk-alpha/src/config/defaults.ts @@ -4,7 +4,7 @@ import type { Config } from '../types/public'; -export const defaultConfig: Required = { +export const defaultConfig: Omit, 'devConfig'> & Pick = { timeouts: { scanMs: 60000 }, // in future this can be used to enable/disable experimental features features: {}, diff --git a/packages/mobile-sdk-alpha/src/config/merge.ts b/packages/mobile-sdk-alpha/src/config/merge.ts index 8602110d8..e635252e2 100644 --- a/packages/mobile-sdk-alpha/src/config/merge.ts +++ b/packages/mobile-sdk-alpha/src/config/merge.ts @@ -4,11 +4,14 @@ import type { Config } from '../types/public'; -export function mergeConfig(base: Required, override: Config): Required { +type BaseConfig = Omit, 'devConfig'> & Pick; + +export function mergeConfig(base: BaseConfig, override: Config): BaseConfig { return { ...base, ...override, timeouts: { ...base.timeouts, ...(override.timeouts ?? {}) }, features: { ...base.features, ...(override.features ?? {}) }, + devConfig: override.devConfig ?? base.devConfig, }; } diff --git a/packages/mobile-sdk-alpha/src/flows/onboarding/read-mrz.ts b/packages/mobile-sdk-alpha/src/flows/onboarding/read-mrz.ts index 069675ed9..a90a60c00 100644 --- a/packages/mobile-sdk-alpha/src/flows/onboarding/read-mrz.ts +++ b/packages/mobile-sdk-alpha/src/flows/onboarding/read-mrz.ts @@ -12,6 +12,9 @@ import { checkScannedInfo, formatDateToYYMMDD } from '../../processing/mrz'; import { SdkEvents } from '../../types/events'; import type { MRZInfo } from '../../types/public'; +// Dev-only error injection - uses injected devConfig from SDK context +// No cross-package requires needed + export type { MRZScannerViewProps } from '../../components/MRZScannerView'; export { MRZScannerView } from '../../components/MRZScannerView'; @@ -28,12 +31,25 @@ const calculateScanDurationSeconds = (scanStartTimeRef: RefObject) => { export function useReadMRZ(scanStartTimeRef: RefObject) { const selfClient = useSelfClient(); + const shouldTrigger = selfClient.config?.devConfig?.shouldTrigger; return { onPassportRead: useCallback( (error: Error | null, result?: MRZInfo) => { const scanDurationSeconds = calculateScanDurationSeconds(scanStartTimeRef); + // Dev-only: Check for injected unknown error + if (shouldTrigger?.('mrz_unknown_error')) { + console.log('[DEV] Injecting MRZ unknown error'); + selfClient.trackEvent(PassportEvents.CAMERA_SCAN_FAILED, { + reason: 'unknown_error', + error: 'Injected error for testing', + duration_seconds: parseFloat(scanDurationSeconds), + }); + selfClient.emit(SdkEvents.DOCUMENT_MRZ_READ_FAILURE); + return; + } + if (error) { console.error(error); @@ -63,7 +79,16 @@ export function useReadMRZ(scanStartTimeRef: RefObject) { const formattedDateOfBirth = Platform.OS === 'ios' ? formatDateToYYMMDD(dateOfBirth) : dateOfBirth; const formattedDateOfExpiry = Platform.OS === 'ios' ? formatDateToYYMMDD(dateOfExpiry) : dateOfExpiry; - if (!checkScannedInfo(documentNumber, formattedDateOfBirth, formattedDateOfExpiry)) { + // Dev-only: Check for injected invalid format error + const shouldInjectInvalidFormat = shouldTrigger?.('mrz_invalid_format') || false; + + if ( + shouldInjectInvalidFormat || + !checkScannedInfo(documentNumber, formattedDateOfBirth, formattedDateOfExpiry) + ) { + if (shouldInjectInvalidFormat) { + console.log('[DEV] Injecting MRZ invalid format error'); + } selfClient.trackEvent(PassportEvents.CAMERA_SCAN_FAILED, { reason: 'invalid_format', passportNumberLength: documentNumber.length, @@ -90,7 +115,7 @@ export function useReadMRZ(scanStartTimeRef: RefObject) { selfClient.emit(SdkEvents.DOCUMENT_MRZ_READ_SUCCESS); }, - [selfClient], + [selfClient, shouldTrigger], ), }; } diff --git a/packages/mobile-sdk-alpha/src/index.ts b/packages/mobile-sdk-alpha/src/index.ts index 7ebeae490..ac8357c4e 100644 --- a/packages/mobile-sdk-alpha/src/index.ts +++ b/packages/mobile-sdk-alpha/src/index.ts @@ -138,5 +138,6 @@ export { parseNFCResponse, scanNFC } from './nfc'; export { reactNativeScannerAdapter } from './adapters/react-native/nfc-scanner'; export { sanitizeErrorMessage } from './utils/utils'; export { useCountries } from './documents/useCountries'; +export { useMRZStore } from './stores/mrzStore'; export { webNFCScannerShim } from './adapters/web/shims'; diff --git a/packages/mobile-sdk-alpha/src/types/public.ts b/packages/mobile-sdk-alpha/src/types/public.ts index df74c79a1..7b6483cf0 100644 --- a/packages/mobile-sdk-alpha/src/types/public.ts +++ b/packages/mobile-sdk-alpha/src/types/public.ts @@ -35,6 +35,18 @@ export interface Config { * treated as `false` and the SDK will continue using legacy flows. */ features?: Record; + /** + * Optional dev-mode configuration for error injection and testing. Should + * only be provided in development builds. Production builds should omit this. + */ + devConfig?: { + /** + * Callback to check if a specific error type should be injected for testing. + * @param errorType - The type of error to check (e.g., 'mrz_unknown_error') + * @returns true if the error should be injected, false otherwise + */ + shouldTrigger?: (errorType: string) => boolean; + }; } /** @@ -375,6 +387,9 @@ export interface SelfClient { useProtocolStore: ReturnType>; /** Zustand store hook mirroring {@link MRZState}. */ useMRZStore: ReturnType>; + + /** The merged configuration object passed to createSelfClient. */ + config: Config; } /** Function returned by {@link SelfClient.on} to detach a listener. */ diff --git a/packages/mobile-sdk-alpha/tests/config.test.ts b/packages/mobile-sdk-alpha/tests/config.test.ts index 119df55e1..91836042f 100644 --- a/packages/mobile-sdk-alpha/tests/config.test.ts +++ b/packages/mobile-sdk-alpha/tests/config.test.ts @@ -8,7 +8,7 @@ import { mergeConfig } from '../src/config/merge'; import type { Config } from '../src/types/public'; describe('mergeConfig', () => { - const baseConfig: Required = { + const baseConfig: Omit, 'devConfig'> & Pick = { timeouts: { scanMs: 30000, }, From ec7ad1e66dae38850155ca15edbcd071084fd028 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Wed, 28 Jan 2026 21:27:22 -0800 Subject: [PATCH 5/6] SELF-1932: sumsub success screen (#1667) * fix typos * typo * match screen design. fix tests --- app/src/navigation/index.tsx | 1 + app/src/navigation/onboarding.ts | 8 + app/src/providers/selfClientProvider.tsx | 7 +- app/src/screens/kyc/KycSuccessScreen.tsx | 124 ++++++++++++++ app/tests/src/navigation.test.tsx | 1 + .../src/screens/kyc/KycSuccessScreen.test.tsx | 154 ++++++++++++++++++ 6 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 app/src/screens/kyc/KycSuccessScreen.tsx create mode 100644 app/tests/src/screens/kyc/KycSuccessScreen.test.tsx diff --git a/app/src/navigation/index.tsx b/app/src/navigation/index.tsx index 65d68e114..17f90209b 100644 --- a/app/src/navigation/index.tsx +++ b/app/src/navigation/index.tsx @@ -201,6 +201,7 @@ export type RootStackParamList = Omit< // Onboarding screens Disclaimer: undefined; + KycSuccess: undefined; // Dev screens CreateMock: undefined; diff --git a/app/src/navigation/onboarding.ts b/app/src/navigation/onboarding.ts index 4c034a545..72156f420 100644 --- a/app/src/navigation/onboarding.ts +++ b/app/src/navigation/onboarding.ts @@ -4,6 +4,7 @@ import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'; +import KycSuccessScreen from '@/screens/kyc/KycSuccessScreen'; import AccountVerifiedSuccessScreen from '@/screens/onboarding/AccountVerifiedSuccessScreen'; import DisclaimerScreen from '@/screens/onboarding/DisclaimerScreen'; import SaveRecoveryPhraseScreen from '@/screens/onboarding/SaveRecoveryPhraseScreen'; @@ -30,6 +31,13 @@ const onboardingScreens = { animation: 'slide_from_bottom', } as NativeStackNavigationOptions, }, + KycSuccess: { + screen: KycSuccessScreen, + options: { + headerShown: false, + animation: 'slide_from_bottom', + } as NativeStackNavigationOptions, + }, }; export default onboardingScreens; diff --git a/app/src/providers/selfClientProvider.tsx b/app/src/providers/selfClientProvider.tsx index 106133216..28f9abe5f 100644 --- a/app/src/providers/selfClientProvider.tsx +++ b/app/src/providers/selfClientProvider.tsx @@ -375,8 +375,13 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => { countryCode, }); } + return; + } + + // Success case: navigate to KYC success screen + if (navigationRef.isReady()) { + navigationRef.navigate('KycSuccess'); } - // success case: provider handles its own success UI } catch (error) { const safeInitError = sanitizeErrorMessage( error instanceof Error ? error.message : String(error), diff --git a/app/src/screens/kyc/KycSuccessScreen.tsx b/app/src/screens/kyc/KycSuccessScreen.tsx new file mode 100644 index 000000000..22849692c --- /dev/null +++ b/app/src/screens/kyc/KycSuccessScreen.tsx @@ -0,0 +1,124 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import React from 'react'; +import { StyleSheet, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { YStack } from 'tamagui'; +import { useNavigation } from '@react-navigation/native'; +import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; + +import { DelayedLottieView } from '@selfxyz/mobile-sdk-alpha'; +import loadingAnimation from '@selfxyz/mobile-sdk-alpha/animations/loading/misc.json'; +import { + AbstractButton, + Description, + Title, +} from '@selfxyz/mobile-sdk-alpha/components'; +import { black, white } from '@selfxyz/mobile-sdk-alpha/constants/colors'; + +import { buttonTap } from '@/integrations/haptics'; +import type { RootStackParamList } from '@/navigation'; +import { requestNotificationPermission } from '@/services/notifications/notificationService'; + +const KycSuccessScreen: React.FC = () => { + const navigation = + useNavigation>(); + const insets = useSafeAreaInsets(); + + const handleReceiveUpdates = async () => { + buttonTap(); + await requestNotificationPermission(); + // Navigate to Home regardless of permission result + navigation.navigate('Home', {}); + }; + + const handleCheckLater = () => { + buttonTap(); + navigation.navigate('Home', {}); + }; + + return ( + + + + + + + Your ID is being verified + + Turn on push notifications to receive an update on your + verification. It's also safe the close the app and come back later. + + + + + + Receive live updates + + + I will check back later + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: black, + }, + centerSection: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + animationContainer: { + width: 80, + height: 80, + justifyContent: 'center', + alignItems: 'center', + marginBottom: 32, + }, + animation: { + width: 160, + height: 160, + }, + title: { + color: white, + textAlign: 'center', + fontSize: 28, + letterSpacing: 1, + }, + description: { + color: white, + textAlign: 'center', + fontSize: 18, + }, +}); + +export default KycSuccessScreen; diff --git a/app/tests/src/navigation.test.tsx b/app/tests/src/navigation.test.tsx index 4c9a7ef26..e32735297 100644 --- a/app/tests/src/navigation.test.tsx +++ b/app/tests/src/navigation.test.tsx @@ -85,6 +85,7 @@ describe('navigation', () => { 'Home', 'IDPicker', 'IdDetails', + 'KycSuccess', 'Loading', 'ManageDocuments', 'MockDataDeepLink', diff --git a/app/tests/src/screens/kyc/KycSuccessScreen.test.tsx b/app/tests/src/screens/kyc/KycSuccessScreen.test.tsx new file mode 100644 index 000000000..ea8cc6c72 --- /dev/null +++ b/app/tests/src/screens/kyc/KycSuccessScreen.test.tsx @@ -0,0 +1,154 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import React from 'react'; +import { useNavigation } from '@react-navigation/native'; +import { render } from '@testing-library/react-native'; + +import ErrorBoundary from '@/components/ErrorBoundary'; +import KycSuccessScreen from '@/screens/kyc/KycSuccessScreen'; +import * as notificationService from '@/services/notifications/notificationService'; + +// Note: While jest.setup.js provides comprehensive React Native mocking, +// react-test-renderer requires component-based mocks (functions) rather than +// string-based mocks for proper rendering. This minimal mock provides the +// specific components needed for this test without using requireActual to +// avoid memory issues (see .cursor/rules/test-memory-optimization.mdc). +jest.mock('react-native', () => ({ + __esModule: true, + Platform: { OS: 'ios', select: jest.fn() }, + StyleSheet: { + create: (styles: any) => styles, + flatten: (style: any) => style, + }, + View: ({ children, ...props }: any) =>
{children}
, + Text: ({ children, ...props }: any) => {children}, +})); + +jest.mock('react-native-edge-to-edge', () => ({ + SystemBars: () => null, +})); + +jest.mock('react-native-safe-area-context', () => ({ + useSafeAreaInsets: jest.fn(() => ({ top: 0, bottom: 0 })), +})); + +jest.mock('@react-navigation/native', () => ({ + useNavigation: jest.fn(), +})); + +// Mock Tamagui components +jest.mock('tamagui', () => ({ + __esModule: true, + YStack: ({ children, ...props }: any) =>
{children}
, + View: ({ children, ...props }: any) =>
{children}
, + Text: ({ children, ...props }: any) => {children}, +})); + +jest.mock('@selfxyz/mobile-sdk-alpha', () => ({ + DelayedLottieView: () => null, +})); + +jest.mock('@selfxyz/mobile-sdk-alpha/constants/colors', () => ({ + black: '#000000', + white: '#FFFFFF', +})); + +jest.mock('@selfxyz/mobile-sdk-alpha/components', () => ({ + AbstractButton: ({ children, onPress }: any) => ( + + ), + PrimaryButton: ({ children, onPress }: any) => ( + + ), + SecondaryButton: ({ children, onPress }: any) => ( + + ), + Title: ({ children }: any) =>
{children}
, + Description: ({ children }: any) => ( +
{children}
+ ), +})); + +jest.mock('@/integrations/haptics', () => ({ + buttonTap: jest.fn(), +})); + +jest.mock('@/services/notifications/notificationService', () => ({ + requestNotificationPermission: jest.fn(), +})); + +jest.mock('@/config/sentry', () => ({ + captureException: jest.fn(), +})); + +jest.mock('@/services/analytics', () => ({ + flushAllAnalytics: jest.fn(), + trackNfcEvent: jest.fn(), +})); + +const mockUseNavigation = useNavigation as jest.MockedFunction< + typeof useNavigation +>; + +describe('KycSuccessScreen', () => { + const mockNavigate = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + + mockUseNavigation.mockReturnValue({ + navigate: mockNavigate, + } as any); + }); + + it('should render the screen without errors', () => { + const { root } = render(); + expect(root).toBeTruthy(); + }); + + it('should have navigation available', () => { + render(); + expect(mockUseNavigation).toHaveBeenCalled(); + }); + + it('should have notification service available', () => { + render(); + expect(notificationService.requestNotificationPermission).toBeDefined(); + }); + + it('renders fallback on render error', () => { + // Mock console.error to suppress error boundary error logs during test + const consoleErrorSpy = jest + .spyOn(console, 'error') + .mockImplementation(() => {}); + + // Create a component that throws an error during render + const ThrowError = () => { + throw new Error('Test render error'); + }; + + // Render the error-throwing component wrapped in ErrorBoundary + const { root } = render( + + + , + ); + + // Verify the error boundary fallback UI is displayed + // Use a more flexible matcher since the text is nested in mocked components + expect(root.findByType('span').props.children).toBe( + 'Something went wrong. Please restart the app.', + ); + + // Restore console.error + consoleErrorSpy.mockRestore(); + }); +}); From a582e1b3cd9e500952492ca0ef19d64eb7113d93 Mon Sep 17 00:00:00 2001 From: Justin Hernandez Date: Wed, 28 Jan 2026 22:03:08 -0800 Subject: [PATCH 6/6] fix tests (#1668) --- circuits/tests/utils/kyc/ofac/ofac.test.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/circuits/tests/utils/kyc/ofac/ofac.test.ts b/circuits/tests/utils/kyc/ofac/ofac.test.ts index ce27b17a0..943562972 100644 --- a/circuits/tests/utils/kyc/ofac/ofac.test.ts +++ b/circuits/tests/utils/kyc/ofac/ofac.test.ts @@ -38,7 +38,7 @@ describe('OFAC - Name and DOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, namedob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -51,7 +51,7 @@ describe('OFAC - Name and DOB match', async function () { const dummy_kyc_input = serializeKycData(NON_OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(NON_OFAC_DUMMY_INPUT, namedob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -64,7 +64,7 @@ describe('OFAC - Name and DOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, namedob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, smt_leaf_key: BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(), }; @@ -79,7 +79,7 @@ describe('OFAC - Name and DOB match', async function () { const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, namedob_smt, proofLevel); ofacInputs.smt_siblings[0] = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -92,7 +92,7 @@ describe('OFAC - Name and DOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, namedob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, smt_root: BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(), }; @@ -129,7 +129,7 @@ describe('OFAC - Name and YOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, nameyob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -142,7 +142,7 @@ describe('OFAC - Name and YOB match', async function () { const dummy_kyc_input = serializeKycData(NON_OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(NON_OFAC_DUMMY_INPUT, nameyob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -155,7 +155,7 @@ describe('OFAC - Name and YOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, nameyob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, smt_leaf_key: BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(), }; @@ -170,7 +170,7 @@ describe('OFAC - Name and YOB match', async function () { const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, nameyob_smt, proofLevel); ofacInputs.smt_siblings[0] = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, }; @@ -183,7 +183,7 @@ describe('OFAC - Name and YOB match', async function () { const dummy_kyc_input = serializeKycData(OFAC_DUMMY_INPUT); const ofacInputs = generateCircuitInputsOfac(OFAC_DUMMY_INPUT, nameyob_smt, proofLevel); const inputs = { - kyc_data: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), + data_padded: dummy_kyc_input.split('').map((x) => x.charCodeAt(0)), ...ofacInputs, smt_root: BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString(), };