diff --git a/.github/actions/mobile-setup/action.yml b/.github/actions/mobile-setup/action.yml index 82429762c..291c0598f 100644 --- a/.github/actions/mobile-setup/action.yml +++ b/.github/actions/mobile-setup/action.yml @@ -52,5 +52,6 @@ runs: run: | cd ${{ inputs.app_path }} corepack enable + yarn set version 4.6.0 yarn install yarn install-app:deploy diff --git a/.github/actions/yarn-install/action.yml b/.github/actions/yarn-install/action.yml index 11e4fc824..24eb20f27 100644 --- a/.github/actions/yarn-install/action.yml +++ b/.github/actions/yarn-install/action.yml @@ -15,7 +15,8 @@ runs: shell: bash run: | corepack enable - corepack prepare yarn@4.5.0 --activate + corepack prepare yarn@4.6.0 --activate + yarn set version 4.6.0 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index d5827be3a..8c434c7ec 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -40,7 +40,9 @@ jobs: - name: Install dependencies run: | - npm i -g yarn && cd circuits && yarn + corepack enable + yarn set version 4.6.0 + cd circuits && yarn - name: Setup Rust uses: dtolnay/rust-toolchain@stable @@ -58,8 +60,8 @@ jobs: - name: Build cpp circuits run: | chmod +x circuits/scripts/build/build_cpp.sh && \ - ./circuits/scripts/build/build_cpp.sh register && - ./circuits/scripts/build/build_cpp.sh disclose && + ./circuits/scripts/build/build_cpp.sh register && + ./circuits/scripts/build/build_cpp.sh disclose && ./circuits/scripts/build/build_cpp.sh dsc - name: Upload Artifact diff --git a/circuits/circuits/utils/crypto/bigInt/bigInt.circom b/circuits/circuits/utils/crypto/bigInt/bigInt.circom index e62828119..47fecc79c 100644 --- a/circuits/circuits/utils/crypto/bigInt/bigInt.circom +++ b/circuits/circuits/utils/crypto/bigInt/bigInt.circom @@ -8,7 +8,7 @@ include "../int/arithmetic.circom"; include "@openpassport/zk-email-circuits/lib/bigint.circom"; // What BigInt in this lib means -// We represent big number as array of chunks with some shunk_size (will be explained later) +// We represent big number as array of chunks with some shunk_size (will be explained later) // for this example we will use N for number, n for chunk size and k for chunk_number: // N[k]; // Number can be calculated by this formula: @@ -31,14 +31,14 @@ template BigMultModP(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS, CHUNK_ signal output div[CHUNK_NUMBER_DIV]; signal output mod[CHUNK_NUMBER_MODULUS]; - + component mult = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS); mult.in1 <== in1; mult.in2 <== in2; var reduced[200] = reduce_overflow_dl(CHUNK_SIZE, CHUNK_NUMBER_BASE - 1, CHUNK_NUMBER_BASE, mult.out); var long_division[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV - 1, reduced, modulus); - + for (var i = 0; i < CHUNK_NUMBER_DIV; i++){ div[i] <-- long_division[0][i]; @@ -51,26 +51,26 @@ template BigMultModP(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS, CHUNK_ modChecks[i].in <== mod[i]; } - + component greaterThan = BigGreaterThan(CHUNK_SIZE, CHUNK_NUMBER_MODULUS); - + greaterThan.in[0] <== modulus; greaterThan.in[1] <== mod; greaterThan.out === 1; - + component mult2; if (CHUNK_NUMBER_DIV >= CHUNK_NUMBER_MODULUS){ mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_DIV, CHUNK_NUMBER_MODULUS); - + mult2.in1 <== div; mult2.in2 <== modulus; } else { mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV); - + mult2.in2 <== div; mult2.in1 <== modulus; } - + component isZero = BigIntIsZero(CHUNK_SIZE, CHUNK_SIZE * 2 + log_ceil(CHUNK_NUMBER_MODULUS + CHUNK_NUMBER_DIV - 1), CHUNK_NUMBER_BASE - 1); for (var i = 0; i < CHUNK_NUMBER_MODULUS; i++) { isZero.in[i] <== mult.out[i] - mult2.out[i] - mod[i]; @@ -84,9 +84,9 @@ template BigMultModP(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS, CHUNK_ // in[0] <= in[1] template BigLessEqThan(CHUNK_SIZE, CHUNK_NUMBER){ signal input in[2][CHUNK_NUMBER]; - + signal output out; - + component lessThan[CHUNK_NUMBER]; component isEqual[CHUNK_NUMBER]; signal result[CHUNK_NUMBER]; @@ -94,12 +94,12 @@ template BigLessEqThan(CHUNK_SIZE, CHUNK_NUMBER){ lessThan[i] = LessThan(CHUNK_SIZE); lessThan[i].in[0] <== in[0][i]; lessThan[i].in[1] <== in[1][i]; - + isEqual[i] = IsEqual(); isEqual[i].in[0] <== in[0][i]; isEqual[i].in[1] <== in[1][i]; } - + for (var i = 0; i < CHUNK_NUMBER; i++){ if (i == 0){ result[i] <== lessThan[i].out + isEqual[i].out; @@ -107,17 +107,17 @@ template BigLessEqThan(CHUNK_SIZE, CHUNK_NUMBER){ result[i] <== lessThan[i].out + isEqual[i].out * result[i - 1]; } } - + out <== result[CHUNK_NUMBER - 1]; - + } // in[0] > in[1] template BigGreaterThan(CHUNK_SIZE, CHUNK_NUMBER){ signal input in[2][CHUNK_NUMBER]; - + signal output out; - + component lessEqThan = BigLessEqThan(CHUNK_SIZE, CHUNK_NUMBER); lessEqThan.in <== in; out <== 1 - lessEqThan.out; @@ -149,20 +149,20 @@ template BigModInv(CHUNK_SIZE, CHUNK_NUMBER) { signal input in[CHUNK_NUMBER]; signal input modulus[CHUNK_NUMBER]; signal output out[CHUNK_NUMBER]; - - + + var inv[200] = mod_inv_dl(CHUNK_SIZE, CHUNK_NUMBER, in, modulus); for (var i = 0; i < CHUNK_NUMBER; i++) { out[i] <-- inv[i]; } - + component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER, CHUNK_NUMBER); mult.in1 <== in; mult.in2 <== out; mult.modulus <== modulus; - + mult.mod[0] === 1; for (var i = 1; i < CHUNK_NUMBER; i++) { mult.mod[i] === 0; } -} \ No newline at end of file +} diff --git a/circuits/circuits/utils/crypto/hasher/shaBytes/dynamic/sha1Bytes.circom b/circuits/circuits/utils/crypto/hasher/shaBytes/dynamic/sha1Bytes.circom index d45616059..979e84102 100644 --- a/circuits/circuits/utils/crypto/hasher/shaBytes/dynamic/sha1Bytes.circom +++ b/circuits/circuits/utils/crypto/hasher/shaBytes/dynamic/sha1Bytes.circom @@ -28,7 +28,7 @@ template Sha1Bytes(max_num_bytes) { for (var i = 0; i < 160; i++) { out[i] <== sha.out[i]; } - + } //Adapted from @openpassport/zk-email-circuits/helpers/sha256general.circom @@ -66,9 +66,9 @@ template Sha1General(maxBitsPadded) { component he0 = H_sha1(4); component sha1compression[maxBlocks]; - + for (i=0; i poseidon2([a, b]), []); tree.insert(BigInt(commitment)); - const passportNo_smt = new SMT(poseidon2, true); - passportNo_smt.import(passportNojson); - const nameAndDob_smt = new SMT(poseidon2, true); nameAndDob_smt.import(nameAndDobjson); @@ -85,7 +81,7 @@ describe('Disclose', function () { selector_older_than, tree, majority, - passportNo_smt, + null, nameAndDob_smt, nameAndYob_smt, selector_ofac, @@ -141,7 +137,7 @@ describe('Disclose', function () { const revealedData_packed = await circuit.getOutput(w, ['revealedData_packed[4]']); const reveal_unpacked = formatAndUnpackReveal(revealedData_packed, 'id'); - for (let i = 0; i < 88; i++) { + for (let i = 0; i < 90; i++) { if (selector_dg1[i] == '1') { const char = String.fromCharCode(Number(inputs.dg1[i + 5])); assert(reveal_unpacked[i] == char, 'Should reveal the right character'); @@ -187,8 +183,8 @@ describe('Disclose', function () { const revealedData_packed = await circuit.getOutput(w, ['revealedData_packed[4]']); const reveal_unpacked = formatAndUnpackReveal(revealedData_packed, 'id'); - expect(reveal_unpacked[88]).to.equal('\x00'); - expect(reveal_unpacked[89]).to.equal('\x00'); + expect(reveal_unpacked[90]).to.equal('\x00'); + expect(reveal_unpacked[91]).to.equal('\x00'); }); describe('OFAC disclosure', function () { @@ -269,7 +265,7 @@ describe('Disclose', function () { selector_older_than, tree, majority, - passportNo_smt, + null, nameAndDob_smt, nameAndYob_smt, '1', // selector_ofac diff --git a/contracts/contracts/IdentityVerificationHubImplV2.sol b/contracts/contracts/IdentityVerificationHubImplV2.sol index 61e303cc0..f18c2aed6 100644 --- a/contracts/contracts/IdentityVerificationHubImplV2.sol +++ b/contracts/contracts/IdentityVerificationHubImplV2.sol @@ -1,87 +1,86 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {CircuitConstantsV2} from "./constants/CircuitConstantsV2.sol"; +import {ImplRoot} from "./upgradeable/ImplRoot.sol"; +import {SelfStructs} from "./libraries/SelfStructs.sol"; +import {CustomVerifier} from "./libraries/CustomVerifier.sol"; +import {GenericFormatter} from "./libraries/GenericFormatter.sol"; import {AttestationId} from "./constants/AttestationId.sol"; -import {Formatter} from "./libraries/Formatter.sol"; -import {CircuitAttributeHandlerV2} from "./libraries/CircuitAttributeHandlerV2.sol"; -import {IIdentityVerificationHubV2} from "./interfaces/IIdentityVerificationHubV2.sol"; +import {IVcAndDiscloseCircuitVerifier} from "./interfaces/IVcAndDiscloseCircuitVerifier.sol"; +import {ISelfVerificationRoot} from "./interfaces/ISelfVerificationRoot.sol"; import {IIdentityRegistryV1} from "./interfaces/IIdentityRegistryV1.sol"; +import {IIdentityRegistryIdCardV1} from "./interfaces/IIdentityRegistryIdCardV1.sol"; import {IRegisterCircuitVerifier} from "./interfaces/IRegisterCircuitVerifier.sol"; -import {IVcAndDiscloseCircuitVerifier} from "./interfaces/IVcAndDiscloseCircuitVerifier.sol"; import {IDscCircuitVerifier} from "./interfaces/IDscCircuitVerifier.sol"; -import {ImplRoot} from "./upgradeable/ImplRoot.sol"; -import {IdentityVerificationHubStorageV1} from "./IdentityVerificationHubImplV1.sol"; -import {IIdentityRegistryIdCardV1} from "./interfaces/IIdentityRegistryIdCardV1.sol"; +import {CircuitConstantsV2} from "./constants/CircuitConstantsV2.sol"; +import {Formatter} from "./libraries/Formatter.sol"; -/** - * @notice ⚠️ CRITICAL STORAGE LAYOUT WARNING ⚠️ - * ============================================= - * - * This contract uses the UUPS upgradeable pattern which makes storage layout EXTREMELY SENSITIVE. - * - * 🚫 NEVER MODIFY OR REORDER existing storage variables - * 🚫 NEVER INSERT new variables between existing ones - * 🚫 NEVER CHANGE THE TYPE of existing variables - * - * ✅ New storage variables MUST be added in one of these two ways ONLY: - * 1. At the END of the storage layout - * 2. In a new V2 contract that inherits from this V1 - * - * Examples of forbidden changes: - * - Changing uint256 to uint128 - * - Changing bytes32 to bytes - * - Changing array type to mapping - * - * For more detailed information about forbidden changes, please refer to: - * https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable#modifying-your-contracts - * - * ⚠️ VIOLATION OF THESE RULES WILL CAUSE CATASTROPHIC STORAGE COLLISIONS IN FUTURE UPGRADES ⚠️ - * ============================================= - */ - -/** - * @title IdentityVerificationHubStorageV2 - * @notice Storage contract for IdentityVerificationHubImplV2. - * @dev Inherits from ImplRoot to include upgradeability functionality. - */ -abstract contract IdentityVerificationHubStorageV2 is IdentityVerificationHubStorageV1 { - mapping(bytes32 => address) internal _attestationIdToRegistry; - mapping(bytes32 => address) internal _attestationIdToDiscloseVerifier; -} +contract IdentityVerificationHubImplV2 is ImplRoot { + /// @custom:storage-location erc7201:self.storage.IdentityVerificationHub + struct IdentityVerificationHubStorage { + uint256 _circuitVersion; + mapping(bytes32 attestationId => address registry) _registries; + mapping(bytes32 attestationId => mapping(uint256 sigTypeId => address registerCircuitVerifier)) _registerCircuitVerifiers; + mapping(bytes32 attestationId => mapping(uint256 sigTypeId => address dscCircuitVerifier)) _dscCircuitVerifiers; + mapping(bytes32 attestationId => address discloseVerifiers) _discloseVerifiers; + } -/** - * @title IdentityVerificationHubImplV2 - * @notice Implementation contract for the Identity Verification Hub. - * @dev Provides functions for registering commitments and verifying groth16 proofs and inclusion proofs. - */ -contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIdentityVerificationHubV2 { - using Formatter for uint256; + /// @custom:storage-location erc7201:self.storage.IdentityVerificationHubV2 + struct IdentityVerificationHubV2Storage { + mapping(bytes32 configId => SelfStructs.VerificationConfigV2) _v2VerificationConfigs; + } + // We should consider to add bridge address + // address bridgeAddress; - uint256 constant MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 40; + /// @dev keccak256(abi.encode(uint256(keccak256("self.storage.IdentityVerificationHub")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant IDENTITYVERIFICATIONHUB_STORAGE_LOCATION = + 0x2ade7eace21710c689ddef374add52ace9783e33bac626e58e73a9d190173d00; - // ==================================================== - // Events - // ==================================================== + /// @dev keccak256(abi.encode(uint256(keccak256("self.storage.IdentityVerificationHubV2")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant IDENTITYVERIFICATIONHUBV2_STORAGE_LOCATION = + 0xf9b5980dcec1a8b0609576a1f453bb2cad4732a0ea02bb89154d44b14a306c00; - event HubInitialized( - bytes32[] attestationIds, - address[] registryAddresses, - address[] vcAndDiscloseCircuitVerifiers, - uint256[] registerCircuitVerifierIds, - address[] registerCircuitVerifiers, - uint256[] dscCircuitVerifierIds, - address[] dscCircuitVerifiers - ); + /** + * @notice Returns the storage struct for the main IdentityVerificationHub. + * @dev Uses ERC-7201 storage pattern for upgradeable contracts. + * @return $ The storage struct reference. + */ + function _getIdentityVerificationHubStorage() private pure returns (IdentityVerificationHubStorage storage $) { + assembly { + $.slot := IDENTITYVERIFICATIONHUB_STORAGE_LOCATION + } + } + + /** + * @notice Returns the storage struct for IdentityVerificationHub V2 features. + * @dev Uses ERC-7201 storage pattern for upgradeable contracts. + * @return $ The V2 storage struct reference. + */ + function _getIdentityVerificationHubV2Storage() private pure returns (IdentityVerificationHubV2Storage storage $) { + assembly { + $.slot := IDENTITYVERIFICATIONHUBV2_STORAGE_LOCATION + } + } + + /** + * @notice Emitted when the Hub V2 is successfully initialized. + */ + event HubInitializedV2(); + /** + * @notice Emitted when a verification config V2 is set. + * @param configId The configuration identifier (generated from config hash). + * @param config The verification configuration that was set. + */ + event VerificationConfigV2Set(bytes32 indexed configId, SelfStructs.VerificationConfigV2 config); /** * @notice Emitted when the registry address is updated. + * @param attestationId The attestation identifier. * @param registry The new registry address. */ event RegistryUpdated(bytes32 attestationId, address registry); /** * @notice Emitted when the VC and Disclose circuit verifier is updated. + * @param attestationId The attestation identifier. * @param vcAndDiscloseCircuitVerifier The new VC and Disclose circuit verifier address. */ event VcAndDiscloseCircuitUpdated(bytes32 attestationId, address vcAndDiscloseCircuitVerifier); @@ -102,67 +101,74 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde // Errors // ==================================================== - /// @notice Thrown when the lengths of provided arrays do not match. - /// @dev Used when initializing or updating arrays that must have equal length. - error LENGTH_MISMATCH(); + /// @notice Thrown when arrays have mismatched lengths in batch operations. + /// @dev Ensures that all input arrays have the same length for batch updates. + error LengthMismatch(); /// @notice Thrown when no verifier is set for a given signature type. /// @dev Indicates that the mapping lookup for the verifier returned the zero address. - error NO_VERIFIER_SET(); + error NoVerifierSet(); /// @notice Thrown when the current date in the proof is not within the valid range. /// @dev Ensures that the provided proof's date is within one day of the expected start time. - error CURRENT_DATE_NOT_IN_VALID_RANGE(); - - /// @notice Thrown when the 'older than' attribute in the proof is invalid. - /// @dev The 'older than' value derived from the proof does not match the expected criteria. - error INVALID_OLDER_THAN(); - - /// @notice Thrown when the provided forbidden countries list is invalid. - /// @dev The forbidden countries list in the proof does not match the expected packed data. - error INVALID_FORBIDDEN_COUNTRIES(); - - /// @notice Thrown when the OFAC check fails. - /// @dev Indicates that the proof did not satisfy the required OFAC conditions. - error INVALID_OFAC(); + error CurrentDateNotInValidRange(); /// @notice Thrown when the register circuit proof is invalid. /// @dev The register circuit verifier did not validate the provided proof. - error INVALID_REGISTER_PROOF(); + error InvalidRegisterProof(); /// @notice Thrown when the DSC circuit proof is invalid. /// @dev The DSC circuit verifier did not validate the provided proof. - error INVALID_DSC_PROOF(); + error InvalidDscProof(); /// @notice Thrown when the VC and Disclose proof is invalid. /// @dev The VC and Disclose circuit verifier did not validate the provided proof. - error INVALID_VC_AND_DISCLOSE_PROOF(); + error InvalidVcAndDiscloseProof(); - /// @notice Thrown when the provided commitment root is invalid. - /// @dev Used in proofs to ensure that the commitment root matches the expected value in the registry. - error INVALID_COMMITMENT_ROOT(); + /// @notice Thrown when the provided identity commitment root is invalid. + /// @dev Used in proofs to ensure that the identity commitment root matches the expected value in the registry. + error InvalidIdentityCommitmentRoot(); - /// @notice Thrown when the provided OFAC root is invalid. - /// @dev Indicates that the OFAC root from the proof does not match the expected OFAC root. - error INVALID_OFAC_ROOT(); + /// @notice Thrown when the provided DSC commitment root is invalid. + /// @dev Used in proofs to ensure that the DSC commitment root matches the expected value in the registry. + error InvalidDscCommitmentRoot(); /// @notice Thrown when the provided CSCA root is invalid. /// @dev Indicates that the CSCA root from the DSC proof does not match the expected CSCA root. - error INVALID_CSCA_ROOT(); + error InvalidCscaRoot(); + + /// @notice Thrown when an invalid attestation ID is provided. + /// @dev The attestation ID must be a supported type (e.g., E_PASSPORT or EU_ID_CARD). + error InvalidAttestationId(); + + /// @notice Thrown when the scope in the header doesn't match the scope in the proof. + /// @dev Ensures that the scope value in the header matches the scope value in the proof. + error ScopeMismatch(); + + /// @notice Thrown when cross-chain verification is attempted but not yet supported. + /// @dev Cross-chain bridging functionality is not implemented yet. + error CrossChainIsNotSupportedYet(); - /// @notice Thrown when the revealed data type is invalid or not supported. - /// @dev Raised during the processing of revealed data if it does not match any supported type. - error INVALID_REVEALED_DATA_TYPE(); + /// @notice Thrown when the input data is too short for decoding. + /// @dev The input data must be at least 97 bytes (1 + 31 + 32 + 32 + 1 minimum). + error InputTooShort(); - error INVALID_ATTESTATION_ID(); + /// @notice Thrown when the user context data is too short for decoding. + /// @dev The user context data must be at least 96 bytes (32 + 32 + 32 minimum). + error UserContextDataTooShort(); + + /// @notice Thrown when the user identifier hash does not match the proof user identifier. + /// @dev Ensures that the user context data hash matches the user identifier in the proof. + error InvalidUserIdentifierInProof(); // ==================================================== // Constructor // ==================================================== /** - * @notice Constructor that disables initializers. - * @dev Prevents direct initialization of the implementation contract. + * @notice Constructor that disables initializers for the implementation contract. + * @dev This prevents the implementation contract from being initialized directly. + * The actual initialization should only happen through the proxy. */ constructor() { _disableInitializers(); @@ -172,124 +178,30 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde // Initializer // ==================================================== - function initialize( - bytes32[] memory attestationIds, - address[] memory registryAddresses, - address[] memory vcAndDiscloseCircuitVerifierAddresses, - uint256[] memory registerCircuitVerifierIds, - address[] memory registerCircuitVerifierAddresses, - uint256[] memory dscCircuitVerifierIds, - address[] memory dscCircuitVerifierAddresses - ) external initializer { - __ImplRoot_init(); - if (attestationIds.length != registryAddresses.length) { - revert LENGTH_MISMATCH(); - } - if (attestationIds.length != vcAndDiscloseCircuitVerifierAddresses.length) { - revert LENGTH_MISMATCH(); - } - if (registerCircuitVerifierIds.length != registerCircuitVerifierAddresses.length) { - revert LENGTH_MISMATCH(); - } - if (dscCircuitVerifierIds.length != dscCircuitVerifierAddresses.length) { - revert LENGTH_MISMATCH(); - } - for (uint256 i = 0; i < attestationIds.length; i++) { - _attestationIdToRegistry[attestationIds[i]] = registryAddresses[i]; - _attestationIdToDiscloseVerifier[attestationIds[i]] = vcAndDiscloseCircuitVerifierAddresses[i]; - } - for (uint256 i = 0; i < registerCircuitVerifierIds.length; i++) { - _sigTypeToRegisterCircuitVerifiers[registerCircuitVerifierIds[i]] = registerCircuitVerifierAddresses[i]; - } - for (uint256 i = 0; i < dscCircuitVerifierIds.length; i++) { - _sigTypeToDscCircuitVerifiers[dscCircuitVerifierIds[i]] = dscCircuitVerifierAddresses[i]; - } - emit HubInitialized( - attestationIds, - registryAddresses, - vcAndDiscloseCircuitVerifierAddresses, - registerCircuitVerifierIds, - registerCircuitVerifierAddresses, - dscCircuitVerifierIds, - dscCircuitVerifierAddresses - ); - } - - // ==================================================== - // External View Functions - // ==================================================== - - /** - * @notice Retrieves the registry address. - * @return The address of the Identity Registry. - */ - function registry(bytes32 attestationId) external view virtual onlyProxy returns (address) { - return _attestationIdToRegistry[attestationId]; - } - /** - * @notice Retrieves the VC and Disclose circuit verifier address. - * @return The address of the VC and Disclose circuit verifier. + * @notice Initializes the Identity Verification Hub V2 contract. + * @dev Sets up the contract state including circuit version and emits initialization event. + * This function can only be called once due to the initializer modifier. + * The circuit version is set to 2 for V2 hub compatibility. */ - function vcAndDiscloseCircuitVerifier(bytes32 attestationId) external view virtual onlyProxy returns (address) { - return _attestationIdToDiscloseVerifier[attestationId]; - } + function initialize() external initializer { + __ImplRoot_init(); - /** - * @notice Retrieves the register circuit verifier address for a given signature type. - * @param typeId The signature type identifier. - * @return The register circuit verifier address. - */ - function sigTypeToRegisterCircuitVerifiers(uint256 typeId) external view virtual onlyProxy returns (address) { - return _sigTypeToRegisterCircuitVerifiers[typeId]; - } + // Initialize circuit version to 2 for V2 hub + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + $._circuitVersion = 2; - /** - * @notice Retrieves the DSC circuit verifier address for a given signature type. - * @param typeId The signature type identifier. - * @return The DSC circuit verifier address. - */ - function sigTypeToDscCircuitVerifiers(uint256 typeId) external view virtual onlyProxy returns (address) { - return _sigTypeToDscCircuitVerifiers[typeId]; - } - - /** - * @notice Verifies a VC and Disclose proof using unified bytes interface. - * @dev Supports both passport and ID card proofs through a unified interface. - * @param proofData Encoded proof data containing all necessary verification parameters. - * @return result Encoded verification result containing all relevant data. - */ - function verifyVcAndDisclose( - bytes calldata proofData - ) external view virtual onlyProxy returns (bytes memory result) { - // Decode the attestation ID from the first 32 bytes - bytes32 attestationId; - assembly { - attestationId := calldataload(proofData.offset) - } - - if (attestationId == AttestationId.E_PASSPORT) { - // Passport proof - VcAndDiscloseHubProof memory proof = _decodePassportProof(proofData[32:]); - VcAndDiscloseVerificationResult memory passportResult = _verifyPassportVcAndDisclose(proof); - return _encodePassportResult(passportResult); - } else if (attestationId == AttestationId.EU_ID_CARD) { - // ID Card proof - IdCardVcAndDiscloseHubProof memory proof = _decodeIdCardProof(proofData[32:]); - IdCardVcAndDiscloseVerificationResult memory idCardResult = _verifyEuIdVcAndDisclose(proof); - return _encodeIdCardResult(idCardResult); - } else { - revert INVALID_ATTESTATION_ID(); - } + emit HubInitializedV2(); } // ==================================================== - // External Functions - Registration + // External Functions // ==================================================== /** - * @notice Registers a passport commitment using a register circuit proof. - * @dev Verifies the proof and then calls the Identity Registry to register the commitment. + * @notice Registers a commitment using a register circuit proof. + * @dev Verifies the register circuit proof and then calls the Identity Registry to register the commitment. + * @param attestationId The attestation ID. * @param registerCircuitVerifierId The identifier for the register circuit verifier to use. * @param registerCircuitProof The register circuit proof data. */ @@ -299,20 +211,21 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof ) external virtual onlyProxy { _verifyRegisterProof(attestationId, registerCircuitVerifierId, registerCircuitProof); + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); if (attestationId == AttestationId.E_PASSPORT) { - IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).registerCommitment( + IIdentityRegistryV1($._registries[attestationId]).registerCommitment( attestationId, registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_NULLIFIER_INDEX], registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_COMMITMENT_INDEX] ); } else if (attestationId == AttestationId.EU_ID_CARD) { - IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).registerCommitment( + IIdentityRegistryIdCardV1($._registries[attestationId]).registerCommitment( attestationId, registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_NULLIFIER_INDEX], registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_COMMITMENT_INDEX] ); } else { - revert INVALID_ATTESTATION_ID(); + revert InvalidAttestationId(); } } @@ -328,29 +241,64 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof ) external virtual onlyProxy { _verifyDscProof(attestationId, dscCircuitVerifierId, dscCircuitProof); + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); if (attestationId == AttestationId.E_PASSPORT) { - IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).registerDscKeyCommitment( + IIdentityRegistryV1($._registries[attestationId]).registerDscKeyCommitment( dscCircuitProof.pubSignals[CircuitConstantsV2.DSC_TREE_LEAF_INDEX] ); } else if (attestationId == AttestationId.EU_ID_CARD) { - IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).registerDscKeyCommitment( + IIdentityRegistryIdCardV1($._registries[attestationId]).registerDscKeyCommitment( dscCircuitProof.pubSignals[CircuitConstantsV2.DSC_TREE_LEAF_INDEX] ); } else { - revert INVALID_ATTESTATION_ID(); + revert InvalidAttestationId(); } } - // ==================================================== - // External Functions - Only Owner - // ==================================================== + /** + * @notice Sets verification config in V2 storage (owner only) + * @dev The configId is automatically generated from the config content using sha256(abi.encode(config)) + * @param config The verification configuration + * @return configId The generated config ID + */ + function setVerificationConfigV2( + SelfStructs.VerificationConfigV2 memory config + ) external virtual onlyProxy returns (bytes32 configId) { + configId = generateConfigId(config); + IdentityVerificationHubV2Storage storage $v2 = _getIdentityVerificationHubV2Storage(); + $v2._v2VerificationConfigs[configId] = config; + + emit VerificationConfigV2Set(configId, config); + } + + /** + * @notice Main verification function with new structured input format. + * @dev Orchestrates the complete verification process including proof validation and result handling. + * This function decodes the input, executes the verification flow, and handles the result based on destination chain. + * @param baseVerificationInput The base verification input containing header and proof data. + * @param userContextData The user context data containing config ID, destination chain ID, user identifier, and additional data. + */ + function verify(bytes calldata baseVerificationInput, bytes calldata userContextData) external virtual onlyProxy { + (SelfStructs.HubInputHeader memory header, bytes calldata proofData) = _decodeInput(baseVerificationInput); + + // Perform verification and get output along with user data + (bytes memory output, uint256 destChainId, bytes memory userDataToPass) = _executeVerificationFlow( + header, + proofData, + userContextData + ); + + // Use destChainId and userDataToPass returned from _executeVerificationFlow + _handleVerificationResult(destChainId, output, userDataToPass); + } /** * @notice Updates the registry address. * @param registryAddress The new registry address. */ function updateRegistry(bytes32 attestationId, address registryAddress) external virtual onlyProxy onlyOwner { - _attestationIdToRegistry[attestationId] = registryAddress; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + $._registries[attestationId] = registryAddress; emit RegistryUpdated(attestationId, registryAddress); } @@ -362,173 +310,372 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde bytes32 attestationId, address vcAndDiscloseCircuitVerifierAddress ) external virtual onlyProxy onlyOwner { - _attestationIdToDiscloseVerifier[attestationId] = vcAndDiscloseCircuitVerifierAddress; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + $._discloseVerifiers[attestationId] = vcAndDiscloseCircuitVerifierAddress; emit VcAndDiscloseCircuitUpdated(attestationId, vcAndDiscloseCircuitVerifierAddress); } /** * @notice Updates the register circuit verifier for a specific signature type. + * @param attestationId The attestation identifier. * @param typeId The signature type identifier. * @param verifierAddress The new register circuit verifier address. */ function updateRegisterCircuitVerifier( + bytes32 attestationId, uint256 typeId, address verifierAddress ) external virtual onlyProxy onlyOwner { - _sigTypeToRegisterCircuitVerifiers[typeId] = verifierAddress; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + $._registerCircuitVerifiers[attestationId][typeId] = verifierAddress; emit RegisterCircuitVerifierUpdated(typeId, verifierAddress); } /** * @notice Updates the DSC circuit verifier for a specific signature type. + * @param attestationId The attestation identifier. * @param typeId The signature type identifier. * @param verifierAddress The new DSC circuit verifier address. */ - function updateDscVerifier(uint256 typeId, address verifierAddress) external virtual onlyProxy onlyOwner { - _sigTypeToDscCircuitVerifiers[typeId] = verifierAddress; + function updateDscVerifier( + bytes32 attestationId, + uint256 typeId, + address verifierAddress + ) external virtual onlyProxy onlyOwner { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + $._dscCircuitVerifiers[attestationId][typeId] = verifierAddress; emit DscCircuitVerifierUpdated(typeId, verifierAddress); } /** * @notice Batch updates register circuit verifiers. + * @param attestationIds An array of attestation identifiers. * @param typeIds An array of signature type identifiers. * @param verifierAddresses An array of new register circuit verifier addresses. */ function batchUpdateRegisterCircuitVerifiers( + bytes32[] calldata attestationIds, uint256[] calldata typeIds, address[] calldata verifierAddresses ) external virtual onlyProxy onlyOwner { - if (typeIds.length != verifierAddresses.length) { - revert LENGTH_MISMATCH(); + if (attestationIds.length != typeIds.length || attestationIds.length != verifierAddresses.length) { + revert LengthMismatch(); } - for (uint256 i = 0; i < typeIds.length; i++) { - _sigTypeToRegisterCircuitVerifiers[typeIds[i]] = verifierAddresses[i]; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + for (uint256 i = 0; i < attestationIds.length; i++) { + $._registerCircuitVerifiers[attestationIds[i]][typeIds[i]] = verifierAddresses[i]; emit RegisterCircuitVerifierUpdated(typeIds[i], verifierAddresses[i]); } } /** * @notice Batch updates DSC circuit verifiers. + * @param attestationIds An array of attestation identifiers. * @param typeIds An array of signature type identifiers. * @param verifierAddresses An array of new DSC circuit verifier addresses. */ function batchUpdateDscCircuitVerifiers( + bytes32[] calldata attestationIds, uint256[] calldata typeIds, address[] calldata verifierAddresses ) external virtual onlyProxy onlyOwner { - if (typeIds.length != verifierAddresses.length) { - revert LENGTH_MISMATCH(); + if (attestationIds.length != typeIds.length || attestationIds.length != verifierAddresses.length) { + revert LengthMismatch(); } - for (uint256 i = 0; i < typeIds.length; i++) { - _sigTypeToDscCircuitVerifiers[typeIds[i]] = verifierAddresses[i]; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + for (uint256 i = 0; i < attestationIds.length; i++) { + $._dscCircuitVerifiers[attestationIds[i]][typeIds[i]] = verifierAddresses[i]; emit DscCircuitVerifierUpdated(typeIds[i], verifierAddresses[i]); } } // ==================================================== - // Internal Functions + // External View Functions // ==================================================== /** - * @notice Internal function to verify passport VC and Disclose proof. + * @notice Returns the registry address for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The registry address associated with the attestation ID. */ - function _verifyPassportVcAndDisclose( - VcAndDiscloseHubProof memory proof - ) internal view returns (VcAndDiscloseVerificationResult memory) { - VcAndDiscloseVerificationResult memory result; - CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices( - AttestationId.E_PASSPORT - ); + function registry(bytes32 attestationId) external view virtual onlyProxy returns (address) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + return $._registries[attestationId]; + } - result.identityCommitmentRoot = _verifyVcAndDiscloseProof( - AttestationId.E_PASSPORT, - proof.vcAndDiscloseProof, - proof.olderThanEnabled, - proof.olderThan, - proof.ofacEnabled, - proof.forbiddenCountriesEnabled, - proof.forbiddenCountriesListPacked - ); + /** + * @notice Returns the disclose verifier address for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The disclose verifier address associated with the attestation ID. + */ + function discloseVerifier(bytes32 attestationId) external view virtual onlyProxy returns (address) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + return $._discloseVerifiers[attestationId]; + } - for (uint256 i = 0; i < 3; i++) { - result.revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; + /** + * @notice Returns the register circuit verifier address for a given attestation ID and type ID. + * @param attestationId The attestation ID to query. + * @param typeId The type ID to query. + * @return The register circuit verifier address associated with the attestation ID and type ID. + */ + function registerCircuitVerifiers( + bytes32 attestationId, + uint256 typeId + ) external view virtual onlyProxy returns (address) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + return $._registerCircuitVerifiers[attestationId][typeId]; + } + + /** + * @notice Returns the DSC circuit verifier address for a given attestation ID and type ID. + * @param attestationId The attestation ID to query. + * @param typeId The type ID to query. + * @return The DSC circuit verifier address associated with the attestation ID and type ID. + */ + function dscCircuitVerifiers( + bytes32 attestationId, + uint256 typeId + ) external view virtual onlyProxy returns (address) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + return $._dscCircuitVerifiers[attestationId][typeId]; + } + + /** + * @notice Returns the merkle root timestamp for a given attestation ID and root. + * @param attestationId The attestation ID to query. + * @param root The merkle root to query. + * @return The merkle root timestamp associated with the attestation ID and root. + */ + function rootTimestamp(bytes32 attestationId, uint256 root) external view virtual onlyProxy returns (uint256) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + address registryAddress = $._registries[attestationId]; + + if (attestationId == AttestationId.E_PASSPORT) { + return IIdentityRegistryV1(registryAddress).rootTimestamps(root); + } else if (attestationId == AttestationId.EU_ID_CARD) { + return IIdentityRegistryIdCardV1(registryAddress).rootTimestamps(root); + } else { + revert InvalidAttestationId(); } - for (uint256 i = 0; i < 4; i++) { - result.forbiddenCountriesListPacked[i] = proof.vcAndDiscloseProof.pubSignals[ - indices.forbiddenCountriesListPackedIndex + i - ]; + } + + /** + * @notice Returns the identity commitment merkle root for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The identity commitment merkle root associated with the attestation ID. + */ + function getIdentityCommitmentMerkleRoot(bytes32 attestationId) external view virtual onlyProxy returns (uint256) { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + address registryAddress = $._registries[attestationId]; + + if (attestationId == AttestationId.E_PASSPORT) { + return IIdentityRegistryV1(registryAddress).getIdentityCommitmentMerkleRoot(); + } else if (attestationId == AttestationId.EU_ID_CARD) { + return IIdentityRegistryIdCardV1(registryAddress).getIdentityCommitmentMerkleRoot(); + } else { + revert InvalidAttestationId(); } - result.nullifier = proof.vcAndDiscloseProof.pubSignals[indices.nullifierIndex]; - result.attestationId = proof.vcAndDiscloseProof.pubSignals[indices.attestationIdIndex]; - result.userIdentifier = proof.vcAndDiscloseProof.pubSignals[indices.userIdentifierIndex]; - result.scope = proof.vcAndDiscloseProof.pubSignals[indices.scopeIndex]; - return result; } /** - * @notice Internal function to verify ID card VC and Disclose proof. + * @notice Checks if a verification config exists + * @param configId The configuration identifier + * @return exists Whether the config exists */ - function _verifyEuIdVcAndDisclose( - IdCardVcAndDiscloseHubProof memory proof - ) internal view returns (IdCardVcAndDiscloseVerificationResult memory) { - IdCardVcAndDiscloseVerificationResult memory result; - CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices( - AttestationId.EU_ID_CARD - ); + function verificationConfigV2Exists(bytes32 configId) external view virtual onlyProxy returns (bool exists) { + SelfStructs.VerificationConfigV2 memory config = getVerificationConfigV2(configId); + return generateConfigId(config) == configId; + } - result.identityCommitmentRoot = _verifyVcAndDiscloseProof( - AttestationId.EU_ID_CARD, - proof.vcAndDiscloseProof, - proof.olderThanEnabled, - proof.olderThan, - _convertOfacFlags(proof.ofacEnabled), - proof.forbiddenCountriesEnabled, - proof.forbiddenCountriesListPacked - ); + // ==================================================== + // Public Functions + // ==================================================== - for (uint256 i = 0; i < 4; i++) { - result.revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; + /** + * @notice Generates a config ID from a verification config + * @param config The verification configuration + * @return The generated config ID (sha256 hash of encoded config) + */ + function generateConfigId(SelfStructs.VerificationConfigV2 memory config) public pure returns (bytes32) { + return sha256(abi.encode(config)); + } + + // ==================================================== + // Internal Functions + // ==================================================== + + /** + * @notice Executes the complete verification flow. + * @dev Processes user context data, retrieves verification config, performs basic verification, + * executes custom verification logic, and formats the output. + * @param header The decoded hub input header containing verification parameters. + * @param proofData The raw proof data to be decoded and verified. + * @param userContextData The user-provided context data. + * @return output The formatted verification output. + * @return destChainId The destination chain identifier. + * @return userDataToPass The remaining user data to pass through. + */ + function _executeVerificationFlow( + SelfStructs.HubInputHeader memory header, + bytes memory proofData, + bytes calldata userContextData + ) internal returns (bytes memory output, uint256 destChainId, bytes memory userDataToPass) { + bytes32 configId; + uint256 userIdentifier; + bytes calldata remainingData; + { + uint256 _destChainId; + (configId, _destChainId, userIdentifier, remainingData) = _decodeUserContextData(userContextData); + destChainId = _destChainId; } - for (uint256 i = 0; i < 4; i++) { - result.forbiddenCountriesListPacked[i] = proof.vcAndDiscloseProof.pubSignals[ - indices.forbiddenCountriesListPackedIndex + i - ]; + + { + bytes memory config = _getVerificationConfigById(configId); + + bytes memory proofOutput = _basicVerification( + header, + _decodeVcAndDiscloseProof(proofData), + userContextData, + userIdentifier + ); + + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput = CustomVerifier.customVerify( + header.attestationId, + config, + proofOutput + ); + + output = _formatVerificationOutput(header.contractVersion, genericDiscloseOutput); } - result.nullifier = proof.vcAndDiscloseProof.pubSignals[indices.nullifierIndex]; - result.attestationId = proof.vcAndDiscloseProof.pubSignals[indices.attestationIdIndex]; - result.userIdentifier = proof.vcAndDiscloseProof.pubSignals[indices.userIdentifierIndex]; - result.scope = proof.vcAndDiscloseProof.pubSignals[indices.scopeIndex]; - return result; + + userDataToPass = remainingData; } + /** + * @notice Handles verification result based on destination chain. + * @dev Routes the verification result to the appropriate handler based on whether + * the destination is the current chain or requires cross-chain bridging. + * @param destChainId The destination chain identifier. + * @param output The verification output data. + * @param userDataToPass The user data to pass to the result handler. + */ + function _handleVerificationResult(uint256 destChainId, bytes memory output, bytes memory userDataToPass) internal { + if (destChainId == block.chainid) { + ISelfVerificationRoot(msg.sender).onVerificationSuccess(output, userDataToPass); + } else { + // Call external bridge + // _handleBridge() + revert CrossChainIsNotSupportedYet(); + } + } + + /** + * @notice Unified basic verification function for both passport and ID card proofs. + * @dev Performs four core verification steps: scopeCheck, rootCheck, currentDateCheck, groth16 proof verification + * @param header The hub input header containing scope and attestation information + * @param vcAndDiscloseProof The VC and Disclose proof data + * @param userContextData The user context data for validation + * @param userIdentifier The user identifier for proof validation + * @return output The verification result encoded as bytes (PassportOutput or EuIdOutput) + */ + function _basicVerification( + SelfStructs.HubInputHeader memory header, + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + bytes calldata userContextData, + uint256 userIdentifier + ) internal returns (bytes memory output) { + // Scope 1: Basic checks (scope and user identifier) + { + CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices( + header.attestationId + ); + _performScopeCheck(header.scope, vcAndDiscloseProof, indices); + _performUserIdentifierCheck(userContextData, vcAndDiscloseProof, header.attestationId, indices); + } + + // Scope 2: Root and date checks + { + CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices( + header.attestationId + ); + _performRootCheck(header.attestationId, vcAndDiscloseProof, indices); + _performCurrentDateCheck(vcAndDiscloseProof, indices); + } + + // Scope 3: Groth16 proof verification + _performGroth16ProofVerification(header.attestationId, vcAndDiscloseProof); + + // Scope 4: Create and return output + { + CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices( + header.attestationId + ); + return _createVerificationOutput(header.attestationId, vcAndDiscloseProof, indices, userIdentifier); + } + } + + // ==================================================== + // Internal View Functions + // ==================================================== + + /** + * @notice Gets verification config from V2 storage + * @param configId The configuration identifier + * @return The verification configuration + */ + function getVerificationConfigV2( + bytes32 configId + ) internal view virtual onlyProxy returns (SelfStructs.VerificationConfigV2 memory) { + IdentityVerificationHubV2Storage storage $v2 = _getIdentityVerificationHubV2Storage(); + return $v2._v2VerificationConfigs[configId]; + } + + /** + * @notice Gets verification config by configId + */ + function _getVerificationConfigById(bytes32 configId) internal view returns (bytes memory config) { + IdentityVerificationHubV2Storage storage $v2 = _getIdentityVerificationHubV2Storage(); + SelfStructs.VerificationConfigV2 memory verificationConfig = $v2._v2VerificationConfigs[configId]; + config = GenericFormatter.formatV2Config(verificationConfig); + } + + /** + * @notice Verifies the register circuit proof. + * @dev Uses the register circuit verifier specified by registerCircuitVerifierId. + * @param attestationId The attestation ID. + * @param registerCircuitVerifierId The identifier for the register circuit verifier. + * @param registerCircuitProof The register circuit proof data. + */ function _verifyRegisterProof( bytes32 attestationId, uint256 registerCircuitVerifierId, IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof ) internal view { - address verifier = _sigTypeToRegisterCircuitVerifiers[registerCircuitVerifierId]; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + address verifier = $._registerCircuitVerifiers[attestationId][registerCircuitVerifierId]; if (verifier == address(0)) { - revert NO_VERIFIER_SET(); + revert NoVerifierSet(); } if (attestationId == AttestationId.E_PASSPORT) { if ( - !IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).checkDscKeyCommitmentMerkleRoot( + !IIdentityRegistryV1($._registries[attestationId]).checkDscKeyCommitmentMerkleRoot( registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_MERKLE_ROOT_INDEX] ) ) { - revert INVALID_COMMITMENT_ROOT(); + revert InvalidDscCommitmentRoot(); } } else if (attestationId == AttestationId.EU_ID_CARD) { if ( - !IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).checkDscKeyCommitmentMerkleRoot( + !IIdentityRegistryIdCardV1($._registries[attestationId]).checkDscKeyCommitmentMerkleRoot( registerCircuitProof.pubSignals[CircuitConstantsV2.REGISTER_MERKLE_ROOT_INDEX] ) ) { - revert INVALID_COMMITMENT_ROOT(); + revert InvalidDscCommitmentRoot(); } } else { - revert INVALID_ATTESTATION_ID(); + revert InvalidAttestationId(); } if ( @@ -539,7 +686,7 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde registerCircuitProof.pubSignals ) ) { - revert INVALID_REGISTER_PROOF(); + revert InvalidRegisterProof(); } } @@ -554,29 +701,30 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde uint256 dscCircuitVerifierId, IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof ) internal view { - address verifier = _sigTypeToDscCircuitVerifiers[dscCircuitVerifierId]; + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + address verifier = $._dscCircuitVerifiers[attestationId][dscCircuitVerifierId]; if (verifier == address(0)) { - revert NO_VERIFIER_SET(); + revert NoVerifierSet(); } if (attestationId == AttestationId.E_PASSPORT) { if ( - !IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).checkCscaRoot( + !IIdentityRegistryV1($._registries[attestationId]).checkCscaRoot( dscCircuitProof.pubSignals[CircuitConstantsV2.DSC_CSCA_ROOT_INDEX] ) ) { - revert INVALID_CSCA_ROOT(); + revert InvalidCscaRoot(); } } else if (attestationId == AttestationId.EU_ID_CARD) { if ( - !IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).checkCscaRoot( + !IIdentityRegistryIdCardV1($._registries[attestationId]).checkCscaRoot( dscCircuitProof.pubSignals[CircuitConstantsV2.DSC_CSCA_ROOT_INDEX] ) ) { - revert INVALID_CSCA_ROOT(); + revert InvalidCscaRoot(); } } else { - revert INVALID_ATTESTATION_ID(); + revert InvalidAttestationId(); } if ( @@ -587,7 +735,7 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde dscCircuitProof.pubSignals ) ) { - revert INVALID_DSC_PROOF(); + revert InvalidDscProof(); } } @@ -601,201 +749,289 @@ contract IdentityVerificationHubImplV2 is IdentityVerificationHubStorageV2, IIde } /** - * @notice Unified internal verification function for both passport and ID card proofs. - * @dev Handles the common verification logic for both proof types. + * @notice Performs scope validation */ - function _verifyVcAndDiscloseProof( + function _performScopeCheck( + uint256 headerScope, + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + CircuitConstantsV2.DiscloseIndices memory indices + ) internal view { + // Get scope from proof using the scope index from indices + uint256 proofScope = vcAndDiscloseProof.pubSignals[indices.scopeIndex]; + + if (headerScope != proofScope) { + revert ScopeMismatch(); + } + } + + /** + * @notice Performs identity commitment root verification + */ + function _performRootCheck( bytes32 attestationId, IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, - bool olderThanEnabled, - uint256 olderThan, - bool[3] memory ofacEnabled, - bool forbiddenCountriesEnabled, - uint256[4] memory forbiddenCountriesListPacked - ) internal view returns (uint256 identityCommitmentRoot) { - // Get indices for the specific attestation type - CircuitConstantsV2.DiscloseIndices memory indices = CircuitConstantsV2.getDiscloseIndices(attestationId); - bool isPassport = (attestationId == AttestationId.E_PASSPORT); - - // verify identity commitment root - if (isPassport) { - if ( - !IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).checkIdentityCommitmentRoot( - vcAndDiscloseProof.pubSignals[indices.merkleRootIndex] - ) - ) { - revert INVALID_COMMITMENT_ROOT(); + CircuitConstantsV2.DiscloseIndices memory indices + ) internal view { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); + uint256 merkleRoot = vcAndDiscloseProof.pubSignals[indices.merkleRootIndex]; + + address registryAddress = $._registries[attestationId]; + + if (registryAddress == address(0)) { + revert("Registry not set for attestation ID"); + } + + if (attestationId == AttestationId.E_PASSPORT) { + if (!IIdentityRegistryV1($._registries[attestationId]).checkIdentityCommitmentRoot(merkleRoot)) { + revert InvalidIdentityCommitmentRoot(); } - } else { - if ( - !IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).checkIdentityCommitmentRoot( - vcAndDiscloseProof.pubSignals[indices.merkleRootIndex] - ) - ) { - revert INVALID_COMMITMENT_ROOT(); + } else if (attestationId == AttestationId.EU_ID_CARD) { + if (!IIdentityRegistryIdCardV1($._registries[attestationId]).checkIdentityCommitmentRoot(merkleRoot)) { + revert InvalidIdentityCommitmentRoot(); } + } else { + revert InvalidAttestationId(); } + } - // verify current date + /** + * @notice Performs current date validation + */ + function _performCurrentDateCheck( + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + CircuitConstantsV2.DiscloseIndices memory indices + ) internal view { uint[6] memory dateNum; for (uint256 i = 0; i < 6; i++) { dateNum[i] = vcAndDiscloseProof.pubSignals[indices.currentDateIndex + i]; } uint currentTimestamp = Formatter.proofDateToUnixTimestamp(dateNum); - if ( - currentTimestamp < _getStartOfDayTimestamp() - 1 days + 1 || - currentTimestamp > _getStartOfDayTimestamp() + 1 days - 1 - ) { - revert CURRENT_DATE_NOT_IN_VALID_RANGE(); - } - - // verify attributes - if (isPassport) { - uint256[3] memory revealedDataPacked; - for (uint256 i = 0; i < 3; i++) { - revealedDataPacked[i] = vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; - } - - if (olderThanEnabled) { - if ( - !CircuitAttributeHandlerV2.compareOlderThan( - attestationId, - Formatter.fieldElementsToBytes(revealedDataPacked), - olderThan - ) - ) { - revert INVALID_OLDER_THAN(); - } - } - - if (ofacEnabled[0] || ofacEnabled[1] || ofacEnabled[2]) { - if ( - !CircuitAttributeHandlerV2.compareOfac( - attestationId, - Formatter.fieldElementsToBytes(revealedDataPacked), - ofacEnabled[0], - ofacEnabled[1], - ofacEnabled[2] - ) - ) { - revert INVALID_OFAC(); - } - if ( - !IIdentityRegistryV1(_attestationIdToRegistry[attestationId]).checkOfacRoots( - vcAndDiscloseProof.pubSignals[indices.passportNoSmtRootIndex], - vcAndDiscloseProof.pubSignals[indices.namedobSmtRootIndex], - vcAndDiscloseProof.pubSignals[indices.nameyobSmtRootIndex] - ) - ) { - revert INVALID_OFAC_ROOT(); - } - } - } else { - uint256[4] memory revealedDataPacked; - for (uint256 i = 0; i < 4; i++) { - revealedDataPacked[i] = vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; - } - - if (olderThanEnabled) { - if ( - !CircuitAttributeHandlerV2.compareOlderThan( - attestationId, - Formatter.fieldElementsToBytesIdCard(revealedDataPacked), - olderThan - ) - ) { - revert INVALID_OLDER_THAN(); - } - } + uint startOfDay = _getStartOfDayTimestamp(); - if (ofacEnabled[1] || ofacEnabled[2]) { - if ( - !CircuitAttributeHandlerV2.compareOfac( - attestationId, - Formatter.fieldElementsToBytesIdCard(revealedDataPacked), - false, // Document number OFAC not applicable for ID cards - ofacEnabled[1], - ofacEnabled[2] - ) - ) { - revert INVALID_OFAC(); - } - if ( - !IIdentityRegistryIdCardV1(_attestationIdToRegistry[attestationId]).checkOfacRoots( - vcAndDiscloseProof.pubSignals[indices.namedobSmtRootIndex], - vcAndDiscloseProof.pubSignals[indices.nameyobSmtRootIndex] - ) - ) { - revert INVALID_OFAC_ROOT(); - } - } + if (currentTimestamp < startOfDay - 1 days + 1 || currentTimestamp > startOfDay + 1 days - 1) { + revert CurrentDateNotInValidRange(); } + } - if (forbiddenCountriesEnabled) { - for (uint256 i = 0; i < 4; i++) { - if ( - forbiddenCountriesListPacked[i] != - vcAndDiscloseProof.pubSignals[indices.forbiddenCountriesListPackedIndex + i] - ) { - revert INVALID_FORBIDDEN_COUNTRIES(); - } - } - } + /** + * @notice Performs Groth16 proof verification + */ + function _performGroth16ProofVerification( + bytes32 attestationId, + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof + ) internal view { + IdentityVerificationHubStorage storage $ = _getIdentityVerificationHubStorage(); - // verify the proof using the VC and Disclose circuit verifier if ( - !IVcAndDiscloseCircuitVerifier(_attestationIdToDiscloseVerifier[attestationId]).verifyProof( + !IVcAndDiscloseCircuitVerifier($._discloseVerifiers[attestationId]).verifyProof( vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals ) ) { - revert INVALID_VC_AND_DISCLOSE_PROOF(); + revert InvalidVcAndDiscloseProof(); } + } - return vcAndDiscloseProof.pubSignals[indices.merkleRootIndex]; + // ==================================================== + // Internal Pure Functions + // ==================================================== + + /** + * @notice Decodes the input data to extract the header and proof data. + * @param baseVerificationInput The input data to decode. Format: | 1 byte contractVersion | 31 bytes buffer | 32 bytes scope | 32 bytes attestationId | user defined data | + * @return header The header of the input data. + * @return proofData The proof data of the input data. + */ + function _decodeInput( + bytes calldata baseVerificationInput + ) internal pure returns (SelfStructs.HubInputHeader memory header, bytes calldata proofData) { + if (baseVerificationInput.length < 97) { + revert InputTooShort(); + } + header.contractVersion = uint8(baseVerificationInput[0]); + header.scope = uint256(bytes32(baseVerificationInput[32:64])); + header.attestationId = bytes32(baseVerificationInput[64:96]); + proofData = baseVerificationInput[96:]; } /** - * @notice Converts ID card OFAC flags (2 elements) to passport format (3 elements). + * @notice Decodes userContextData to extract configId, destChainId, and userIdentifier + * @param userContextData User-defined data in format: | 32 bytes configId | 32 bytes destChainId | 32 bytes userIdentifier | data | + * @return configId The configuration identifier + * @return destChainId The destination chain identifier + * @return userIdentifier The user identifier + * @return remainingData The remaining data after the first 96 bytes */ - function _convertOfacFlags(bool[2] memory idCardOfacEnabled) internal pure returns (bool[3] memory) { - bool[3] memory passportOfacEnabled; - passportOfacEnabled[0] = false; // ID cards don't have passport number OFAC - passportOfacEnabled[1] = idCardOfacEnabled[0]; // name and DOB OFAC - passportOfacEnabled[2] = idCardOfacEnabled[1]; // name and YOB OFAC - return passportOfacEnabled; + function _decodeUserContextData( + bytes calldata userContextData + ) + internal + pure + returns (bytes32 configId, uint256 destChainId, uint256 userIdentifier, bytes calldata remainingData) + { + if (userContextData.length < 96) { + revert UserContextDataTooShort(); + } + configId = bytes32(userContextData[0:32]); + destChainId = uint256(bytes32(userContextData[32:64])); + userIdentifier = uint256(bytes32(userContextData[64:96])); + remainingData = userContextData[96:]; } /** - * @notice Decodes passport proof data from bytes. + * @notice Formats verification output based on contract version. + * @dev Converts the generic disclosure output to the appropriate struct format based on version. + * @param contractVersion The contract version to determine output format. + * @param genericDiscloseOutput The generic disclosure output to format. + * @return output The formatted output as bytes. */ - function _decodePassportProof(bytes memory data) internal pure returns (VcAndDiscloseHubProof memory) { - return abi.decode(data, (VcAndDiscloseHubProof)); + function _formatVerificationOutput( + uint256 contractVersion, + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput + ) internal pure returns (bytes memory output) { + if (contractVersion == 2) { + output = GenericFormatter.toV2Struct(genericDiscloseOutput); + } } /** - * @notice Decodes ID card proof data from bytes. + * @notice Creates verification output based on attestation type. + * @dev Routes to the appropriate output creation function based on the attestation ID. + * @param attestationId The attestation identifier (passport or EU ID card). + * @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. + * @return The encoded verification output. */ - function _decodeIdCardProof(bytes memory data) internal pure returns (IdCardVcAndDiscloseHubProof memory) { - return abi.decode(data, (IdCardVcAndDiscloseHubProof)); + function _createVerificationOutput( + bytes32 attestationId, + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + CircuitConstantsV2.DiscloseIndices memory indices, + uint256 userIdentifier + ) internal pure returns (bytes memory) { + if (attestationId == AttestationId.E_PASSPORT) { + return _createPassportOutput(vcAndDiscloseProof, indices, attestationId, userIdentifier); + } else if (attestationId == AttestationId.EU_ID_CARD) { + return _createEuIdOutput(vcAndDiscloseProof, indices, attestationId, userIdentifier); + } else { + revert InvalidAttestationId(); + } } /** - * @notice Encodes passport verification result to bytes. + * @notice Creates passport output struct. + * @dev Constructs a PassportOutput struct from the proof data and encodes it. + * @param vcAndDiscloseProof The VC and Disclose proof containing passport data. + * @param indices The circuit-specific indices for extracting proof values. + * @param attestationId The attestation identifier. + * @param userIdentifier The user identifier. + * @return The encoded PassportOutput struct. */ - function _encodePassportResult(VcAndDiscloseVerificationResult memory result) internal pure returns (bytes memory) { - return abi.encode(result); + function _createPassportOutput( + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + CircuitConstantsV2.DiscloseIndices memory indices, + bytes32 attestationId, + uint256 userIdentifier + ) internal pure returns (bytes memory) { + SelfStructs.PassportOutput memory passportOutput; + passportOutput.attestationId = uint256(attestationId); + passportOutput.userIdentifier = userIdentifier; + passportOutput.nullifier = vcAndDiscloseProof.pubSignals[indices.nullifierIndex]; + + // Extract revealed data + uint256[3] memory revealedDataPacked; + for (uint256 i = 0; i < 3; i++) { + revealedDataPacked[i] = vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; + } + passportOutput.revealedDataPacked = Formatter.fieldElementsToBytes(revealedDataPacked); + + // Extract forbidden countries list + for (uint256 i = 0; i < 4; i++) { + passportOutput.forbiddenCountriesListPacked[i] = vcAndDiscloseProof.pubSignals[ + indices.forbiddenCountriesListPackedIndex + i + ]; + } + + return abi.encode(passportOutput); } /** - * @notice Encodes ID card verification result to bytes. + * @notice Creates EU ID output struct. + * @dev Constructs an EuIdOutput struct from the proof data and encodes it. + * @param vcAndDiscloseProof The VC and Disclose proof containing EU ID card data. + * @param indices The circuit-specific indices for extracting proof values. + * @param attestationId The attestation identifier. + * @param userIdentifier The user identifier. + * @return The encoded EuIdOutput struct. */ - function _encodeIdCardResult( - IdCardVcAndDiscloseVerificationResult memory result + function _createEuIdOutput( + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + CircuitConstantsV2.DiscloseIndices memory indices, + bytes32 attestationId, + uint256 userIdentifier ) internal pure returns (bytes memory) { - return abi.encode(result); + SelfStructs.EuIdOutput memory euIdOutput; + euIdOutput.attestationId = uint256(attestationId); + euIdOutput.userIdentifier = userIdentifier; + euIdOutput.nullifier = vcAndDiscloseProof.pubSignals[indices.nullifierIndex]; + + // Extract revealed data + uint256[4] memory revealedDataPacked; + for (uint256 i = 0; i < 4; i++) { + revealedDataPacked[i] = vcAndDiscloseProof.pubSignals[indices.revealedDataPackedIndex + i]; + } + euIdOutput.revealedDataPacked = Formatter.fieldElementsToBytesIdCard(revealedDataPacked); + + // Extract forbidden countries list + for (uint256 i = 0; i < 4; i++) { + euIdOutput.forbiddenCountriesListPacked[i] = vcAndDiscloseProof.pubSignals[ + indices.forbiddenCountriesListPackedIndex + i + ]; + } + + return abi.encode(euIdOutput); + } + + /** + * @notice Decodes VC and Disclose proof from bytes data. + * @dev Simple wrapper around abi.decode for type safety and clarity. + * @param data The encoded proof data. + * @return The decoded VcAndDiscloseProof struct. + */ + function _decodeVcAndDiscloseProof( + bytes memory data + ) internal pure returns (IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory) { + return abi.decode(data, (IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof)); + } + + /** + * @notice Performs user identifier validation. + * @dev Validates that the user identifier in the proof matches the hash of the user context data. + * Uses SHA256 followed by RIPEMD160 hashing for consistency with circuit implementation. + * @param userContextData The user context data to hash and compare. + * @param vcAndDiscloseProof The VC and Disclose proof containing the user identifier. + * @param attestationId The attestation identifier (used for getting correct indices). + * @param indices The circuit-specific indices for extracting the user identifier from proof. + */ + function _performUserIdentifierCheck( + bytes calldata userContextData, + IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory vcAndDiscloseProof, + bytes32 attestationId, + CircuitConstantsV2.DiscloseIndices memory indices + ) internal pure { + // Get the user identifier index for this attestation type + uint256 proofUserIdentifier = vcAndDiscloseProof.pubSignals[indices.userIdentifierIndex]; + + bytes memory userContextDataWithoutConfigId = userContextData[32:]; + bytes32 sha256Hash = sha256(userContextDataWithoutConfigId); + bytes20 ripemdHash = ripemd160(abi.encodePacked(sha256Hash)); + uint256 hashedValue = uint256(uint160(ripemdHash)); + + if (hashedValue != proofUserIdentifier) { + revert InvalidUserIdentifierInProof(); + } } } diff --git a/contracts/contracts/abstract/SelfVerificationRoot.sol b/contracts/contracts/abstract/SelfVerificationRoot.sol index 3ed14b602..4e9254043 100644 --- a/contracts/contracts/abstract/SelfVerificationRoot.sol +++ b/contracts/contracts/abstract/SelfVerificationRoot.sol @@ -3,21 +3,23 @@ pragma solidity 0.8.28; import {IIdentityVerificationHubV2} from "../interfaces/IIdentityVerificationHubV2.sol"; import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; -import {CircuitConstants} from "../constants/CircuitConstants.sol"; +import {CircuitConstantsV2} from "../constants/CircuitConstantsV2.sol"; import {AttestationId} from "../constants/AttestationId.sol"; /** * @title SelfVerificationRoot * @notice Abstract base contract to be integrated with self's verification infrastructure * @dev Provides base functionality for verifying and disclosing identity credentials + * @author Self Team */ abstract contract SelfVerificationRoot is ISelfVerificationRoot { // ==================================================== // Constants // ==================================================== - uint256 constant E_PASSPORT_REVEALED_DATA_LENGTH = 3; - uint256 constant EU_ID_CARD_REVEALED_DATA_LENGTH = 4; + /// @notice Contract version identifier used in verification process + /// @dev This version is included in the hub data for protocol compatibility + uint8 constant CONTRACT_VERSION = 2; // ==================================================== // Storage Variables @@ -27,143 +29,53 @@ abstract contract SelfVerificationRoot is ISelfVerificationRoot { /// @dev Used to validate that submitted proofs match the expected scope uint256 internal _scope; - /// @notice The contract version for validation - /// @dev Used to validate the contract version in relayer data - uint8 internal _contractVersion; - - /// @notice The attestation ID that proofs must match - /// @dev Used to validate that submitted proofs is generated with allowed attestation IDs - mapping(bytes32 attestationId => bool attestationIdEnabled) internal _attestationIdToEnabled; - - /// @notice Configuration settings for the verification process - /// @dev Contains settings for age verification, country restrictions, and OFAC checks - ISelfVerificationRoot.VerificationConfig internal _verificationConfig; - /// @notice Reference to the identity verification hub V2 contract /// @dev Immutable reference used for bytes-based proof verification IIdentityVerificationHubV2 internal immutable _identityVerificationHubV2; - // ==================================================== - // Circuit Constants - // ==================================================== - - // Make CircuitConstants available to inheriting contracts - uint256 internal constant REVEALED_DATA_PACKED_INDEX = CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX; - uint256 internal constant FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX = - CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX; - uint256 internal constant NULLIFIER_INDEX = CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX; - uint256 internal constant ATTESTATION_ID_INDEX = CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX; - uint256 internal constant MERKLE_ROOT_INDEX = CircuitConstants.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX; - uint256 internal constant CURRENT_DATE_INDEX = CircuitConstants.VC_AND_DISCLOSE_CURRENT_DATE_INDEX; - uint256 internal constant PASSPORT_NO_SMT_ROOT_INDEX = CircuitConstants.VC_AND_DISCLOSE_PASSPORT_NO_SMT_ROOT_INDEX; - uint256 internal constant NAME_DOB_SMT_ROOT_INDEX = CircuitConstants.VC_AND_DISCLOSE_NAME_DOB_SMT_ROOT_INDEX; - uint256 internal constant NAME_YOB_SMT_ROOT_INDEX = CircuitConstants.VC_AND_DISCLOSE_NAME_YOB_SMT_ROOT_INDEX; - uint256 internal constant SCOPE_INDEX = CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX; - uint256 internal constant USER_IDENTIFIER_INDEX = CircuitConstants.VC_AND_DISCLOSE_USER_IDENTIFIER_INDEX; - - // ==================================================== - // Attestation ID - // ==================================================== - - bytes32 constant E_PASSPORT_ID = AttestationId.E_PASSPORT; - // ==================================================== // Errors // ==================================================== - /// @notice Error thrown when the proof's scope doesn't match the expected scope - /// @dev Triggered in verifySelfProof when scope validation fails - error InvalidScope(); - - /// @notice Error thrown when the proof's attestation ID doesn't match the expected ID - /// @dev Triggered in verifySelfProof when attestation ID validation fails - error InvalidAttestationId(); - - /// @notice Error thrown when the contract version doesn't match - /// @dev Triggered in verifySelfProof when contract version validation fails - error InvalidContractVersion(); - /// @notice Error thrown when the data format is invalid /// @dev Triggered when the provided bytes data doesn't have the expected format error InvalidDataFormat(); + /// @notice Error thrown when onVerificationSuccess is called by an unauthorized address + /// @dev Only the identity verification hub V2 contract can call onVerificationSuccess + error UnauthorizedCaller(); + // ==================================================== // Events // ==================================================== - /// @notice Emitted when the verification configuration is updated - event VerificationConfigUpdated(ISelfVerificationRoot.VerificationConfig indexed verificationConfig); - - /// @notice Emitted when the verification is successful - event VerificationSuccess( - uint256 indexed scope, - bytes32 indexed attestationId, - uint256 indexed nullifier, - uint256 userIdentifier, - uint256[] revealedDataPacked - ); - /// @notice Emitted when the scope is updated + /// @param newScope The new scope value that was set event ScopeUpdated(uint256 indexed newScope); - /// @notice Emitted when a new attestation ID is added - event AttestationIdAdded(bytes32 indexed attestationId); - - /// @notice Emitted when an attestation ID is removed - event AttestationIdRemoved(bytes32 indexed attestationId); - - /// @notice Emitted when the contract version is updated - event ContractVersionUpdated(uint8 indexed newContractVersion); - /** - * @notice Initializes the SelfVerificationRoot contract. - * @param identityVerificationHubV2Address The address of the Identity Verification Hub V2. - * @param scopeValue The expected proof scope for user registration. - * @param contractVersion The contract version for validation. - * @param attestationIds The expected attestation identifiers required in proofs. + * @notice Initializes the SelfVerificationRoot contract + * @dev Sets up the immutable reference to the hub contract and initial scope + * @param identityVerificationHubV2Address The address of the Identity Verification Hub V2 + * @param scopeValue The expected proof scope for user registration */ - constructor( - address identityVerificationHubV2Address, - uint256 scopeValue, - uint8 contractVersion, - bytes32[] memory attestationIds - ) { + constructor(address identityVerificationHubV2Address, uint256 scopeValue) { _identityVerificationHubV2 = IIdentityVerificationHubV2(identityVerificationHubV2Address); _scope = scopeValue; - _contractVersion = contractVersion; - - // Cache array length for gas optimization - uint256 length = attestationIds.length; - for (uint256 i; i < length; ) { - _attestationIdToEnabled[attestationIds[i]] = true; - unchecked { - ++i; - } - } - } - - /** - * @notice Updates the verification configuration - * @dev Used to set or update verification parameters after contract deployment - * @param newVerificationConfig The new verification configuration to apply - */ - function _setVerificationConfig(ISelfVerificationRoot.VerificationConfig memory newVerificationConfig) internal { - _verificationConfig = newVerificationConfig; - emit VerificationConfigUpdated(newVerificationConfig); } /** - * @notice Returns the current verification configuration - * @dev Used to retrieve the current verification settings - * @return Current verification configuration + * @notice Returns the current scope value + * @dev Public view function to access the current scope setting + * @return The scope value that proofs must match */ - function _getVerificationConfig() internal view returns (ISelfVerificationRoot.VerificationConfig memory) { - return _verificationConfig; + function scope() public view returns (uint256) { + return _scope; } /** * @notice Updates the scope value - * @dev Used to change the expected scope for proofs + * @dev Protected internal function to change the expected scope for proofs * @param newScope The new scope value to set */ function _setScope(uint256 newScope) internal { @@ -171,163 +83,108 @@ abstract contract SelfVerificationRoot is ISelfVerificationRoot { emit ScopeUpdated(newScope); } - /** - * @notice Updates the contract version - * @dev Used to change the expected contract version - * @param newContractVersion The new contract version to set - */ - function _setContractVersion(uint8 newContractVersion) internal { - _contractVersion = newContractVersion; - emit ContractVersionUpdated(newContractVersion); - } - - /** - * @notice Adds a new attestation ID to the allowed list - * @dev Used to add support for additional attestation types - * @param attestationId The attestation ID to add - */ - function _addAttestationId(bytes32 attestationId) internal { - _attestationIdToEnabled[attestationId] = true; - emit AttestationIdAdded(attestationId); - } - - /** - * @notice Removes an attestation ID from the allowed list - * @dev Used to revoke support for specific attestation types - * @param attestationId The attestation ID to remove - */ - function _removeAttestationId(bytes32 attestationId) internal { - _attestationIdToEnabled[attestationId] = false; - emit AttestationIdRemoved(attestationId); - } - /** * @notice Verifies a self-proof using the bytes-based interface * @dev Parses relayer data format and validates against contract settings before calling hub V2 - * @param relayerData Packed data from relayer in format: | 1 byte circuitVersion | 31 bytes buffer | 32 bytes attestationId | proof data | + * @param proofPayload Packed data from relayer in format: | 32 bytes attestationId | proof data | + * @param userContextData User-defined data in format: | 32 bytes destChainId | 32 bytes userIdentifier | data | + * @custom:data-format proofPayload = | 32 bytes attestationId | proofData | + * @custom:data-format userContextData = | 32 bytes destChainId | 32 bytes userIdentifier | data | + * @custom:data-format hubData = | 1 bytes contract version | 31 bytes buffer | 32 bytes scope | 32 bytes attestationId | proofData | */ - function verifySelfProof(bytes calldata relayerData) public { - // Minimum expected length: 1 + 31 + 32 = 64 bytes + proof data - if (relayerData.length < 64) { + function verifySelfProof(bytes calldata proofPayload, bytes calldata userContextData) public { + // Minimum expected length for proofData: 32 bytes attestationId + proof data + if (proofPayload.length < 32) { revert InvalidDataFormat(); } - // Parse the relayer data - uint8 circuitVersion = uint8(relayerData[0]); - // bytes31 buffer = bytes31(relayerData[1:32]); // Reserved for future use + // Minimum userDefinedData length: 32 (destChainId) + 32 (userIdentifier) + 0 (userDefinedData) = 64 bytes + if (userContextData.length < 64) { + revert InvalidDataFormat(); + } bytes32 attestationId; assembly { - // Load attestationId from offset 32 (after 1+31 bytes) - attestationId := calldataload(add(relayerData.offset, 32)) + // Load attestationId from the beginning of proofData (first 32 bytes) + attestationId := calldataload(proofPayload.offset) } - // Validate attestation ID against our stored allowed list - if (!_attestationIdToEnabled[attestationId]) { - revert InvalidAttestationId(); - } + bytes32 destinationChainId = bytes32(userContextData[0:32]); + bytes32 userIdentifier = bytes32(userContextData[32:64]); + bytes memory userDefinedData = userContextData[64:]; + + bytes32 configId = getConfigId(destinationChainId, userIdentifier, userDefinedData); - // Hub data should be | 1 byte circuitVersion | 1 byte contractVersion | 30 bytes buffer | 32 bytes attestationId | 32 bytes scope | proof data - bytes memory hubData = abi.encodePacked( - // 1 byte circuitVersion - circuitVersion, + // Hub data should be | 1 byte contractVersion | 31 bytes buffer | 32 bytes scope | 32 bytes attestationId | proof data + bytes memory baseVerificationInput = abi.encodePacked( // 1 byte contractVersion - _contractVersion, - // 30 bytes buffer (all zeros) - bytes30(0), - // 32 bytes attestationId - attestationId, + CONTRACT_VERSION, + // 31 bytes buffer (all zeros) + bytes31(0), // 32 bytes scope _scope, - // proof data (starts after 1+1+30+32+32 = 96 bytes) - relayerData[96:] + // 32 bytes attestationId + attestationId, + // proof data (starts after 32 bytes attestationId) + proofPayload[32:] ); // Call hub V2 verification - bytes memory result = _identityVerificationHubV2.verifyVcAndDisclose(hubData); - - // Decode the result to extract all verification data - // Note: Result format depends on attestation type (passport vs ID card) - uint256 userIdentifier; - uint256 nullifier; - uint256 scope; - uint256 identityCommitmentRoot; - uint256[] memory revealedDataPacked; - uint256[4] memory forbiddenCountriesListPacked; - - if (attestationId == AttestationId.E_PASSPORT) { - IIdentityVerificationHubV2.VcAndDiscloseVerificationResult memory passportResult = abi.decode( - result, - (IIdentityVerificationHubV2.VcAndDiscloseVerificationResult) - ); - - // Copy passport data using a for loop - revealedDataPacked = new uint256[](E_PASSPORT_REVEALED_DATA_LENGTH); - for (uint256 i = 0; i < E_PASSPORT_REVEALED_DATA_LENGTH; i++) { - revealedDataPacked[i] = passportResult.revealedDataPacked[i]; - } - - userIdentifier = passportResult.userIdentifier; - nullifier = passportResult.nullifier; - scope = passportResult.scope; - identityCommitmentRoot = passportResult.identityCommitmentRoot; - forbiddenCountriesListPacked = passportResult.forbiddenCountriesListPacked; - } else if (attestationId == AttestationId.EU_ID_CARD) { - IIdentityVerificationHubV2.IdCardVcAndDiscloseVerificationResult memory idCardResult = abi.decode( - result, - (IIdentityVerificationHubV2.IdCardVcAndDiscloseVerificationResult) - ); - - // Copy ID card data using a for loop - revealedDataPacked = new uint256[](EU_ID_CARD_REVEALED_DATA_LENGTH); - for (uint256 i = 0; i < EU_ID_CARD_REVEALED_DATA_LENGTH; i++) { - revealedDataPacked[i] = idCardResult.revealedDataPacked[i]; - } - - userIdentifier = idCardResult.userIdentifier; - nullifier = idCardResult.nullifier; - scope = idCardResult.scope; - identityCommitmentRoot = idCardResult.identityCommitmentRoot; - forbiddenCountriesListPacked = idCardResult.forbiddenCountriesListPacked; - } else { - revert InvalidAttestationId(); - } + _identityVerificationHubV2.verify(baseVerificationInput, bytes.concat(configId, userContextData)); + } - // Validate scope against our stored scope - if (scope != _scope) { - revert InvalidScope(); + /** + * @notice Callback function called upon successful verification by the hub contract + * @dev Only callable by the identity verification hub V2 contract for security + * @param output The verification output data containing disclosed identity information + * @param userData The user-defined data passed through the verification process + * @custom:security Only the authorized hub contract can call this function + * @custom:flow This function decodes the output and calls the customizable verification hook + */ + function onVerificationSuccess(bytes memory output, bytes memory userData) public { + // Only allow the identity verification hub V2 to call this function + if (msg.sender != address(_identityVerificationHubV2)) { + revert UnauthorizedCaller(); } - emit VerificationSuccess(scope, attestationId, nullifier, userIdentifier, revealedDataPacked); - onBasicVerificationSuccess( - attestationId, - scope, - userIdentifier, - nullifier, - identityCommitmentRoot, - revealedDataPacked, - forbiddenCountriesListPacked + ISelfVerificationRoot.GenericDiscloseOutputV2 memory genericDiscloseOutput = abi.decode( + output, + (ISelfVerificationRoot.GenericDiscloseOutputV2) ); + + // Call the customizable verification hook + customVerificationHook(genericDiscloseOutput, userData); } /** - * @notice Hook called after successful verification - * @dev Virtual function to be overridden by derived contracts for custom business logic - * @param attestationId The attestation identifier from the proof - * @param scope The scope of the verification - * @param userIdentifier The user identifier from the proof - * @param nullifier The nullifier from the proof - * @param identityCommitmentRoot The root of the identity commitment - * @param revealedDataPacked The packed revealed data from the proof (E_PASSPORT_REVEALED_DATA_LENGTH for passport, EU_ID_CARD_REVEALED_DATA_LENGTH for ID card) - * @param forbiddenCountriesListPacked The packed forbidden countries list + * @notice Generates a configId for the user + * @dev This function should be overridden by the implementing contract to provide custom configId logic + * @param destinationChainId The destination chain ID + * @param userIdentifier The user identifier + * @param userDefinedData The user defined data + * @return The configId */ - function onBasicVerificationSuccess( - bytes32 attestationId, - uint256 scope, - uint256 userIdentifier, - uint256 nullifier, - uint256 identityCommitmentRoot, - uint256[] memory revealedDataPacked, - uint256[4] memory forbiddenCountriesListPacked - ) internal virtual; + function getConfigId( + bytes32 destinationChainId, + bytes32 userIdentifier, + bytes memory userDefinedData + ) public view virtual returns (bytes32) { + // Default implementation reverts; must be overridden in derived contract + revert("SelfVerificationRoot: getConfigId must be overridden"); + } + + /** + * @notice Custom verification hook that can be overridden by implementing contracts + * @dev This function is called after successful verification and hub address validation + * @param output The verification output data from the hub containing disclosed identity information + * @param userData The user-defined data passed through the verification process + * @custom:override Override this function in derived contracts to add custom verification logic + * @custom:security This function is only called after proper authentication by the hub contract + */ + function customVerificationHook( + ISelfVerificationRoot.GenericDiscloseOutputV2 memory output, + bytes memory userData + ) internal virtual { + // Default implementation is empty - override in derived contracts to add custom logic + } } diff --git a/contracts/contracts/constants/CircuitConstantsV2.sol b/contracts/contracts/constants/CircuitConstantsV2.sol index 62549a2dd..98734ad09 100644 --- a/contracts/contracts/constants/CircuitConstantsV2.sol +++ b/contracts/contracts/constants/CircuitConstantsV2.sol @@ -61,7 +61,7 @@ library CircuitConstantsV2 { uint256 nameyobSmtRootIndex; uint256 scopeIndex; uint256 userIdentifierIndex; - uint256 passportNoSmtRootIndex; // Only for passport, 0 for ID card + uint256 passportNoSmtRootIndex; // Only for passport, 99 for ID card } /** @@ -98,7 +98,7 @@ library CircuitConstantsV2 { nameyobSmtRootIndex: 18, scopeIndex: 19, userIdentifierIndex: 20, - passportNoSmtRootIndex: 0 // Not applicable for ID cards + passportNoSmtRootIndex: 99 }); } else { revert("Invalid attestation ID"); diff --git a/contracts/contracts/example/Airdrop.sol b/contracts/contracts/example/Airdrop.sol index 9f016878a..2b28f0e46 100644 --- a/contracts/contracts/example/Airdrop.sol +++ b/contracts/contracts/example/Airdrop.sol @@ -1,329 +1,329 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; - -import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; - -import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; - -/** - * @title Airdrop (Experimental) - * @notice This contract manages an airdrop campaign by verifying user registrations with zero‐knowledge proofs - * and distributing ERC20 tokens. It is provided for testing and demonstration purposes only. - * **WARNING:** This contract has not been audited and is NOT intended for production use. - * @dev Inherits from SelfVerificationRoot for registration logic and Ownable for administrative control. - */ -contract Airdrop is SelfVerificationRoot, Ownable { - using SafeERC20 for IERC20; - - // ==================================================== - // Storage Variables - // ==================================================== - - /// @notice ERC20 token to be airdropped. - IERC20 public immutable token; - /// @notice Merkle root used to validate airdrop claims. - bytes32 public merkleRoot; - /// @notice Tracks addresses that have claimed tokens. - mapping(address => bool) public claimed; - /// @notice Indicates whether the registration phase is active. - bool public isRegistrationOpen; - /// @notice Indicates whether the claim phase is active. - bool public isClaimOpen; - - /// @notice Maps nullifiers to user identifiers for registration tracking - mapping(uint256 nullifier => uint256 userIdentifier) internal _nullifierToUserIdentifier; - - /// @notice Maps user identifiers to registration status - mapping(uint256 userIdentifier => bool registered) internal _registeredUserIdentifiers; - - // ==================================================== - // Errors - // ==================================================== - - /// @notice Reverts when an invalid Merkle proof is provided. - error InvalidProof(); - /// @notice Reverts when a user attempts to claim tokens more than once. - error AlreadyClaimed(); - /// @notice Reverts when an unregistered address attempts to claim tokens. - error NotRegistered(address nonRegisteredAddress); - /// @notice Reverts when registration is attempted while the registration phase is closed. - error RegistrationNotOpen(); - /// @notice Reverts when a claim attempt is made while registration is still open. - error RegistrationNotClosed(); - /// @notice Reverts when a claim is attempted while claiming is not enabled. - error ClaimNotOpen(); - /// @notice Reverts when an invalid user identifier is provided. - error InvalidUserIdentifier(); - /// @notice Reverts when a user identifier has already been registered - error UserIdentifierAlreadyRegistered(); - /// @notice Reverts when a nullifier has already been registered - error RegisteredNullifier(); - - // ==================================================== - // Events - // ==================================================== - - /// @notice Emitted when a user successfully claims tokens. - /// @param index The index of the claim in the Merkle tree. - /// @param account The address that claimed tokens. - /// @param amount The amount of tokens claimed. - event Claimed(uint256 index, address account, uint256 amount); - /// @notice Emitted when the registration phase is opened. - event RegistrationOpen(); - /// @notice Emitted when the registration phase is closed. - event RegistrationClose(); - /// @notice Emitted when the claim phase is opened. - event ClaimOpen(); - /// @notice Emitted when the claim phase is closed. - event ClaimClose(); - - /// @notice Emitted when a user identifier is registered. - event UserIdentifierRegistered(uint256 indexed registeredUserIdentifier, uint256 indexed nullifier); - - /// @notice Emitted when the Merkle root is updated. - event MerkleRootUpdated(bytes32 newMerkleRoot); - - // ==================================================== - // Constructor - // ==================================================== - - /** - * @notice Constructor for the experimental Airdrop contract. - * @dev Initializes the airdrop parameters, zero-knowledge verification configuration, - * and sets the ERC20 token to be distributed. - * @param identityVerificationHubAddress The address of the Identity Verification Hub. - * @param scopeValue The expected proof scope for user registration. - * @param contractVersion The contract version for validation. - * @param attestationIds The expected attestation identifiers required in proofs. - * @param tokenAddress The address of the ERC20 token for airdrop. - */ - constructor( - address identityVerificationHubAddress, - uint256 scopeValue, - uint8 contractVersion, - bytes32[] memory attestationIds, - address tokenAddress - ) - SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIds) - Ownable(_msgSender()) - { - token = IERC20(tokenAddress); - } - - // ==================================================== - // External/Public Functions - // ==================================================== - - /** - * @notice Sets the Merkle root for claim validation. - * @dev Only callable by the contract owner. - * @param newMerkleRoot The new Merkle root. - */ - function setMerkleRoot(bytes32 newMerkleRoot) external onlyOwner { - merkleRoot = newMerkleRoot; - emit MerkleRootUpdated(newMerkleRoot); - } - - /** - * @notice Updates the verification configuration for address registration. - * @dev Only callable by the contract owner. - * @param newVerificationConfig The new verification configuration. - */ - function setVerificationConfig( - ISelfVerificationRoot.VerificationConfig memory newVerificationConfig - ) external onlyOwner { - _setVerificationConfig(newVerificationConfig); - } - - /** - * @notice Updates the scope used for verification. - * @dev Only callable by the contract owner. - * @param newScope The new scope to set. - */ - function setScope(uint256 newScope) external onlyOwner { - _setScope(newScope); - } - - /** - * @notice Adds a new attestation ID to the allowed list. - * @dev Only callable by the contract owner. - * @param attestationId The attestation ID to add. - */ - function addAttestationId(bytes32 attestationId) external onlyOwner { - _addAttestationId(attestationId); - } - - /** - * @notice Removes an attestation ID from the allowed list. - * @dev Only callable by the contract owner. - * @param attestationId The attestation ID to remove. - */ - function removeAttestationId(bytes32 attestationId) external onlyOwner { - _removeAttestationId(attestationId); - } - - /** - * @notice Opens the registration phase for users. - * @dev Only callable by the contract owner. - */ - function openRegistration() external onlyOwner { - isRegistrationOpen = true; - emit RegistrationOpen(); - } - - /** - * @notice Closes the registration phase. - * @dev Only callable by the contract owner. - */ - function closeRegistration() external onlyOwner { - isRegistrationOpen = false; - emit RegistrationClose(); - } - - /** - * @notice Opens the claim phase, allowing registered users to claim tokens. - * @dev Only callable by the contract owner. - */ - function openClaim() external onlyOwner { - isClaimOpen = true; - emit ClaimOpen(); - } - - /** - * @notice Closes the claim phase. - * @dev Only callable by the contract owner. - */ - function closeClaim() external onlyOwner { - isClaimOpen = false; - emit ClaimClose(); - } - - /** - * @notice Retrieves the expected proof scope. - * @return The scope value used for registration verification. - */ - function getScope() external view returns (uint256) { - return _scope; - } - - /** - * @notice Checks if the specified attestation ID is allowed. - * @param attestationId The attestation ID to check. - * @return True if the attestation ID is allowed, false otherwise. - */ - function isAttestationIdAllowed(bytes32 attestationId) external view returns (bool) { - return _attestationIdToEnabled[attestationId]; - } - - /** - * @notice Retrieves the current verification configuration. - * @return The verification configuration used for registration. - */ - function getVerificationConfig() external view returns (ISelfVerificationRoot.VerificationConfig memory) { - return _getVerificationConfig(); - } - - /** - * @notice Checks if a given address is registered. - * @param registeredAddress The address to check. - * @return True if the address is registered, false otherwise. - */ - function isRegistered(address registeredAddress) external view returns (bool) { - return _registeredUserIdentifiers[uint256(uint160(registeredAddress))]; - } - - /** - * @notice Allows a registered user to claim their tokens. - * @dev Reverts if registration is still open, if claiming is disabled, if already claimed, - * or if the sender is not registered. Also validates the claim using a Merkle proof. - * @param index The index of the claim in the Merkle tree. - * @param amount The amount of tokens to be claimed. - * @param merkleProof The Merkle proof verifying the claim. - */ - function claim(uint256 index, uint256 amount, bytes32[] memory merkleProof) external { - if (isRegistrationOpen) { - revert RegistrationNotClosed(); - } - if (!isClaimOpen) { - revert ClaimNotOpen(); - } - if (claimed[msg.sender]) { - revert AlreadyClaimed(); - } - if (!_registeredUserIdentifiers[uint256(uint160(msg.sender))]) { - revert NotRegistered(msg.sender); - } - - // Verify the Merkle proof. - bytes32 node = keccak256(abi.encodePacked(index, msg.sender, amount)); - if (!MerkleProof.verify(merkleProof, merkleRoot, node)) revert InvalidProof(); - - // Mark as claimed and transfer tokens. - _setClaimed(); - token.safeTransfer(msg.sender, amount); - - emit Claimed(index, msg.sender, amount); - } - - // ==================================================== - // Override Functions from SelfVerificationRoot - // ==================================================== - - /** - * @notice Hook called after successful verification - handles user registration - * @dev Validates registration conditions and registers the user - * @param userIdentifier The user identifier from the proof - * @param nullifier The nullifier from the proof - */ - function onBasicVerificationSuccess( - bytes32 /* attestationId */, - uint256 /* scope */, - uint256 userIdentifier, - uint256 nullifier, - uint256 /* identityCommitmentRoot */, - uint256[] memory /* revealedDataPacked */, - uint256[4] memory /* forbiddenCountriesListPacked */ - ) internal override { - // Check if registration is open - if (!isRegistrationOpen) { - revert RegistrationNotOpen(); - } - - // Check if nullifier has already been registered - if (_nullifierToUserIdentifier[nullifier] != 0) { - revert RegisteredNullifier(); - } - - // Check if user identifier is valid - if (userIdentifier == 0) { - revert InvalidUserIdentifier(); - } - - // Check if user identifier has already been registered - if (_registeredUserIdentifiers[userIdentifier]) { - revert UserIdentifierAlreadyRegistered(); - } - - _nullifierToUserIdentifier[nullifier] = userIdentifier; - _registeredUserIdentifiers[userIdentifier] = true; - - // Emit registration event - emit UserIdentifierRegistered(userIdentifier, nullifier); - } - - // ==================================================== - // Internal Functions - // ==================================================== - - /** - * @notice Internal function to mark the caller as having claimed their tokens. - * @dev Updates the claimed mapping. - */ - function _setClaimed() internal { - claimed[msg.sender] = true; - } -} + // // SPDX-License-Identifier: MIT +// pragma solidity 0.8.28; + +// import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +// import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; +// import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +// import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; + +// import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; + +// /** +// * @title Airdrop (Experimental) +// * @notice This contract manages an airdrop campaign by verifying user registrations with zero‐knowledge proofs +// * and distributing ERC20 tokens. It is provided for testing and demonstration purposes only. +// * **WARNING:** This contract has not been audited and is NOT intended for production use. +// * @dev Inherits from SelfVerificationRoot for registration logic and Ownable for administrative control. +// */ +// contract Airdrop is SelfVerificationRoot, Ownable { +// using SafeERC20 for IERC20; + +// // ==================================================== +// // Storage Variables +// // ==================================================== + +// /// @notice ERC20 token to be airdropped. +// IERC20 public immutable token; +// /// @notice Merkle root used to validate airdrop claims. +// bytes32 public merkleRoot; +// /// @notice Tracks addresses that have claimed tokens. +// mapping(address => bool) public claimed; +// /// @notice Indicates whether the registration phase is active. +// bool public isRegistrationOpen; +// /// @notice Indicates whether the claim phase is active. +// bool public isClaimOpen; + +// /// @notice Maps nullifiers to user identifiers for registration tracking +// mapping(uint256 nullifier => uint256 userIdentifier) internal _nullifierToUserIdentifier; + +// /// @notice Maps user identifiers to registration status +// mapping(uint256 userIdentifier => bool registered) internal _registeredUserIdentifiers; + +// // ==================================================== +// // Errors +// // ==================================================== + +// /// @notice Reverts when an invalid Merkle proof is provided. +// error InvalidProof(); +// /// @notice Reverts when a user attempts to claim tokens more than once. +// error AlreadyClaimed(); +// /// @notice Reverts when an unregistered address attempts to claim tokens. +// error NotRegistered(address nonRegisteredAddress); +// /// @notice Reverts when registration is attempted while the registration phase is closed. +// error RegistrationNotOpen(); +// /// @notice Reverts when a claim attempt is made while registration is still open. +// error RegistrationNotClosed(); +// /// @notice Reverts when a claim is attempted while claiming is not enabled. +// error ClaimNotOpen(); +// /// @notice Reverts when an invalid user identifier is provided. +// error InvalidUserIdentifier(); +// /// @notice Reverts when a user identifier has already been registered +// error UserIdentifierAlreadyRegistered(); +// /// @notice Reverts when a nullifier has already been registered +// error RegisteredNullifier(); + +// // ==================================================== +// // Events +// // ==================================================== + +// /// @notice Emitted when a user successfully claims tokens. +// /// @param index The index of the claim in the Merkle tree. +// /// @param account The address that claimed tokens. +// /// @param amount The amount of tokens claimed. +// event Claimed(uint256 index, address account, uint256 amount); +// /// @notice Emitted when the registration phase is opened. +// event RegistrationOpen(); +// /// @notice Emitted when the registration phase is closed. +// event RegistrationClose(); +// /// @notice Emitted when the claim phase is opened. +// event ClaimOpen(); +// /// @notice Emitted when the claim phase is closed. +// event ClaimClose(); + +// /// @notice Emitted when a user identifier is registered. +// event UserIdentifierRegistered(uint256 indexed registeredUserIdentifier, uint256 indexed nullifier); + +// /// @notice Emitted when the Merkle root is updated. +// event MerkleRootUpdated(bytes32 newMerkleRoot); + +// // ==================================================== +// // Constructor +// // ==================================================== + +// /** +// * @notice Constructor for the experimental Airdrop contract. +// * @dev Initializes the airdrop parameters, zero-knowledge verification configuration, +// * and sets the ERC20 token to be distributed. +// * @param identityVerificationHubAddress The address of the Identity Verification Hub. +// * @param scopeValue The expected proof scope for user registration. +// * @param contractVersion The contract version for validation. +// * @param attestationIds The expected attestation identifiers required in proofs. +// * @param tokenAddress The address of the ERC20 token for airdrop. +// */ +// constructor( +// address identityVerificationHubAddress, +// uint256 scopeValue, +// uint8 contractVersion, +// bytes32[] memory attestationIds, +// address tokenAddress +// ) +// SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIds) +// Ownable(_msgSender()) +// { +// token = IERC20(tokenAddress); +// } + +// // ==================================================== +// // External/Public Functions +// // ==================================================== + +// /** +// * @notice Sets the Merkle root for claim validation. +// * @dev Only callable by the contract owner. +// * @param newMerkleRoot The new Merkle root. +// */ +// function setMerkleRoot(bytes32 newMerkleRoot) external onlyOwner { +// merkleRoot = newMerkleRoot; +// emit MerkleRootUpdated(newMerkleRoot); +// } + +// /** +// * @notice Updates the verification configuration for address registration. +// * @dev Only callable by the contract owner. +// * @param newVerificationConfig The new verification configuration. +// */ +// function setVerificationConfig( +// ISelfVerificationRoot.VerificationConfig memory newVerificationConfig +// ) external onlyOwner { +// _setVerificationConfig(newVerificationConfig); +// } + +// /** +// * @notice Updates the scope used for verification. +// * @dev Only callable by the contract owner. +// * @param newScope The new scope to set. +// */ +// function setScope(uint256 newScope) external onlyOwner { +// _setScope(newScope); +// } + +// /** +// * @notice Adds a new attestation ID to the allowed list. +// * @dev Only callable by the contract owner. +// * @param attestationId The attestation ID to add. +// */ +// function addAttestationId(bytes32 attestationId) external onlyOwner { +// _addAttestationId(attestationId); +// } + +// /** +// * @notice Removes an attestation ID from the allowed list. +// * @dev Only callable by the contract owner. +// * @param attestationId The attestation ID to remove. +// */ +// function removeAttestationId(bytes32 attestationId) external onlyOwner { +// _removeAttestationId(attestationId); +// } + +// /** +// * @notice Opens the registration phase for users. +// * @dev Only callable by the contract owner. +// */ +// function openRegistration() external onlyOwner { +// isRegistrationOpen = true; +// emit RegistrationOpen(); +// } + +// /** +// * @notice Closes the registration phase. +// * @dev Only callable by the contract owner. +// */ +// function closeRegistration() external onlyOwner { +// isRegistrationOpen = false; +// emit RegistrationClose(); +// } + +// /** +// * @notice Opens the claim phase, allowing registered users to claim tokens. +// * @dev Only callable by the contract owner. +// */ +// function openClaim() external onlyOwner { +// isClaimOpen = true; +// emit ClaimOpen(); +// } + +// /** +// * @notice Closes the claim phase. +// * @dev Only callable by the contract owner. +// */ +// function closeClaim() external onlyOwner { +// isClaimOpen = false; +// emit ClaimClose(); +// } + +// /** +// * @notice Retrieves the expected proof scope. +// * @return The scope value used for registration verification. +// */ +// function getScope() external view returns (uint256) { +// return _scope; +// } + +// /** +// * @notice Checks if the specified attestation ID is allowed. +// * @param attestationId The attestation ID to check. +// * @return True if the attestation ID is allowed, false otherwise. +// */ +// function isAttestationIdAllowed(bytes32 attestationId) external view returns (bool) { +// return _attestationIdToEnabled[attestationId]; +// } + +// /** +// * @notice Retrieves the current verification configuration. +// * @return The verification configuration used for registration. +// */ +// function getVerificationConfig() external view returns (ISelfVerificationRoot.VerificationConfig memory) { +// return _getVerificationConfig(); +// } + +// /** +// * @notice Checks if a given address is registered. +// * @param registeredAddress The address to check. +// * @return True if the address is registered, false otherwise. +// */ +// function isRegistered(address registeredAddress) external view returns (bool) { +// return _registeredUserIdentifiers[uint256(uint160(registeredAddress))]; +// } + +// /** +// * @notice Allows a registered user to claim their tokens. +// * @dev Reverts if registration is still open, if claiming is disabled, if already claimed, +// * or if the sender is not registered. Also validates the claim using a Merkle proof. +// * @param index The index of the claim in the Merkle tree. +// * @param amount The amount of tokens to be claimed. +// * @param merkleProof The Merkle proof verifying the claim. +// */ +// function claim(uint256 index, uint256 amount, bytes32[] memory merkleProof) external { +// if (isRegistrationOpen) { +// revert RegistrationNotClosed(); +// } +// if (!isClaimOpen) { +// revert ClaimNotOpen(); +// } +// if (claimed[msg.sender]) { +// revert AlreadyClaimed(); +// } +// if (!_registeredUserIdentifiers[uint256(uint160(msg.sender))]) { +// revert NotRegistered(msg.sender); +// } + +// // Verify the Merkle proof. +// bytes32 node = keccak256(abi.encodePacked(index, msg.sender, amount)); +// if (!MerkleProof.verify(merkleProof, merkleRoot, node)) revert InvalidProof(); + +// // Mark as claimed and transfer tokens. +// _setClaimed(); +// token.safeTransfer(msg.sender, amount); + +// emit Claimed(index, msg.sender, amount); +// } + +// // ==================================================== +// // Override Functions from SelfVerificationRoot +// // ==================================================== + +// /** +// * @notice Hook called after successful verification - handles user registration +// * @dev Validates registration conditions and registers the user +// * @param userIdentifier The user identifier from the proof +// * @param nullifier The nullifier from the proof +// */ +// function onBasicVerificationSuccess( +// bytes32 /* attestationId */, +// uint256 /* scope */, +// uint256 userIdentifier, +// uint256 nullifier, +// uint256 /* identityCommitmentRoot */, +// uint256[] memory /* revealedDataPacked */, +// uint256[4] memory /* forbiddenCountriesListPacked */ +// ) internal override { +// // Check if registration is open +// if (!isRegistrationOpen) { +// revert RegistrationNotOpen(); +// } + +// // Check if nullifier has already been registered +// if (_nullifierToUserIdentifier[nullifier] != 0) { +// revert RegisteredNullifier(); +// } + +// // Check if user identifier is valid +// if (userIdentifier == 0) { +// revert InvalidUserIdentifier(); +// } + +// // Check if user identifier has already been registered +// if (_registeredUserIdentifiers[userIdentifier]) { +// revert UserIdentifierAlreadyRegistered(); +// } + +// _nullifierToUserIdentifier[nullifier] = userIdentifier; +// _registeredUserIdentifiers[userIdentifier] = true; + +// // Emit registration event +// emit UserIdentifierRegistered(userIdentifier, nullifier); +// } + +// // ==================================================== +// // Internal Functions +// // ==================================================== + +// /** +// * @notice Internal function to mark the caller as having claimed their tokens. +// * @dev Updates the claimed mapping. +// */ +// function _setClaimed() internal { +// claimed[msg.sender] = true; +// } +// } diff --git a/contracts/contracts/example/HappyBirthday.sol b/contracts/contracts/example/HappyBirthday.sol index 14e6b23f3..9315d60db 100644 --- a/contracts/contracts/example/HappyBirthday.sol +++ b/contracts/contracts/example/HappyBirthday.sol @@ -1,201 +1,201 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; - -import {SelfCircuitLibrary} from "../libraries/SelfCircuitLibrary.sol"; -import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; - -/** - * @title SelfHappyBirthday - * @notice A contract that gives out USDC to users on their birthday - * @dev Uses SelfVerificationRoot to handle verification with nullifier management for birthday claims - */ -contract SelfHappyBirthday is SelfVerificationRoot, Ownable { - using SafeERC20 for IERC20; - - // ==================================================== - // Storage Variables - // ==================================================== - - /// @notice USDC token contract - IERC20 public immutable usdc; - - /// @notice Default: 1 dollar (6 decimals for USDC) - uint256 public claimableAmount = 1e6; - - /// @notice Default: 1 day window around birthday - uint256 public claimableWindow = 1 days; - - /// @notice Tracks users who have claimed to prevent double claims - mapping(uint256 nullifier => bool hasClaimed) public hasClaimed; - - // ==================================================== - // Events - // ==================================================== - - event USDCClaimed(address indexed claimer, uint256 amount); - event ClaimableAmountUpdated(uint256 oldAmount, uint256 newAmount); - event ClaimableWindowUpdated(uint256 oldWindow, uint256 newWindow); - - // ==================================================== - // Errors - // ==================================================== - - error NotWithinBirthdayWindow(); - error AlreadyClaimed(); - - /** - * @notice Initializes the HappyBirthday contract - * @param identityVerificationHubAddress The address of the Identity Verification Hub - * @param scopeValue The expected proof scope for user registration - * @param contractVersion The contract version for validation - * @param attestationIds Array of allowed attestation identifiers - * @param token The USDC token address - */ - constructor( - address identityVerificationHubAddress, - uint256 scopeValue, - uint8 contractVersion, - bytes32[] memory attestationIds, - address token - ) - SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIds) - Ownable(_msgSender()) - { - usdc = IERC20(token); - } - - // ==================================================== - // External/Public Functions - // ==================================================== - - /** - * @notice Sets the verification configuration - * @param newVerificationConfig The new verification settings - */ - function setVerificationConfig( - ISelfVerificationRoot.VerificationConfig memory newVerificationConfig - ) external onlyOwner { - _setVerificationConfig(newVerificationConfig); - } - - /** - * @notice Sets the claimable USDC amount - * @param newAmount The new claimable amount - */ - function setClaimableAmount(uint256 newAmount) external onlyOwner { - uint256 oldAmount = claimableAmount; - claimableAmount = newAmount; - emit ClaimableAmountUpdated(oldAmount, newAmount); - } - - /** - * @notice Sets the claimable window around birthdays - * @param newWindow The new claimable window in seconds - */ - function setClaimableWindow(uint256 newWindow) external onlyOwner { - uint256 oldWindow = claimableWindow; - claimableWindow = newWindow; - emit ClaimableWindowUpdated(oldWindow, newWindow); - } - - /** - * @notice Allows the owner to withdraw USDC from the contract - * @param to The address to withdraw to - * @param amount The amount to withdraw - */ - function withdrawUSDC(address to, uint256 amount) external onlyOwner { - usdc.safeTransfer(to, amount); - } - - // ==================================================== - // Override Functions from SelfVerificationRoot - // ==================================================== - - /** - * @notice Hook called after successful verification - * @dev Checks user hasn't claimed, validates birthday window, and transfers USDC if eligible - * @param userIdentifier The user identifier from the proof - * @param nullifier The nullifier from the proof - * @param revealedDataPacked The packed revealed data from the proof - */ - function onBasicVerificationSuccess( - bytes32 /* attestationId */, - uint256 /* scope */, - uint256 userIdentifier, - uint256 nullifier, - uint256 /* identityCommitmentRoot */, - uint256[] memory revealedDataPacked, - uint256[4] memory /* forbiddenCountriesListPacked */ - ) internal override { - // Check if user has already claimed - if (hasClaimed[nullifier]) { - revert AlreadyClaimed(); - } - - // Check if within birthday window - only use first 3 elements for passport data - uint256[3] memory passportData; - for (uint256 i = 0; i < 3 && i < revealedDataPacked.length; i++) { - passportData[i] = revealedDataPacked[i]; - } - - if (_isWithinBirthdayWindow(passportData)) { - // Mark user as claimed - hasClaimed[nullifier] = true; - - address recipient = address(uint160(userIdentifier)); - - // Transfer USDC to the user - usdc.safeTransfer(recipient, claimableAmount); - - // Emit success event - emit USDCClaimed(recipient, claimableAmount); - } else { - revert NotWithinBirthdayWindow(); - } - } - - // ==================================================== - // Internal Functions - // ==================================================== - - /** - * @notice Checks if the current date is within the user's birthday window - * @param revealedDataPacked The packed revealed data containing DOB information - * @return isWithinWindow True if within the birthday window - */ - function _isWithinBirthdayWindow(uint256[3] memory revealedDataPacked) internal view returns (bool) { - string memory dob = SelfCircuitLibrary.getDateOfBirth(revealedDataPacked); - - bytes memory dobBytes = bytes(dob); - bytes memory dayBytes = new bytes(2); - bytes memory monthBytes = new bytes(2); - - dayBytes[0] = dobBytes[0]; - dayBytes[1] = dobBytes[1]; - - monthBytes[0] = dobBytes[3]; - monthBytes[1] = dobBytes[4]; - - string memory day = string(dayBytes); - string memory month = string(monthBytes); - string memory dobInThisYear = string(abi.encodePacked("25", month, day)); - - uint256 dobInThisYearTimestamp = SelfCircuitLibrary.dateToTimestamp(dobInThisYear); - - uint256 currentTime = block.timestamp; - uint256 timeDifference; - - if (currentTime > dobInThisYearTimestamp) { - timeDifference = currentTime - dobInThisYearTimestamp; - } else { - timeDifference = dobInThisYearTimestamp - currentTime; - } - - return timeDifference <= claimableWindow; - } -} + // // SPDX-License-Identifier: MIT +// pragma solidity 0.8.28; + +// import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +// import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +// import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; + +// import {SelfCircuitLibrary} from "../libraries/SelfCircuitLibrary.sol"; +// import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; + +// /** +// * @title SelfHappyBirthday +// * @notice A contract that gives out USDC to users on their birthday +// * @dev Uses SelfVerificationRoot to handle verification with nullifier management for birthday claims +// */ +// contract SelfHappyBirthday is SelfVerificationRoot, Ownable { +// using SafeERC20 for IERC20; + +// // ==================================================== +// // Storage Variables +// // ==================================================== + +// /// @notice USDC token contract +// IERC20 public immutable usdc; + +// /// @notice Default: 1 dollar (6 decimals for USDC) +// uint256 public claimableAmount = 1e6; + +// /// @notice Default: 1 day window around birthday +// uint256 public claimableWindow = 1 days; + +// /// @notice Tracks users who have claimed to prevent double claims +// mapping(uint256 nullifier => bool hasClaimed) public hasClaimed; + +// // ==================================================== +// // Events +// // ==================================================== + +// event USDCClaimed(address indexed claimer, uint256 amount); +// event ClaimableAmountUpdated(uint256 oldAmount, uint256 newAmount); +// event ClaimableWindowUpdated(uint256 oldWindow, uint256 newWindow); + +// // ==================================================== +// // Errors +// // ==================================================== + +// error NotWithinBirthdayWindow(); +// error AlreadyClaimed(); + +// /** +// * @notice Initializes the HappyBirthday contract +// * @param identityVerificationHubAddress The address of the Identity Verification Hub +// * @param scopeValue The expected proof scope for user registration +// * @param contractVersion The contract version for validation +// * @param attestationIds Array of allowed attestation identifiers +// * @param token The USDC token address +// */ +// constructor( +// address identityVerificationHubAddress, +// uint256 scopeValue, +// uint8 contractVersion, +// bytes32[] memory attestationIds, +// address token +// ) +// SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIds) +// Ownable(_msgSender()) +// { +// usdc = IERC20(token); +// } + +// // ==================================================== +// // External/Public Functions +// // ==================================================== + +// /** +// * @notice Sets the verification configuration +// * @param newVerificationConfig The new verification settings +// */ +// function setVerificationConfig( +// ISelfVerificationRoot.VerificationConfig memory newVerificationConfig +// ) external onlyOwner { +// _setVerificationConfig(newVerificationConfig); +// } + +// /** +// * @notice Sets the claimable USDC amount +// * @param newAmount The new claimable amount +// */ +// function setClaimableAmount(uint256 newAmount) external onlyOwner { +// uint256 oldAmount = claimableAmount; +// claimableAmount = newAmount; +// emit ClaimableAmountUpdated(oldAmount, newAmount); +// } + +// /** +// * @notice Sets the claimable window around birthdays +// * @param newWindow The new claimable window in seconds +// */ +// function setClaimableWindow(uint256 newWindow) external onlyOwner { +// uint256 oldWindow = claimableWindow; +// claimableWindow = newWindow; +// emit ClaimableWindowUpdated(oldWindow, newWindow); +// } + +// /** +// * @notice Allows the owner to withdraw USDC from the contract +// * @param to The address to withdraw to +// * @param amount The amount to withdraw +// */ +// function withdrawUSDC(address to, uint256 amount) external onlyOwner { +// usdc.safeTransfer(to, amount); +// } + +// // ==================================================== +// // Override Functions from SelfVerificationRoot +// // ==================================================== + +// /** +// * @notice Hook called after successful verification +// * @dev Checks user hasn't claimed, validates birthday window, and transfers USDC if eligible +// * @param userIdentifier The user identifier from the proof +// * @param nullifier The nullifier from the proof +// * @param revealedDataPacked The packed revealed data from the proof +// */ +// function onBasicVerificationSuccess( +// bytes32 /* attestationId */, +// uint256 /* scope */, +// uint256 userIdentifier, +// uint256 nullifier, +// uint256 /* identityCommitmentRoot */, +// uint256[] memory revealedDataPacked, +// uint256[4] memory /* forbiddenCountriesListPacked */ +// ) internal override { +// // Check if user has already claimed +// if (hasClaimed[nullifier]) { +// revert AlreadyClaimed(); +// } + +// // Check if within birthday window - only use first 3 elements for passport data +// uint256[3] memory passportData; +// for (uint256 i = 0; i < 3 && i < revealedDataPacked.length; i++) { +// passportData[i] = revealedDataPacked[i]; +// } + +// if (_isWithinBirthdayWindow(passportData)) { +// // Mark user as claimed +// hasClaimed[nullifier] = true; + +// address recipient = address(uint160(userIdentifier)); + +// // Transfer USDC to the user +// usdc.safeTransfer(recipient, claimableAmount); + +// // Emit success event +// emit USDCClaimed(recipient, claimableAmount); +// } else { +// revert NotWithinBirthdayWindow(); +// } +// } + +// // ==================================================== +// // Internal Functions +// // ==================================================== + +// /** +// * @notice Checks if the current date is within the user's birthday window +// * @param revealedDataPacked The packed revealed data containing DOB information +// * @return isWithinWindow True if within the birthday window +// */ +// function _isWithinBirthdayWindow(uint256[3] memory revealedDataPacked) internal view returns (bool) { +// string memory dob = SelfCircuitLibrary.getDateOfBirth(revealedDataPacked); + +// bytes memory dobBytes = bytes(dob); +// bytes memory dayBytes = new bytes(2); +// bytes memory monthBytes = new bytes(2); + +// dayBytes[0] = dobBytes[0]; +// dayBytes[1] = dobBytes[1]; + +// monthBytes[0] = dobBytes[3]; +// monthBytes[1] = dobBytes[4]; + +// string memory day = string(dayBytes); +// string memory month = string(monthBytes); +// string memory dobInThisYear = string(abi.encodePacked("25", month, day)); + +// uint256 dobInThisYearTimestamp = SelfCircuitLibrary.dateToTimestamp(dobInThisYear); + +// uint256 currentTime = block.timestamp; +// uint256 timeDifference; + +// if (currentTime > dobInThisYearTimestamp) { +// timeDifference = currentTime - dobInThisYearTimestamp; +// } else { +// timeDifference = dobInThisYearTimestamp - currentTime; +// } + +// return timeDifference <= claimableWindow; +// } +// } diff --git a/contracts/contracts/example/SelfPassportERC721.sol b/contracts/contracts/example/SelfPassportERC721.sol index 6348106cc..7df8611d1 100644 --- a/contracts/contracts/example/SelfPassportERC721.sol +++ b/contracts/contracts/example/SelfPassportERC721.sol @@ -1,219 +1,219 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; - -import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; - -import {SelfCircuitLibrary} from "../libraries/SelfCircuitLibrary.sol"; -import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; - -/** - * @title SelfPassportERC721 - * @notice This contract issues ERC721 tokens based on verified passport credentials using self's verification infrastructure - * @dev Inherits from SelfVerificationRoot for verification logic and ERC721 for NFT functionality - */ -contract SelfPassportERC721 is SelfVerificationRoot, ERC721, Ownable { - using SelfCircuitLibrary for uint256[3]; - - // ==================================================== - // Storage Variables - // ==================================================== - - /// @notice Counter for token IDs - uint256 private _tokenIdCounter; - - /// @notice Mapping from token ID to passport attributes - mapping(uint256 tokenId => SelfCircuitLibrary.PassportData passportAttributes) private _passportAttributes; - - /// @notice Mapping to track minted user identifiers to prevent double minting - mapping(uint256 userIdentifier => bool minted) private _mintedUserIdentifiers; - - // ==================================================== - // Events - // ==================================================== - - event PassportNFTMinted(uint256 indexed tokenId, address indexed owner, SelfCircuitLibrary.PassportData attributes); - - // ==================================================== - // Errors - // ==================================================== - - error UserIdentifierAlreadyMinted(); - error InvalidUserIdentifier(); - - // ==================================================== - // Constructor - // ==================================================== - - /** - * @notice Constructor for the SelfPassportERC721 contract - * @param identityVerificationHubAddress The address of the Identity Verification Hub - * @param scopeValue The expected proof scope for user registration - * @param contractVersion The contract version for validation - * @param attestationIdsList The expected attestation identifiers required in proofs - * @param name The name of the NFT collection - * @param symbol The symbol of the NFT collection - */ - constructor( - address identityVerificationHubAddress, - uint256 scopeValue, - uint8 contractVersion, - bytes32[] memory attestationIdsList, - string memory name, - string memory symbol - ) - SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIdsList) - ERC721(name, symbol) - Ownable(_msgSender()) - {} - - // ==================================================== - // External/Public Functions - // ==================================================== - - /** - * @notice Updates the scope used for verification - * @dev Only callable by the contract owner - * @param newScope The new scope to set - */ - function setScope(uint256 newScope) external onlyOwner { - _setScope(newScope); - } - - /** - * @notice Adds a new attestation ID to the allowed list - * @dev Only callable by the contract owner - * @param attestationId The attestation ID to add - */ - function addAttestationId(bytes32 attestationId) external onlyOwner { - _addAttestationId(attestationId); - } - - /** - * @notice Removes an attestation ID from the allowed list - * @dev Only callable by the contract owner - * @param attestationId The attestation ID to remove - */ - function removeAttestationId(bytes32 attestationId) external onlyOwner { - _removeAttestationId(attestationId); - } - - /** - * @notice Updates the verification configuration - * @dev Only callable by the contract owner - * @param newVerificationConfig The new verification configuration - */ - function setVerificationConfig( - ISelfVerificationRoot.VerificationConfig memory newVerificationConfig - ) external onlyOwner { - _setVerificationConfig(newVerificationConfig); - } - - /** - * @notice Get passport attributes for a specific token ID - * @param tokenId The token ID to query - * @return The passport attributes associated with the token - */ - function getPassportAttributes(uint256 tokenId) external view returns (SelfCircuitLibrary.PassportData memory) { - require(_exists(tokenId), "Token does not exist"); - return _passportAttributes[tokenId]; - } - - /** - * @notice Check if a user identifier has already minted an NFT - * @param userIdentifier The user identifier to check - * @return True if the user identifier has already minted, false otherwise - */ - function isUserIdentifierMinted(uint256 userIdentifier) external view returns (bool) { - return _mintedUserIdentifiers[userIdentifier]; - } - - /** - * @notice Check if the specified attestation ID is allowed - * @param attestationId The attestation ID to check - * @return True if the attestation ID is allowed, false otherwise - */ - function isAttestationIdAllowed(bytes32 attestationId) external view returns (bool) { - return _attestationIdToEnabled[attestationId]; - } - - /** - * @notice Get the current scope value - * @return The current scope value - */ - function getScope() external view returns (uint256) { - return _scope; - } - - /** - * @notice Get the current verification configuration - * @return The current verification configuration - */ - function getVerificationConfig() external view returns (ISelfVerificationRoot.VerificationConfig memory) { - return _getVerificationConfig(); - } - - // ==================================================== - // Override Functions from SelfVerificationRoot - // ==================================================== - - /** - * @notice Hook called after successful verification - handles NFT minting - * @dev Validates user identifier and mints passport NFT with extracted attributes - * @param userIdentifier The user identifier from the proof - * @param revealedDataPacked The packed revealed data from the proof - */ - function onBasicVerificationSuccess( - bytes32 /* attestationId */, - uint256 /* scope */, - uint256 userIdentifier, - uint256 /* nullifier */, - uint256 /* identityCommitmentRoot */, - uint256[] memory revealedDataPacked, - uint256[4] memory /* forbiddenCountriesListPacked */ - ) internal override { - // Check if user identifier is valid - if (userIdentifier == 0) { - revert InvalidUserIdentifier(); - } - - // Check if user identifier has already minted an NFT - if (_mintedUserIdentifiers[userIdentifier]) { - revert UserIdentifierAlreadyMinted(); - } - - // Convert dynamic array to fixed-size array for passport data (first 3 elements) - uint256[3] memory passportRevealedData; - for (uint256 i = 0; i < 3 && i < revealedDataPacked.length; i++) { - passportRevealedData[i] = revealedDataPacked[i]; - } - - // Extract passport data using SelfCircuitLibrary - SelfCircuitLibrary.PassportData memory attributes = SelfCircuitLibrary.extractPassportData( - passportRevealedData - ); - - // Mint NFT - uint256 tokenId = _tokenIdCounter++; - _mint(msg.sender, tokenId); - _passportAttributes[tokenId] = attributes; - _mintedUserIdentifiers[userIdentifier] = true; - - emit PassportNFTMinted(tokenId, msg.sender, attributes); - } - - // ==================================================== - // Internal Functions - // ==================================================== - - /** - * @notice Check if a token exists - * @param tokenId The token ID to check - * @return True if the token exists, false otherwise - */ - function _exists(uint256 tokenId) internal view returns (bool) { - return _ownerOf(tokenId) != address(0); - } -} + // // SPDX-License-Identifier: MIT +// pragma solidity 0.8.28; + +// import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +// import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +// import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; + +// import {SelfCircuitLibrary} from "../libraries/SelfCircuitLibrary.sol"; +// import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; + +// /** +// * @title SelfPassportERC721 +// * @notice This contract issues ERC721 tokens based on verified passport credentials using self's verification infrastructure +// * @dev Inherits from SelfVerificationRoot for verification logic and ERC721 for NFT functionality +// */ +// contract SelfPassportERC721 is SelfVerificationRoot, ERC721, Ownable { +// using SelfCircuitLibrary for uint256[3]; + +// // ==================================================== +// // Storage Variables +// // ==================================================== + +// /// @notice Counter for token IDs +// uint256 private _tokenIdCounter; + +// /// @notice Mapping from token ID to passport attributes +// mapping(uint256 tokenId => SelfCircuitLibrary.PassportData passportAttributes) private _passportAttributes; + +// /// @notice Mapping to track minted user identifiers to prevent double minting +// mapping(uint256 userIdentifier => bool minted) private _mintedUserIdentifiers; + +// // ==================================================== +// // Events +// // ==================================================== + +// event PassportNFTMinted(uint256 indexed tokenId, address indexed owner, SelfCircuitLibrary.PassportData attributes); + +// // ==================================================== +// // Errors +// // ==================================================== + +// error UserIdentifierAlreadyMinted(); +// error InvalidUserIdentifier(); + +// // ==================================================== +// // Constructor +// // ==================================================== + +// /** +// * @notice Constructor for the SelfPassportERC721 contract +// * @param identityVerificationHubAddress The address of the Identity Verification Hub +// * @param scopeValue The expected proof scope for user registration +// * @param contractVersion The contract version for validation +// * @param attestationIdsList The expected attestation identifiers required in proofs +// * @param name The name of the NFT collection +// * @param symbol The symbol of the NFT collection +// */ +// constructor( +// address identityVerificationHubAddress, +// uint256 scopeValue, +// uint8 contractVersion, +// bytes32[] memory attestationIdsList, +// string memory name, +// string memory symbol +// ) +// SelfVerificationRoot(identityVerificationHubAddress, scopeValue, contractVersion, attestationIdsList) +// ERC721(name, symbol) +// Ownable(_msgSender()) +// {} + +// // ==================================================== +// // External/Public Functions +// // ==================================================== + +// /** +// * @notice Updates the scope used for verification +// * @dev Only callable by the contract owner +// * @param newScope The new scope to set +// */ +// function setScope(uint256 newScope) external onlyOwner { +// _setScope(newScope); +// } + +// /** +// * @notice Adds a new attestation ID to the allowed list +// * @dev Only callable by the contract owner +// * @param attestationId The attestation ID to add +// */ +// function addAttestationId(bytes32 attestationId) external onlyOwner { +// _addAttestationId(attestationId); +// } + +// /** +// * @notice Removes an attestation ID from the allowed list +// * @dev Only callable by the contract owner +// * @param attestationId The attestation ID to remove +// */ +// function removeAttestationId(bytes32 attestationId) external onlyOwner { +// _removeAttestationId(attestationId); +// } + +// /** +// * @notice Updates the verification configuration +// * @dev Only callable by the contract owner +// * @param newVerificationConfig The new verification configuration +// */ +// function setVerificationConfig( +// ISelfVerificationRoot.VerificationConfig memory newVerificationConfig +// ) external onlyOwner { +// _setVerificationConfig(newVerificationConfig); +// } + +// /** +// * @notice Get passport attributes for a specific token ID +// * @param tokenId The token ID to query +// * @return The passport attributes associated with the token +// */ +// function getPassportAttributes(uint256 tokenId) external view returns (SelfCircuitLibrary.PassportData memory) { +// require(_exists(tokenId), "Token does not exist"); +// return _passportAttributes[tokenId]; +// } + +// /** +// * @notice Check if a user identifier has already minted an NFT +// * @param userIdentifier The user identifier to check +// * @return True if the user identifier has already minted, false otherwise +// */ +// function isUserIdentifierMinted(uint256 userIdentifier) external view returns (bool) { +// return _mintedUserIdentifiers[userIdentifier]; +// } + +// /** +// * @notice Check if the specified attestation ID is allowed +// * @param attestationId The attestation ID to check +// * @return True if the attestation ID is allowed, false otherwise +// */ +// function isAttestationIdAllowed(bytes32 attestationId) external view returns (bool) { +// return _attestationIdToEnabled[attestationId]; +// } + +// /** +// * @notice Get the current scope value +// * @return The current scope value +// */ +// function getScope() external view returns (uint256) { +// return _scope; +// } + +// /** +// * @notice Get the current verification configuration +// * @return The current verification configuration +// */ +// function getVerificationConfig() external view returns (ISelfVerificationRoot.VerificationConfig memory) { +// return _getVerificationConfig(); +// } + +// // ==================================================== +// // Override Functions from SelfVerificationRoot +// // ==================================================== + +// /** +// * @notice Hook called after successful verification - handles NFT minting +// * @dev Validates user identifier and mints passport NFT with extracted attributes +// * @param userIdentifier The user identifier from the proof +// * @param revealedDataPacked The packed revealed data from the proof +// */ +// function onBasicVerificationSuccess( +// bytes32 /* attestationId */, +// uint256 /* scope */, +// uint256 userIdentifier, +// uint256 /* nullifier */, +// uint256 /* identityCommitmentRoot */, +// uint256[] memory revealedDataPacked, +// uint256[4] memory /* forbiddenCountriesListPacked */ +// ) internal override { +// // Check if user identifier is valid +// if (userIdentifier == 0) { +// revert InvalidUserIdentifier(); +// } + +// // Check if user identifier has already minted an NFT +// if (_mintedUserIdentifiers[userIdentifier]) { +// revert UserIdentifierAlreadyMinted(); +// } + +// // Convert dynamic array to fixed-size array for passport data (first 3 elements) +// uint256[3] memory passportRevealedData; +// for (uint256 i = 0; i < 3 && i < revealedDataPacked.length; i++) { +// passportRevealedData[i] = revealedDataPacked[i]; +// } + +// // Extract passport data using SelfCircuitLibrary +// SelfCircuitLibrary.PassportData memory attributes = SelfCircuitLibrary.extractPassportData( +// passportRevealedData +// ); + +// // Mint NFT +// uint256 tokenId = _tokenIdCounter++; +// _mint(msg.sender, tokenId); +// _passportAttributes[tokenId] = attributes; +// _mintedUserIdentifiers[userIdentifier] = true; + +// emit PassportNFTMinted(tokenId, msg.sender, attributes); +// } + +// // ==================================================== +// // Internal Functions +// // ==================================================== + +// /** +// * @notice Check if a token exists +// * @param tokenId The token ID to check +// * @return True if the token exists, false otherwise +// */ +// function _exists(uint256 tokenId) internal view returns (bool) { +// return _ownerOf(tokenId) != address(0); +// } +// } diff --git a/contracts/contracts/interfaces/IIdentityVerificationHubV2.sol b/contracts/contracts/interfaces/IIdentityVerificationHubV2.sol index 72ff5c324..cb566af36 100644 --- a/contracts/contracts/interfaces/IIdentityVerificationHubV2.sol +++ b/contracts/contracts/interfaces/IIdentityVerificationHubV2.sol @@ -3,101 +3,22 @@ pragma solidity 0.8.28; import {IRegisterCircuitVerifier} from "./IRegisterCircuitVerifier.sol"; import {IDscCircuitVerifier} from "./IDscCircuitVerifier.sol"; -import {IVcAndDiscloseCircuitVerifier} from "./IVcAndDiscloseCircuitVerifier.sol"; -import {CircuitConstants} from "../constants/CircuitConstants.sol"; +import {SelfStructs} from "../libraries/SelfStructs.sol"; /** * @title IIdentityVerificationHubV2 - * @notice Interface for the Identity Verification Hub for verifying zero-knowledge proofs using VC and Disclose circuits. - * @dev Defines data structures and external functions for verifying proofs and recovering human-readable data. + * @notice Interface for the Identity Verification Hub V2 for verifying zero-knowledge proofs. + * @dev Defines all external and public functions from IdentityVerificationHubImplV2. */ interface IIdentityVerificationHubV2 { + // ==================================================== + // External Functions + // ==================================================== + /** - * @notice Enum representing types of data that may be revealed. - */ - enum RevealedDataType { - ISSUING_STATE, // The issuing state of the passport. - NAME, // The full name of the passport holder. - PASSPORT_NUMBER, // The passport number. - NATIONALITY, // The nationality. - DATE_OF_BIRTH, // The date of birth. - GENDER, // The gender. - EXPIRY_DATE, // The passport expiry date. - OLDER_THAN, // The "older than" age verification value. - PASSPORT_NO_OFAC, // The passport number OFAC status. - NAME_AND_DOB_OFAC, // The name and date of birth OFAC verification result. - NAME_AND_YOB_OFAC // The name and year of birth OFAC verification result. - } - - /** - * @notice Structure representing the verification result of a VC and Disclose proof. - * @param attestationId The attestation identifier from the proof. - * @param scope The scope of the verification. - * @param userIdentifier Unique identifier for the user. - * @param nullifier A value used to prevent double registration. - * @param identityCommitmentRoot The root of the identity commitment. - * @param revealedDataPacked Packed revealed data. - * @param forbiddenCountriesListPacked Packed forbidden countries list. - */ - struct VcAndDiscloseVerificationResult { - uint256 attestationId; - uint256 scope; - uint256 userIdentifier; - uint256 nullifier; - uint256 identityCommitmentRoot; - uint256[3] revealedDataPacked; - uint256[4] forbiddenCountriesListPacked; - } - - struct IdCardVcAndDiscloseVerificationResult { - uint256 attestationId; - uint256 scope; - uint256 userIdentifier; - uint256 nullifier; - uint256 identityCommitmentRoot; - uint256[4] revealedDataPacked; - uint256[4] forbiddenCountriesListPacked; - } - - /** - * @notice Structure representing a hub proof for VC and Disclose verification. - * @param olderThanEnabled Flag indicating if the 'olderThan' check is required. - * @param olderThan Threshold age for verification. - * @param forbiddenCountriesEnabled Flag indicating if forbidden countries verification is required. - * @param forbiddenCountriesListPacked Packed forbidden countries list. - * @param ofacEnabled Array of flags indicating which OFAC checks are enabled. [passportNo, nameAndDob, nameAndYob] - * @param vcAndDiscloseProof The underlying VC and Disclose proof. - */ - struct VcAndDiscloseHubProof { - bool olderThanEnabled; - uint256 olderThan; - bool forbiddenCountriesEnabled; - uint256[4] forbiddenCountriesListPacked; - bool[3] ofacEnabled; - IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof vcAndDiscloseProof; - } - - struct IdCardVcAndDiscloseHubProof { - bool olderThanEnabled; - uint256 olderThan; - bool forbiddenCountriesEnabled; - uint256[4] forbiddenCountriesListPacked; - bool[2] ofacEnabled; - IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof vcAndDiscloseProof; - } - - /** - * @notice Verifies a VC and Disclose proof using unified bytes interface. - * @dev Supports both passport and ID card proofs through a unified interface. - * @param proofData Encoded proof data containing all necessary verification parameters. - * @return result Encoded verification result containing all relevant data. - */ - function verifyVcAndDisclose(bytes calldata proofData) external view returns (bytes memory result); - - /** - * @notice Registers a passport commitment using a register circuit proof. - * @dev Verifies the proof and then calls the Identity Registry to register the commitment. - * @param attestationId The attestation identifier. + * @notice Registers a commitment using a register circuit proof. + * @dev Verifies the register circuit proof and then calls the Identity Registry to register the commitment. + * @param attestationId The attestation ID. * @param registerCircuitVerifierId The identifier for the register circuit verifier to use. * @param registerCircuitProof The register circuit proof data. */ @@ -109,10 +30,10 @@ interface IIdentityVerificationHubV2 { /** * @notice Registers a DSC key commitment using a DSC circuit proof. - * @dev Verifies the DSC circuit proof before registering the DSC key commitment. - * @param attestationId The attestation identifier. - * @param dscCircuitVerifierId The identifier for the DSC circuit verifier to be used. - * @param dscCircuitProof The proof data for the DSC circuit. + * @dev Verifies the DSC proof and then calls the Identity Registry to register the dsc key commitment. + * @param attestationId The attestation ID. + * @param dscCircuitVerifierId The identifier for the DSC circuit verifier to use. + * @param dscCircuitProof The DSC circuit proof data. */ function registerDscKeyCommitment( bytes32 attestationId, @@ -121,75 +42,140 @@ interface IIdentityVerificationHubV2 { ) external; /** - * @notice Returns the address of the Identity Registry for a specific attestation type. - * @param attestationId The attestation identifier. - * @return registryAddr The address of the Identity Registry contract. - */ - function registry(bytes32 attestationId) external view returns (address registryAddr); - - /** - * @notice Returns the address of the VC and Disclose circuit verifier for a specific attestation type. - * @param attestationId The attestation identifier. - * @return verifierAddr The address of the VC and Disclose circuit verifier. + * @notice Sets verification config in V2 storage (owner only) + * @dev The configId is automatically generated from the config content using sha256(abi.encode(config)) + * @param config The verification configuration + * @return configId The generated config ID */ - function vcAndDiscloseCircuitVerifier(bytes32 attestationId) external view returns (address verifierAddr); + function setVerificationConfigV2( + SelfStructs.VerificationConfigV2 memory config + ) external returns (bytes32 configId); /** - * @notice Retrieves the register circuit verifier for a given signature type. - * @param typeId The signature type identifier. - * @return verifier The address of the register circuit verifier. + * @notice Main verification function with new structured input format + * @param baseVerificationInput The base verification input data + * @param userContextData The user context data */ - function sigTypeToRegisterCircuitVerifiers(uint256 typeId) external view returns (address verifier); - - /** - * @notice Retrieves the DSC circuit verifier for a given signature type. - * @param typeId The signature type identifier. - * @return verifier The address of the DSC circuit verifier. - */ - function sigTypeToDscCircuitVerifiers(uint256 typeId) external view returns (address verifier); + function verify(bytes calldata baseVerificationInput, bytes calldata userContextData) external; /** * @notice Updates the registry address. - * @param attestationId The attestation identifier. + * @param attestationId The attestation ID. * @param registryAddress The new registry address. */ function updateRegistry(bytes32 attestationId, address registryAddress) external; /** * @notice Updates the VC and Disclose circuit verifier address. - * @param attestationId The attestation identifier. + * @param attestationId The attestation ID. * @param vcAndDiscloseCircuitVerifierAddress The new VC and Disclose circuit verifier address. */ function updateVcAndDiscloseCircuit(bytes32 attestationId, address vcAndDiscloseCircuitVerifierAddress) external; /** * @notice Updates the register circuit verifier for a specific signature type. + * @param attestationId The attestation identifier. * @param typeId The signature type identifier. * @param verifierAddress The new register circuit verifier address. */ - function updateRegisterCircuitVerifier(uint256 typeId, address verifierAddress) external; + function updateRegisterCircuitVerifier(bytes32 attestationId, uint256 typeId, address verifierAddress) external; /** * @notice Updates the DSC circuit verifier for a specific signature type. + * @param attestationId The attestation identifier. * @param typeId The signature type identifier. * @param verifierAddress The new DSC circuit verifier address. */ - function updateDscVerifier(uint256 typeId, address verifierAddress) external; + function updateDscVerifier(bytes32 attestationId, uint256 typeId, address verifierAddress) external; /** * @notice Batch updates register circuit verifiers. + * @param attestationIds An array of attestation identifiers. * @param typeIds An array of signature type identifiers. * @param verifierAddresses An array of new register circuit verifier addresses. */ function batchUpdateRegisterCircuitVerifiers( + bytes32[] calldata attestationIds, uint256[] calldata typeIds, address[] calldata verifierAddresses ) external; /** * @notice Batch updates DSC circuit verifiers. + * @param attestationIds An array of attestation identifiers. * @param typeIds An array of signature type identifiers. * @param verifierAddresses An array of new DSC circuit verifier addresses. */ - function batchUpdateDscCircuitVerifiers(uint256[] calldata typeIds, address[] calldata verifierAddresses) external; + function batchUpdateDscCircuitVerifiers( + bytes32[] calldata attestationIds, + uint256[] calldata typeIds, + address[] calldata verifierAddresses + ) external; + + // ==================================================== + // External View Functions + // ==================================================== + + /** + * @notice Returns the registry address for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The registry address associated with the attestation ID. + */ + function registry(bytes32 attestationId) external view returns (address); + + /** + * @notice Returns the disclose verifier address for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The disclose verifier address associated with the attestation ID. + */ + function discloseVerifier(bytes32 attestationId) external view returns (address); + + /** + * @notice Returns the register circuit verifier address for a given attestation ID and type ID. + * @param attestationId The attestation ID to query. + * @param typeId The type ID to query. + * @return The register circuit verifier address associated with the attestation ID and type ID. + */ + function registerCircuitVerifiers(bytes32 attestationId, uint256 typeId) external view returns (address); + + /** + * @notice Returns the DSC circuit verifier address for a given attestation ID and type ID. + * @param attestationId The attestation ID to query. + * @param typeId The type ID to query. + * @return The DSC circuit verifier address associated with the attestation ID and type ID. + */ + function dscCircuitVerifiers(bytes32 attestationId, uint256 typeId) external view returns (address); + + /** + * @notice Returns the merkle root timestamp for a given attestation ID and root. + * @param attestationId The attestation ID to query. + * @param root The merkle root to query. + * @return The merkle root timestamp associated with the attestation ID and root. + */ + function rootTimestamp(bytes32 attestationId, uint256 root) external view returns (uint256); + + /** + * @notice Returns the identity commitment merkle root for a given attestation ID. + * @param attestationId The attestation ID to query. + * @return The identity commitment merkle root associated with the attestation ID. + */ + function getIdentityCommitmentMerkleRoot(bytes32 attestationId) external view returns (uint256); + + /** + * @notice Checks if a verification config exists + * @param configId The configuration identifier + * @return exists Whether the config exists + */ + function verificationConfigV2Exists(bytes32 configId) external view returns (bool exists); + + // ==================================================== + // Public Functions + // ==================================================== + + /** + * @notice Generates a config ID from a verification config + * @param config The verification configuration + * @return The generated config ID (sha256 hash of encoded config) + */ + function generateConfigId(SelfStructs.VerificationConfigV2 memory config) external pure returns (bytes32); } diff --git a/contracts/contracts/interfaces/ISelfVerificationRoot.sol b/contracts/contracts/interfaces/ISelfVerificationRoot.sol index b7b2cee01..9fa75bb47 100644 --- a/contracts/contracts/interfaces/ISelfVerificationRoot.sol +++ b/contracts/contracts/interfaces/ISelfVerificationRoot.sol @@ -1,15 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; +/** + * @title ISelfVerificationRoot + * @notice Interface for self-verification infrastructure integration + * @dev Provides base functionality for verifying and disclosing identity credentials + */ interface ISelfVerificationRoot { - struct VerificationConfig { - bool olderThanEnabled; - uint256 olderThan; - bool forbiddenCountriesEnabled; - uint256[4] forbiddenCountriesListPacked; - bool[3] ofacEnabled; - } - + /** + * @notice Structure containing proof data for disclose circuits + * @dev Contains the proof elements required for zero-knowledge verification + * @param a First proof element + * @param b Second proof element (2x2 matrix) + * @param c Third proof element + * @param pubSignals Array of 21 public signals for the circuit + */ struct DiscloseCircuitProof { uint256[2] a; uint256[2][2] b; @@ -18,8 +23,51 @@ interface ISelfVerificationRoot { } /** - * @notice Verifies a self-proof using bytes-based relayer data - * @param relayerData Packed data from relayer in format: | 1 byte circuitVersion | 1 byte contractVersion | 30 bytes buffer | 32 bytes attestationId | 32 bytes scope | proof data | + * @notice Structure containing verified identity disclosure output data + * @dev Contains all disclosed identity information after successful verification + * @param attestationId Unique identifier for the identity documents + * @param userIdentifier Unique identifier for the user + * @param nullifier Unique nullifier to prevent double-spending + * @param forbiddenCountriesListPacked Packed representation of forbidden countries list + * @param issuingState The state/country that issued the identity document + * @param name Array of name components + * @param idNumber The identity document number + * @param nationality The nationality of the document holder + * @param dateOfBirth Date of birth in string format + * @param gender Gender of the document holder + * @param expiryDate Expiry date of the identity document + * @param olderThan Verified age threshold (e.g., 18 for adult verification) + * @param ofac Array of OFAC (Office of Foreign Assets Control) compliance flags + */ + struct GenericDiscloseOutputV2 { + bytes32 attestationId; + uint256 userIdentifier; + uint256 nullifier; + uint256[4] forbiddenCountriesListPacked; + string issuingState; + string[] name; + string idNumber; + string nationality; + string dateOfBirth; + string gender; + string expiryDate; + uint256 olderThan; + bool[3] ofac; + } + + /** + * @notice Verifies a self-proof using the bytes-based interface + * @dev Parses relayer data format and validates against contract settings before calling hub V2 + * @param proofPayload Packed data from relayer in format: | 32 bytes attestationId | proof data | + * @param userContextData User-defined data in format: | 32 bytes configId | 32 bytes destChainId | 32 bytes userIdentifier | data | + */ + function verifySelfProof(bytes calldata proofPayload, bytes calldata userContextData) external; + + /** + * @notice Callback function called upon successful verification + * @dev Only the identity verification hub V2 contract should call this function + * @param output The verification output data containing disclosed identity information + * @param userData The user-defined data passed through the verification process */ - function verifySelfProof(bytes calldata relayerData) external; + function onVerificationSuccess(bytes memory output, bytes memory userData) external; } diff --git a/contracts/contracts/libraries/CircuitAttributeHandler.sol b/contracts/contracts/libraries/CircuitAttributeHandler.sol index 88696e503..6f1429b3f 100644 --- a/contracts/contracts/libraries/CircuitAttributeHandler.sol +++ b/contracts/contracts/libraries/CircuitAttributeHandler.sol @@ -12,7 +12,7 @@ library CircuitAttributeHandler { /** * @dev Reverts when the provided character codes array does not contain enough data to extract an attribute. */ - error INSUFFICIENT_CHARCODE_LEN(); + error InsufficientCharcodeLen(); // Define constant start and end positions for each attribute uint256 private constant ISSUING_STATE_START = 2; @@ -179,7 +179,7 @@ library CircuitAttributeHandler { /** * @notice Extracts a substring from a specified range in the byte array. - * @dev Reverts with INSUFFICIENT_CHARCODE_LEN if the byte array's length is insufficient. + * @dev Reverts with InsufficientCharcodeLen if the byte array's length is insufficient. * @param charcodes The byte array containing the encoded passport attribute. * @param start The starting index (inclusive) of the attribute in the byte array. * @param end The ending index (inclusive) of the attribute in the byte array. @@ -191,7 +191,7 @@ library CircuitAttributeHandler { uint256 end ) internal pure returns (string memory) { if (charcodes.length <= end) { - revert INSUFFICIENT_CHARCODE_LEN(); + revert InsufficientCharcodeLen(); } bytes memory attributeBytes = new bytes(end - start + 1); for (uint256 i = start; i <= end; i++) { diff --git a/contracts/contracts/libraries/CircuitAttributeHandlerV2.sol b/contracts/contracts/libraries/CircuitAttributeHandlerV2.sol index 32d31ab99..5cdcd9433 100644 --- a/contracts/contracts/libraries/CircuitAttributeHandlerV2.sol +++ b/contracts/contracts/libraries/CircuitAttributeHandlerV2.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.28; import {Formatter} from "./Formatter.sol"; import {AttestationId} from "../constants/AttestationId.sol"; +import {SelfStructs} from "./SelfStructs.sol"; /** * @title UnifiedAttributeHandler Library @@ -13,7 +14,7 @@ library CircuitAttributeHandlerV2 { /** * @dev Reverts when the provided character codes array does not contain enough data to extract an attribute. */ - error INSUFFICIENT_CHARCODE_LEN(); + error InsufficientCharcodeLen(); /** * @notice Structure containing field positions for a specific attestation type. @@ -195,9 +196,9 @@ library CircuitAttributeHandlerV2 { * @param charcodes The byte array containing attribute data. * @return The OFAC status for document number check as a uint256. */ - function getDocumentNoOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (uint256) { + function getDocumentNoOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (bool) { FieldPositions memory positions = getFieldPositions(attestationId); - return uint8(charcodes[positions.ofacStart]); + return uint8(charcodes[positions.ofacStart]) == 1; } /** @@ -206,12 +207,12 @@ library CircuitAttributeHandlerV2 { * @param charcodes The byte array containing attribute data. * @return The OFAC status for name and DOB check as a uint256. */ - function getNameAndDobOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (uint256) { + function getNameAndDobOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (bool) { FieldPositions memory positions = getFieldPositions(attestationId); if (attestationId == AttestationId.E_PASSPORT) { - return uint8(charcodes[positions.ofacStart + 1]); + return uint8(charcodes[positions.ofacStart + 1]) == 1; } else { - return uint8(charcodes[positions.ofacStart]); + return uint8(charcodes[positions.ofacStart]) == 1; } } @@ -221,12 +222,12 @@ library CircuitAttributeHandlerV2 { * @param charcodes The byte array containing attribute data. * @return The OFAC status for name and YOB check as a uint256. */ - function getNameAndYobOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (uint256) { + function getNameAndYobOfac(bytes32 attestationId, bytes memory charcodes) internal pure returns (bool) { FieldPositions memory positions = getFieldPositions(attestationId); if (attestationId == AttestationId.E_PASSPORT) { - return uint8(charcodes[positions.ofacStart + 2]); + return uint8(charcodes[positions.ofacStart + 2]) == 1; } else { - return uint8(charcodes[positions.ofacStart + 1]); + return uint8(charcodes[positions.ofacStart + 1]) == 1; } } @@ -246,22 +247,23 @@ library CircuitAttributeHandlerV2 { bool checkNameAndDob, bool checkNameAndYob ) internal pure returns (bool) { - bool documentNoResult = true; - bool nameAndDobResult = true; - bool nameAndYobResult = true; + bool documentNoResult = true; // Default to true (no violation) if not checking + bool nameAndDobResult = true; // Default to true (no violation) if not checking + bool nameAndYobResult = true; // Default to true (no violation) if not checking if (checkDocumentNo && attestationId == AttestationId.E_PASSPORT) { - documentNoResult = getDocumentNoOfac(attestationId, charcodes) == 1; + documentNoResult = getDocumentNoOfac(attestationId, charcodes); } if (checkNameAndDob) { - nameAndDobResult = getNameAndDobOfac(attestationId, charcodes) == 1; + nameAndDobResult = getNameAndDobOfac(attestationId, charcodes); } if (checkNameAndYob) { - nameAndYobResult = getNameAndYobOfac(attestationId, charcodes) == 1; + nameAndYobResult = getNameAndYobOfac(attestationId, charcodes); } + // Return true if all enabled checks indicate no OFAC violations (all return true) return documentNoResult && nameAndDobResult && nameAndYobResult; } @@ -293,7 +295,7 @@ library CircuitAttributeHandlerV2 { uint256 end ) internal pure returns (string memory) { if (charcodes.length <= end) { - revert INSUFFICIENT_CHARCODE_LEN(); + revert InsufficientCharcodeLen(); } bytes memory attributeBytes = new bytes(end - start + 1); for (uint256 i = start; i <= end; i++) { @@ -319,6 +321,6 @@ library CircuitAttributeHandlerV2 { * @dev Maintained for backward compatibility. Use getDocumentNoOfac instead. */ function getPassportNoOfac(bytes memory charcodes) internal pure returns (uint256) { - return getDocumentNoOfac(AttestationId.E_PASSPORT, charcodes); + return getDocumentNoOfac(AttestationId.E_PASSPORT, charcodes) ? 1 : 0; } } diff --git a/contracts/contracts/libraries/CustomVerifier.sol b/contracts/contracts/libraries/CustomVerifier.sol new file mode 100644 index 000000000..e94d829eb --- /dev/null +++ b/contracts/contracts/libraries/CustomVerifier.sol @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {CircuitAttributeHandlerV2} from "./CircuitAttributeHandlerV2.sol"; +import {AttestationId} from "../constants/AttestationId.sol"; +import {SelfStructs} from "./SelfStructs.sol"; +import {CircuitAttributeHandlerV2} from "./CircuitAttributeHandlerV2.sol"; +import {Formatter} from "./Formatter.sol"; +import {GenericFormatter} from "./GenericFormatter.sol"; + +library CustomVerifier { + error InvalidAttestationId(); + error InvalidOfacCheck(); + error InvalidForbiddenCountries(); + error InvalidOlderThan(); + + /** + * @notice Verifies the configuration of the custom verifier. + * @param attestationId The attestation ID. + * @param config The verification config of the custom verifier. + * @param proofOutput The proof output of the custom verifier. + * @return genericDiscloseOutput The generic disclose output. + */ + function customVerify( + bytes32 attestationId, + bytes calldata config, + bytes calldata proofOutput + ) external pure returns (SelfStructs.GenericDiscloseOutputV2 memory) { + SelfStructs.VerificationConfigV2 memory verificationConfig = GenericFormatter.verificationConfigFromBytes( + config + ); + + if (attestationId == AttestationId.E_PASSPORT) { + SelfStructs.PassportOutput memory passportOutput = abi.decode(proofOutput, (SelfStructs.PassportOutput)); + return CustomVerifier.verifyPassport(verificationConfig, passportOutput); + } else if (attestationId == AttestationId.EU_ID_CARD) { + SelfStructs.EuIdOutput memory idCardOutput = abi.decode(proofOutput, (SelfStructs.EuIdOutput)); + return CustomVerifier.verifyIdCard(verificationConfig, idCardOutput); + } else { + revert InvalidAttestationId(); + } + } + + /** + * @notice Verifies a passport output. + * @param verificationConfig The verification configuration. + * @param passportOutput The passport output from the circuit. + * @return genericDiscloseOutput The generic disclose output. + */ + function verifyPassport( + SelfStructs.VerificationConfigV2 memory verificationConfig, + SelfStructs.PassportOutput memory passportOutput + ) internal pure returns (SelfStructs.GenericDiscloseOutputV2 memory) { + if ( + verificationConfig.ofacEnabled[0] || verificationConfig.ofacEnabled[1] || verificationConfig.ofacEnabled[2] + ) { + if ( + !CircuitAttributeHandlerV2.compareOfac( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked, + verificationConfig.ofacEnabled[0], + verificationConfig.ofacEnabled[1], + verificationConfig.ofacEnabled[2] + ) + ) { + revert InvalidOfacCheck(); + } + } + if (verificationConfig.forbiddenCountriesEnabled) { + for (uint256 i = 0; i < 4; i++) { + if ( + passportOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i] + ) { + revert InvalidForbiddenCountries(); + } + } + } + + if (verificationConfig.olderThanEnabled) { + if ( + !CircuitAttributeHandlerV2.compareOlderThan( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked, + verificationConfig.olderThan + ) + ) { + revert InvalidOlderThan(); + } + } + + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput = SelfStructs.GenericDiscloseOutputV2({ + attestationId: AttestationId.E_PASSPORT, + userIdentifier: passportOutput.userIdentifier, + nullifier: passportOutput.nullifier, + forbiddenCountriesListPacked: passportOutput.forbiddenCountriesListPacked, + issuingState: CircuitAttributeHandlerV2.getIssuingState( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + name: CircuitAttributeHandlerV2.getName(AttestationId.E_PASSPORT, passportOutput.revealedDataPacked), + idNumber: CircuitAttributeHandlerV2.getDocumentNumber( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + nationality: CircuitAttributeHandlerV2.getNationality( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + dateOfBirth: CircuitAttributeHandlerV2.getDateOfBirth( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + gender: CircuitAttributeHandlerV2.getGender(AttestationId.E_PASSPORT, passportOutput.revealedDataPacked), + expiryDate: CircuitAttributeHandlerV2.getExpiryDate( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + olderThan: verificationConfig.olderThan, + ofac: [ + CircuitAttributeHandlerV2.getDocumentNoOfac( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + CircuitAttributeHandlerV2.getNameAndDobOfac( + AttestationId.E_PASSPORT, + passportOutput.revealedDataPacked + ), + CircuitAttributeHandlerV2.getNameAndYobOfac(AttestationId.E_PASSPORT, passportOutput.revealedDataPacked) + ] + }); + + return genericDiscloseOutput; + } + + /** + * @notice Verifies an ID card output. + * @param verificationConfig The verification configuration. + * @param idCardOutput The ID card output from the circuit. + * @return genericDiscloseOutput The generic disclose output. + */ + function verifyIdCard( + SelfStructs.VerificationConfigV2 memory verificationConfig, + SelfStructs.EuIdOutput memory idCardOutput + ) internal pure returns (SelfStructs.GenericDiscloseOutputV2 memory) { + if (verificationConfig.ofacEnabled[0] || verificationConfig.ofacEnabled[1]) { + if ( + !CircuitAttributeHandlerV2.compareOfac( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked, + false, + verificationConfig.ofacEnabled[0], + verificationConfig.ofacEnabled[1] + ) + ) { + revert InvalidOfacCheck(); + } + } + + if (verificationConfig.forbiddenCountriesEnabled) { + for (uint256 i = 0; i < 4; i++) { + if ( + idCardOutput.forbiddenCountriesListPacked[i] != verificationConfig.forbiddenCountriesListPacked[i] + ) { + revert InvalidForbiddenCountries(); + } + } + } + + if (verificationConfig.olderThanEnabled) { + if ( + !CircuitAttributeHandlerV2.compareOlderThan( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked, + verificationConfig.olderThan + ) + ) { + revert InvalidOlderThan(); + } + } + + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput = SelfStructs.GenericDiscloseOutputV2({ + attestationId: AttestationId.EU_ID_CARD, + userIdentifier: idCardOutput.userIdentifier, + nullifier: idCardOutput.nullifier, + forbiddenCountriesListPacked: idCardOutput.forbiddenCountriesListPacked, + issuingState: CircuitAttributeHandlerV2.getIssuingState( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked + ), + name: CircuitAttributeHandlerV2.getName(AttestationId.EU_ID_CARD, idCardOutput.revealedDataPacked), + idNumber: CircuitAttributeHandlerV2.getDocumentNumber( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked + ), + nationality: CircuitAttributeHandlerV2.getNationality( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked + ), + dateOfBirth: CircuitAttributeHandlerV2.getDateOfBirth( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked + ), + gender: CircuitAttributeHandlerV2.getGender(AttestationId.EU_ID_CARD, idCardOutput.revealedDataPacked), + expiryDate: CircuitAttributeHandlerV2.getExpiryDate( + AttestationId.EU_ID_CARD, + idCardOutput.revealedDataPacked + ), + olderThan: verificationConfig.olderThan, + ofac: [ + false, + CircuitAttributeHandlerV2.getNameAndDobOfac(AttestationId.EU_ID_CARD, idCardOutput.revealedDataPacked), + CircuitAttributeHandlerV2.getNameAndYobOfac(AttestationId.EU_ID_CARD, idCardOutput.revealedDataPacked) + ] + }); + + return genericDiscloseOutput; + } +} diff --git a/contracts/contracts/libraries/Formatter.sol b/contracts/contracts/libraries/Formatter.sol index a39947f3d..7c5a8d96c 100644 --- a/contracts/contracts/libraries/Formatter.sol +++ b/contracts/contracts/libraries/Formatter.sol @@ -154,6 +154,7 @@ library Formatter { * @param publicSignals A packed uint256 containing encoded forbidden country data. * @return forbiddenCountries An array of strings representing the forbidden country codes. */ + // TODO: look at this function a bit function extractForbiddenCountriesFromPacked( uint256[4] memory publicSignals ) internal pure returns (string[MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH] memory forbiddenCountries) { @@ -164,33 +165,47 @@ library Formatter { } for (uint256 j = 0; j < MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH; j++) { - uint256 byteIndex = j * 3; + uint256 byteIndex = (j * 3) % 93; + uint256 index = j / 31; - if (byteIndex + 2 < 32) { + if (byteIndex + 2 < 31) { uint256 shift = byteIndex * 8; uint256 mask = 0xFFFFFF; - uint256 packedData = (publicSignals[0] >> shift) & mask; - forbiddenCountries[j] = string(abi.encodePacked(uint24(packedData))); - } else if (byteIndex < 32) { - uint256 bytesFrom0 = 32 - byteIndex; - uint256 bytesTo1 = 3 - bytesFrom0; - - uint256 shift0 = byteIndex * 8; - uint256 mask0 = (1 << (bytesFrom0 * 8)) - 1; - uint256 part0 = (publicSignals[0] >> shift0) & mask0; - - uint256 shift1 = 0; - uint256 mask1 = (1 << (bytesTo1 * 8)) - 1; - uint256 part1 = (publicSignals[1] >> shift1) & mask1; - - uint256 combined = (part1 << (bytesFrom0 * 8)) | part0; + uint256 packedData = (publicSignals[index * 3] >> shift) & mask; + uint256 reversedPackedData = ((packedData & 0xff) << 16) | + ((packedData & 0xff00)) | + ((packedData & 0xff0000) >> 16); + forbiddenCountries[j] = string(abi.encodePacked(uint24(reversedPackedData))); + } else if (byteIndex < 31) { + uint256 part0 = (publicSignals[0] >> (byteIndex * 8)); + uint256 part1 = publicSignals[1] & 0x00ffff; + uint256 reversedPart1 = ((part1 & 0xff) << 8) | ((part1 & 0xff00) >> 8); + uint256 combined = reversedPart1 | (part0 << 16); forbiddenCountries[j] = string(abi.encodePacked(uint24(combined))); - } else { - uint256 byteIndexIn1 = byteIndex - 32; + } else if (byteIndex + 2 < 62) { + uint256 byteIndexIn1 = byteIndex - 31; uint256 shift = byteIndexIn1 * 8; uint256 mask = 0xFFFFFF; uint256 packedData = (publicSignals[1] >> shift) & mask; - forbiddenCountries[j] = string(abi.encodePacked(uint24(packedData))); + uint256 reversedPackedData = ((packedData & 0xff) << 16) | + ((packedData & 0xff00)) | + ((packedData & 0xff0000) >> 16); + forbiddenCountries[j] = string(abi.encodePacked(uint24(reversedPackedData))); + } else if (byteIndex < 62) { + uint256 part0 = (publicSignals[1] >> ((byteIndex - 31) * 8)) & 0x00ffff; + uint256 reversedPart0 = ((part0 & 0xff) << 8) | ((part0 & 0xff00) >> 8); + uint256 part1 = publicSignals[2] & 0x0000ff; + uint256 combined = part1 | (reversedPart0 << 8); + forbiddenCountries[j] = string(abi.encodePacked(uint24(combined))); + } else if (byteIndex < 93) { + uint256 byteIndexIn1 = byteIndex - 62; + uint256 shift = byteIndexIn1 * 8; + uint256 mask = 0xFFFFFF; + uint256 packedData = (publicSignals[2] >> shift) & mask; + uint256 reversedPackedData = ((packedData & 0xff) << 16) | + ((packedData & 0xff00)) | + ((packedData & 0xff0000) >> 16); + forbiddenCountries[j] = string(abi.encodePacked(uint24(reversedPackedData))); } } diff --git a/contracts/contracts/libraries/GenericFormatter.sol b/contracts/contracts/libraries/GenericFormatter.sol new file mode 100644 index 000000000..da16da46c --- /dev/null +++ b/contracts/contracts/libraries/GenericFormatter.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {SelfStructs} from "./SelfStructs.sol"; + +struct GenericVerificationStruct { + uint8 attestationId; + bytes verificationConfig; +} + +library GenericFormatter { + /** + * @notice Converts a VerificationConfigV1 struct to a VerificationConfigV2 struct. + * @param verificationConfigV1 The VerificationConfigV1 struct to convert. + * @return verificationConfig The converted VerificationConfigV2 struct. + */ + function fromV1Config( + SelfStructs.VerificationConfigV1 memory verificationConfigV1 + ) internal pure returns (SelfStructs.VerificationConfigV2 memory verificationConfig) { + verificationConfig = SelfStructs.VerificationConfigV2({ + olderThanEnabled: verificationConfigV1.olderThanEnabled, + olderThan: verificationConfigV1.olderThan, + forbiddenCountriesEnabled: verificationConfigV1.forbiddenCountriesEnabled, + forbiddenCountriesListPacked: verificationConfigV1.forbiddenCountriesListPacked, + ofacEnabled: verificationConfigV1.ofacEnabled + }); + } + + /** + * @notice Converts a bytes array to the latest VerificationConfig struct. + * @param verificationConfig The bytes array to convert. + * @return verificationConfigV2 The converted VerificationConfig struct. + */ + function verificationConfigFromBytes( + bytes memory verificationConfig + ) internal pure returns (SelfStructs.VerificationConfigV2 memory verificationConfigV2) { + return abi.decode(verificationConfig, (SelfStructs.VerificationConfigV2)); + } + + /** + * @notice Formats a VerificationConfigV1 struct to the latest verification config bytes array. + * @param verificationConfigV1 The VerificationConfigV1 struct to format. + * @return v1ConfigBytes The latest verification config formatted bytes array. + */ + function formatV1Config( + SelfStructs.VerificationConfigV1 memory verificationConfigV1 + ) internal pure returns (bytes memory v1ConfigBytes) { + SelfStructs.VerificationConfigV2 memory verificationConfigV2 = fromV1Config(verificationConfigV1); + return abi.encode(verificationConfigV2); + } + + /** + * @notice Formats a VerificationConfigV2 struct to the latest verification config bytes array. + * @param verificationConfigV2 The VerificationConfigV2 struct to format. + * @return v2ConfigBytes The latest verification config formatted bytes array. + */ + function formatV2Config( + SelfStructs.VerificationConfigV2 memory verificationConfigV2 + ) internal pure returns (bytes memory v2ConfigBytes) { + return abi.encode(verificationConfigV2); + } + + /** + * @notice Formats a GenericDiscloseOutputV2 struct to the latest generic disclose output bytes array. + * @param genericDiscloseOutput The GenericDiscloseOutputV2 struct to format. + * @return v2StructBytes The latest generic disclose output formatted bytes array. + */ + function toV2Struct( + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput + ) internal pure returns (bytes memory v2StructBytes) { + v2StructBytes = abi.encode(genericDiscloseOutput); + } +} diff --git a/contracts/contracts/libraries/IdCardAttributeHandler.sol b/contracts/contracts/libraries/IdCardAttributeHandler.sol index 9207b439d..03c587a87 100644 --- a/contracts/contracts/libraries/IdCardAttributeHandler.sol +++ b/contracts/contracts/libraries/IdCardAttributeHandler.sol @@ -13,7 +13,7 @@ library IdCardAttributeHandler { /** * @dev Reverts when the provided character codes array does not contain enough data to extract an attribute. */ - error INSUFFICIENT_CHARCODE_LEN(); + error InsufficientCharcodeLen(); // Define constant start and end positions for each attribute uint256 private constant ISSUING_STATE_START = 2; @@ -177,7 +177,7 @@ library IdCardAttributeHandler { /** * @notice Extracts a substring from a specified range in the byte array. - * @dev Reverts with INSUFFICIENT_CHARCODE_LEN if the byte array's length is insufficient. + * @dev Reverts with InsufficientCharcodeLen if the byte array's length is insufficient. * @param charcodes The byte array containing the encoded passport attribute. * @param start The starting index (inclusive) of the attribute in the byte array. * @param end The ending index (inclusive) of the attribute in the byte array. @@ -189,7 +189,7 @@ library IdCardAttributeHandler { uint256 end ) internal pure returns (string memory) { if (charcodes.length <= end) { - revert INSUFFICIENT_CHARCODE_LEN(); + revert InsufficientCharcodeLen(); } bytes memory attributeBytes = new bytes(end - start + 1); for (uint256 i = start; i <= end; i++) { diff --git a/contracts/contracts/libraries/SelfStructs.sol b/contracts/contracts/libraries/SelfStructs.sol new file mode 100644 index 000000000..14b1fbb99 --- /dev/null +++ b/contracts/contracts/libraries/SelfStructs.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +/** + * @title SelfStructs + * @dev Library containing data structures for Self protocol identity verification + * @notice Defines structs for passport verification, EU ID verification, and generic disclosure outputs + */ +library SelfStructs { + /** + * @dev Header structure for Hub input containing contract version and scope information + * @param contractVersion Version of the contract being used + * @param scope Scope identifier for the verification request + * @param attestationId Unique identifier for the attestation + */ + struct HubInputHeader { + uint8 contractVersion; + uint256 scope; + bytes32 attestationId; + } + + /** + * @dev Output structure for passport verification results + * @param attestationId Unique identifier for the attestation + * @param revealedDataPacked Packed binary data of revealed information + * @param userIdentifier Unique identifier for the user + * @param nullifier Cryptographic nullifier to prevent double-spending + * @param forbiddenCountriesListPacked Packed list of forbidden countries (4 uint256 array) + */ + struct PassportOutput { + uint256 attestationId; + bytes revealedDataPacked; + uint256 userIdentifier; + uint256 nullifier; + uint256[4] forbiddenCountriesListPacked; + } + + /** + * @dev Output structure for EU ID verification results + * @param attestationId Unique identifier for the attestation + * @param revealedDataPacked Packed binary data of revealed information + * @param userIdentifier Unique identifier for the user + * @param nullifier Cryptographic nullifier to prevent double-spending + * @param forbiddenCountriesListPacked Packed list of forbidden countries (4 uint256 array) + */ + struct EuIdOutput { + uint256 attestationId; + bytes revealedDataPacked; + uint256 userIdentifier; + uint256 nullifier; + uint256[4] forbiddenCountriesListPacked; + } + + /// @dev OFAC verification mode: Passport number only + uint256 constant passportNoOfac = 0; + /// @dev OFAC verification mode: Name and date of birth + uint256 constant nameAndDobOfac = 1; + /// @dev OFAC verification mode: Name and year of birth + uint256 constant nameAndYobOfac = 2; + + /** + * @dev Generic disclosure output structure (Version 2) with detailed personal information + * @param attestationId Unique identifier for the attestation + * @param userIdentifier Unique identifier for the user + * @param nullifier Cryptographic nullifier to prevent double-spending + * @param forbiddenCountriesListPacked Packed list of forbidden countries (4 uint256 array) + * @param issuingState Country or state that issued the document + * @param name Array of name components (first, middle, last names) + * @param idNumber Government-issued identification number + * @param nationality Nationality of the document holder + * @param dateOfBirth Date of birth in string format + * @param gender Gender of the document holder + * @param expiryDate Document expiration date in string format + * @param olderThan Minimum age verification result + * @param ofac Array of OFAC (Office of Foreign Assets Control) verification results for different modes + */ + struct GenericDiscloseOutputV2 { + bytes32 attestationId; + uint256 userIdentifier; + uint256 nullifier; + uint256[4] forbiddenCountriesListPacked; + string issuingState; + string[] name; + string idNumber; + string nationality; + string dateOfBirth; + string gender; + string expiryDate; + uint256 olderThan; + bool[3] ofac; + } + + /** + * @dev Verification configuration structure (Version 1) + * @param olderThanEnabled Whether minimum age verification is enabled + * @param olderThan Minimum age requirement + * @param forbiddenCountriesEnabled Whether forbidden countries check is enabled + * @param forbiddenCountriesListPacked Packed list of forbidden countries (4 uint256 array) + * @param ofacEnabled Array of boolean flags for different OFAC verification modes + */ + struct VerificationConfigV1 { + bool olderThanEnabled; + uint256 olderThan; + bool forbiddenCountriesEnabled; + uint256[4] forbiddenCountriesListPacked; + bool[3] ofacEnabled; + } + + /** + * @dev Verification configuration structure (Version 2) + * @param olderThanEnabled Whether minimum age verification is enabled + * @param olderThan Minimum age requirement + * @param forbiddenCountriesEnabled Whether forbidden countries check is enabled + * @param forbiddenCountriesListPacked Packed list of forbidden countries (4 uint256 array) + * @param ofacEnabled Array of boolean flags for different OFAC verification modes + */ + struct VerificationConfigV2 { + bool olderThanEnabled; + uint256 olderThan; + bool forbiddenCountriesEnabled; + uint256[4] forbiddenCountriesListPacked; + bool[3] ofacEnabled; + } +} diff --git a/contracts/contracts/registry/IdentityRegistryIdCard.sol b/contracts/contracts/registry/IdentityRegistryIdCard.sol deleted file mode 100644 index e41dfda66..000000000 --- a/contracts/contracts/registry/IdentityRegistryIdCard.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -import {ProxyRoot} from "../upgradeable/ProxyRoot.sol"; - -/** - * @title IdentityRegistry - * @notice Acts as an upgradeable proxy for the identity registry. - * @dev Inherits from ProxyRoot to delegate calls to an implementation contract. - * The constructor initializes the proxy using the provided implementation address and initialization data. - */ -contract IdentityRegistryIdCard is ProxyRoot { - /** - * @notice Creates a new instance of the IdentityRegistry proxy. - * @param _logic The address of the initial implementation contract that contains the registry logic. - * @param _data The initialization data passed to the implementation during deployment. - */ - constructor(address _logic, bytes memory _data) ProxyRoot(_logic, _data) {} -} diff --git a/contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol b/contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol index 270270716..068ef2e63 100644 --- a/contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol +++ b/contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol @@ -2,11 +2,8 @@ pragma solidity 0.8.28; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {InternalLeanIMT, LeanIMTData} from "@zk-kit/imt.sol/internal/InternalLeanIMT.sol"; import {IIdentityRegistryIdCardV1} from "../interfaces/IIdentityRegistryIdCardV1.sol"; -import {IIdentityVerificationHubV1} from "../interfaces/IIdentityVerificationHubV1.sol"; import {ImplRoot} from "../upgradeable/ImplRoot.sol"; /** * @notice ⚠️ CRITICAL STORAGE LAYOUT WARNING ⚠️ diff --git a/contracts/contracts/tests/TestCustomVerifier.sol b/contracts/contracts/tests/TestCustomVerifier.sol new file mode 100644 index 000000000..077233905 --- /dev/null +++ b/contracts/contracts/tests/TestCustomVerifier.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {CustomVerifier} from "../libraries/CustomVerifier.sol"; +import {SelfStructs} from "../libraries/SelfStructs.sol"; + +contract TestCustomVerifier { + function testCustomVerify( + bytes32 attestationId, + bytes calldata config, + bytes calldata proofOutput + ) external pure returns (SelfStructs.GenericDiscloseOutputV2 memory) { + return CustomVerifier.customVerify(attestationId, config, proofOutput); + } +} diff --git a/contracts/contracts/tests/TestSelfVerificationRoot.sol b/contracts/contracts/tests/TestSelfVerificationRoot.sol new file mode 100644 index 000000000..59cfb6bc8 --- /dev/null +++ b/contracts/contracts/tests/TestSelfVerificationRoot.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {SelfVerificationRoot} from "../abstract/SelfVerificationRoot.sol"; +import {ISelfVerificationRoot} from "../interfaces/ISelfVerificationRoot.sol"; +import {SelfStructs} from "../libraries/SelfStructs.sol"; + +/** + * @title TestSelfVerificationRoot + * @notice Test implementation of SelfVerificationRoot for testing purposes + * @dev This contract provides a concrete implementation of the abstract SelfVerificationRoot + */ +contract TestSelfVerificationRoot is SelfVerificationRoot { + // Storage for testing purposes + bool public verificationSuccessful; + ISelfVerificationRoot.GenericDiscloseOutputV2 public lastOutput; + bytes public lastUserData; + SelfStructs.VerificationConfigV2 public verificationConfig; + + // Events for testing + event VerificationCompleted(ISelfVerificationRoot.GenericDiscloseOutputV2 output, bytes userData); + + /** + * @notice Constructor for the test contract + * @param identityVerificationHubV2Address The address of the Identity Verification Hub V2 + * @param scopeValue The expected proof scope for user registration + */ + constructor( + address identityVerificationHubV2Address, + uint256 scopeValue + ) SelfVerificationRoot(identityVerificationHubV2Address, scopeValue) {} + + /** + * @notice Implementation of customVerificationHook for testing + * @dev This function is called by onVerificationSuccess after hub address validation + * @param output The verification output from the hub + * @param userData The user data passed through verification + */ + function customVerificationHook( + ISelfVerificationRoot.GenericDiscloseOutputV2 memory output, + bytes memory userData + ) internal override { + verificationSuccessful = true; + lastOutput = output; + lastUserData = userData; + + emit VerificationCompleted(output, userData); + } + + /** + * @notice Reset the test state + */ + function resetTestState() external { + verificationSuccessful = false; + lastOutput = ISelfVerificationRoot.GenericDiscloseOutputV2({ + attestationId: bytes32(0), + userIdentifier: 0, + nullifier: 0, + forbiddenCountriesListPacked: [uint256(0), uint256(0), uint256(0), uint256(0)], + issuingState: "", + name: new string[](3), + idNumber: "", + nationality: "", + dateOfBirth: "", + gender: "", + expiryDate: "", + olderThan: 0, + ofac: [false, false, false] + }); + lastUserData = ""; + } + + /** + * @notice Expose the internal _setScope function for testing + * @param newScope The new scope value to set + */ + function setScope(uint256 newScope) external { + _setScope(newScope); + } + + function setVerificationConfig(SelfStructs.VerificationConfigV2 memory config) external { + verificationConfig = config; + _identityVerificationHubV2.setVerificationConfigV2(verificationConfig); + } + + function getConfigId( + bytes32 destinationChainId, + bytes32 userIdentifier, + bytes memory userDefinedData + ) public view override returns (bytes32) { + return _identityVerificationHubV2.generateConfigId(verificationConfig); + } + + /** + * @notice Test function to simulate calling onVerificationSuccess from hub + * @dev This function is only for testing purposes to verify access control + * @param output The verification output + * @param userData The user data + */ + function testOnVerificationSuccess(bytes memory output, bytes memory userData) external { + // This should fail if called by anyone other than the hub + onVerificationSuccess(output, userData); + } +} diff --git a/contracts/contracts/tests/testGenericFormatter.sol b/contracts/contracts/tests/testGenericFormatter.sol new file mode 100644 index 000000000..3f563a321 --- /dev/null +++ b/contracts/contracts/tests/testGenericFormatter.sol @@ -0,0 +1,34 @@ +import {GenericFormatter} from "../libraries/GenericFormatter.sol"; +import {SelfStructs} from "../libraries/SelfStructs.sol"; + +contract TestGenericFormatter { + function testFromV1Config( + SelfStructs.VerificationConfigV1 memory verificationConfigV1 + ) public pure returns (SelfStructs.VerificationConfigV2 memory verificationConfigV2) { + verificationConfigV2 = GenericFormatter.fromV1Config(verificationConfigV1); + } + + function testVerificationConfigFromBytes( + bytes memory verificationConfig + ) public pure returns (SelfStructs.VerificationConfigV2 memory verificationConfigV2) { + verificationConfigV2 = GenericFormatter.verificationConfigFromBytes(verificationConfig); + } + + function testFormatV1Config( + SelfStructs.VerificationConfigV1 memory verificationConfigV1 + ) public pure returns (bytes memory v1ConfigBytes) { + v1ConfigBytes = GenericFormatter.formatV1Config(verificationConfigV1); + } + + function testFormatV2Config( + SelfStructs.VerificationConfigV2 memory verificationConfigV2 + ) public pure returns (bytes memory v2ConfigBytes) { + v2ConfigBytes = GenericFormatter.formatV2Config(verificationConfigV2); + } + + function testToV2Struct( + SelfStructs.GenericDiscloseOutputV2 memory genericDiscloseOutput + ) public pure returns (bytes memory v2StructBytes) { + v2StructBytes = GenericFormatter.toV2Struct(genericDiscloseOutput); + } +} diff --git a/contracts/contracts/verifiers/disclose/Verifier_vc_and_disclose_id.sol b/contracts/contracts/verifiers/disclose/Verifier_vc_and_disclose_id.sol new file mode 100644 index 000000000..598366bc6 --- /dev/null +++ b/contracts/contracts/verifiers/disclose/Verifier_vc_and_disclose_id.sol @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-3.0 +/* + Copyright 2021 0KIMS association. + + This file is generated with [snarkJS](https://github.com/iden3/snarkjs). + + snarkJS is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + snarkJS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with snarkJS. If not, see . +*/ + +pragma solidity >=0.7.0 <0.9.0; + +contract Verifier_vc_and_disclose_id { + // Scalar field size + uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + // Base field size + uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + + // Verification Key data + uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; + uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; + uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; + uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; + uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; + uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; + uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; + uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; + uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; + uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; + uint256 constant deltax1 = 2570683437117593959871249718321087344182581865653762639494656774741884774451; + uint256 constant deltax2 = 10791937519136459850121173854513919670439026432248975480520108456769523413706; + uint256 constant deltay1 = 7697803293347511746398205466597805067891748159831340108443169903730430911531; + uint256 constant deltay2 = 18135141573537061188590013042324734692899788683249633264832904379088420521347; + + uint256 constant IC0x = 5856920506801943179747940431507261587545690354191837904074746625856713057019; + uint256 constant IC0y = 19124539120756340306225201952668471579555384876400327849356328019845881097562; + + uint256 constant IC1x = 3907275788156399155726133032274445611289536322362606696599801283854580295437; + uint256 constant IC1y = 8451119154682439762054395905067543035497291620054904162598329277934126172016; + + uint256 constant IC2x = 20530143257595175213619797207279919184153764911566159122843961254673243634293; + uint256 constant IC2y = 18418107796075636508766997478881789861884175034155105905934657000306915821371; + + uint256 constant IC3x = 14368654893588239986356440315957545435792265903841511372331944472664329358460; + uint256 constant IC3y = 12284629478683204119754717091716141149657267016652380030058008792997116131875; + + uint256 constant IC4x = 9578716983925369516022217522731093507962466534359837901987460531141004851058; + uint256 constant IC4y = 11546230489007268978353544383968439771367148945013199458278541261408798518042; + + uint256 constant IC5x = 20186291580274548265191299475582935526688657371386630094736889868165148343049; + uint256 constant IC5y = 7066081396404019076294461314754121975461942238116236506003634245369912659348; + + uint256 constant IC6x = 7223725756527208741423329209765674164138947999927552108248321109787428330576; + uint256 constant IC6y = 7090893321878038809726547992284174238790568751222590654054815492845205850020; + + uint256 constant IC7x = 3508039657302366273723082871441943167324729420192561664273405366370025413334; + uint256 constant IC7y = 16077897542007852149081275458028106372577804015189016149401990661491415919989; + + uint256 constant IC8x = 7157834980199389511778623097557341082580034352641045942337042309147987264745; + uint256 constant IC8y = 17810088059705235516956644702714110398594370075197014246657966746880992708168; + + uint256 constant IC9x = 19990085150526235401122450579432100767788242749821689359772693208891467804622; + uint256 constant IC9y = 11875741660249391520213283913162030612995484283095257075118031592533202953731; + + uint256 constant IC10x = 565576411533726770996320843760026133874517147039816053645457725776038253277; + uint256 constant IC10y = 6930421180986466104206189528520482999522362852059930498501019935177194699565; + + uint256 constant IC11x = 9687304248878239799475267106341943076035784248337790140346422230644442528821; + uint256 constant IC11y = 8718390928981091008213508300667652242975655218883879916045519674874973495651; + + uint256 constant IC12x = 13400562939760543038178200762869273415986171711360997974863414188041195677804; + uint256 constant IC12y = 19454142021037427981814241940238985741634162007055597028328858197655005999592; + + uint256 constant IC13x = 5304642595939683424612415509804552638020604037251875803456909825635793998553; + uint256 constant IC13y = 5306882009576422477327808720898870532843294871978759595546305216807124752880; + + uint256 constant IC14x = 14031793532934637725744550192616647697277176739864804433516834701426772096040; + uint256 constant IC14y = 13997965923135752232663850400013330288274429042096588718589372655870427909076; + + uint256 constant IC15x = 6857315285146692182841362377259336559693847336499456322687817740418786750593; + uint256 constant IC15y = 7773075738364850482446135825145951942474724287022442267891210024402400169358; + + uint256 constant IC16x = 7350867218242766859946239631839980088884228896188196079908494306313085242757; + uint256 constant IC16y = 16585312954662800633717122107305570207242746661443177600922110732010586303604; + + uint256 constant IC17x = 12371794706813431625295862613989653271433404490947256703099159689503429758617; + uint256 constant IC17y = 16874395293051993576135801684114190330547607587787157588928779976192005582901; + + uint256 constant IC18x = 18408185524203075886684659649084141997263054479485752795420181339411166689531; + uint256 constant IC18y = 16243204335737707642434624849163560305778796389979434010995242909912410681115; + + uint256 constant IC19x = 12827474512217515366731958666602059443683014227879101851822634933350038305567; + uint256 constant IC19y = 12103285317170015797205692728698593084779876459612203243369112597137507623396; + + uint256 constant IC20x = 21871607573936419852307486960157754714579931787264995102940433544145315016287; + uint256 constant IC20y = 3793515164944941168720752793034269182533154487955578472737823429132294441082; + + uint256 constant IC21x = 694085742582167480921564969992368553233272238548053666297768861621687596406; + uint256 constant IC21y = 19146278969945936933324725088253247909700597465969498560427768702663925772917; + + // Memory data + uint16 constant pVk = 0; + uint16 constant pPairing = 128; + + uint16 constant pLastMem = 896; + + function verifyProof( + uint[2] calldata _pA, + uint[2][2] calldata _pB, + uint[2] calldata _pC, + uint[21] calldata _pubSignals + ) public view returns (bool) { + assembly { + function checkField(v) { + if iszero(lt(v, r)) { + mstore(0, 0) + return(0, 0x20) + } + } + + // G1 function to multiply a G1 value(x,y) to value in an address + function g1_mulAccC(pR, x, y, s) { + let success + let mIn := mload(0x40) + mstore(mIn, x) + mstore(add(mIn, 32), y) + mstore(add(mIn, 64), s) + + success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + + mstore(add(mIn, 64), mload(pR)) + mstore(add(mIn, 96), mload(add(pR, 32))) + + success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + } + + function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { + let _pPairing := add(pMem, pPairing) + let _pVk := add(pMem, pVk) + + mstore(_pVk, IC0x) + mstore(add(_pVk, 32), IC0y) + + // Compute the linear combination vk_x + + g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) + + g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) + + g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64))) + + g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96))) + + g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128))) + + g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160))) + + g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192))) + + g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224))) + + g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256))) + + g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288))) + + g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320))) + + g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352))) + + g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384))) + + g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416))) + + g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448))) + + g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480))) + + g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512))) + + g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544))) + + g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576))) + + g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608))) + + g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640))) + + // -A + mstore(_pPairing, calldataload(pA)) + mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) + + // B + mstore(add(_pPairing, 64), calldataload(pB)) + mstore(add(_pPairing, 96), calldataload(add(pB, 32))) + mstore(add(_pPairing, 128), calldataload(add(pB, 64))) + mstore(add(_pPairing, 160), calldataload(add(pB, 96))) + + // alpha1 + mstore(add(_pPairing, 192), alphax) + mstore(add(_pPairing, 224), alphay) + + // beta2 + mstore(add(_pPairing, 256), betax1) + mstore(add(_pPairing, 288), betax2) + mstore(add(_pPairing, 320), betay1) + mstore(add(_pPairing, 352), betay2) + + // vk_x + mstore(add(_pPairing, 384), mload(add(pMem, pVk))) + mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) + + // gamma2 + mstore(add(_pPairing, 448), gammax1) + mstore(add(_pPairing, 480), gammax2) + mstore(add(_pPairing, 512), gammay1) + mstore(add(_pPairing, 544), gammay2) + + // C + mstore(add(_pPairing, 576), calldataload(pC)) + mstore(add(_pPairing, 608), calldataload(add(pC, 32))) + + // delta2 + mstore(add(_pPairing, 640), deltax1) + mstore(add(_pPairing, 672), deltax2) + mstore(add(_pPairing, 704), deltay1) + mstore(add(_pPairing, 736), deltay2) + + let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) + + isOk := and(success, mload(_pPairing)) + } + + let pMem := mload(0x40) + mstore(0x40, add(pMem, pLastMem)) + + // Validate that all evaluations ∈ F + + checkField(calldataload(add(_pubSignals, 0))) + + checkField(calldataload(add(_pubSignals, 32))) + + checkField(calldataload(add(_pubSignals, 64))) + + checkField(calldataload(add(_pubSignals, 96))) + + checkField(calldataload(add(_pubSignals, 128))) + + checkField(calldataload(add(_pubSignals, 160))) + + checkField(calldataload(add(_pubSignals, 192))) + + checkField(calldataload(add(_pubSignals, 224))) + + checkField(calldataload(add(_pubSignals, 256))) + + checkField(calldataload(add(_pubSignals, 288))) + + checkField(calldataload(add(_pubSignals, 320))) + + checkField(calldataload(add(_pubSignals, 352))) + + checkField(calldataload(add(_pubSignals, 384))) + + checkField(calldataload(add(_pubSignals, 416))) + + checkField(calldataload(add(_pubSignals, 448))) + + checkField(calldataload(add(_pubSignals, 480))) + + checkField(calldataload(add(_pubSignals, 512))) + + checkField(calldataload(add(_pubSignals, 544))) + + checkField(calldataload(add(_pubSignals, 576))) + + checkField(calldataload(add(_pubSignals, 608))) + + checkField(calldataload(add(_pubSignals, 640))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/contracts/verifiers/register_id/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096.sol b/contracts/contracts/verifiers/register_id/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096.sol index 37e0e0026..50d7b9f92 100644 --- a/contracts/contracts/verifiers/register_id/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096.sol +++ b/contracts/contracts/verifiers/register_id/Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096.sol @@ -22,17 +22,17 @@ pragma solidity >=0.7.0 <0.9.0; contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { // Scalar field size - uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Base field size - uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // Verification Key data - uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; - uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; - uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; - uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; - uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; - uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; + uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; + uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; + uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; + uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; + uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; + uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; @@ -42,27 +42,30 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { uint256 constant deltay1 = 17093903636529404715977441649383548797208493053670591927268936136905628890632; uint256 constant deltay2 = 4972965029582644081071578284460620299080512423640837516215418184958287485742; - uint256 constant IC0x = 10355093401382030671225395655869217898600304666279529568537338332467402365304; uint256 constant IC0y = 4965486376320532678254373789150183805614443765077280090063627634214290673841; - + uint256 constant IC1x = 15499415295419376168702866885907180620949913073936284071089537160198730049399; uint256 constant IC1y = 9281988302763410034273237781396743554700695834575740098855226007996985888530; - + uint256 constant IC2x = 14098031970434182418452511377672297745474345532972352145312731453903292311930; uint256 constant IC2y = 5496357494362502413877905425401698232434560336945612609023708765434745421701; - + uint256 constant IC3x = 6540495825150439480926083011463382216384205445522489211977434270583326380648; uint256 constant IC3y = 4164688383627561794431395614711252825194458846441353030452544157419373614848; - - + // Memory data uint16 constant pVk = 0; uint16 constant pPairing = 128; uint16 constant pLastMem = 896; - function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[3] calldata _pubSignals) public view returns (bool) { + function verifyProof( + uint[2] calldata _pA, + uint[2][2] calldata _pB, + uint[2] calldata _pC, + uint[3] calldata _pubSignals + ) public view returns (bool) { assembly { function checkField(v) { if iszero(lt(v, r)) { @@ -70,7 +73,7 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { return(0, 0x20) } } - + // G1 function to multiply a G1 value(x,y) to value in an address function g1_mulAccC(pR, x, y, s) { let success @@ -105,13 +108,12 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { mstore(add(_pVk, 32), IC0y) // Compute the linear combination vk_x - + g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) - + g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) - + g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64))) - // -A mstore(_pPairing, calldataload(pA)) @@ -137,7 +139,6 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { mstore(add(_pPairing, 384), mload(add(pMem, pVk))) mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) - // gamma2 mstore(add(_pPairing, 448), gammax1) mstore(add(_pPairing, 480), gammax2) @@ -154,7 +155,6 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { mstore(add(_pPairing, 704), deltay1) mstore(add(_pPairing, 736), deltay2) - let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) isOk := and(success, mload(_pPairing)) @@ -164,19 +164,18 @@ contract Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 { mstore(0x40, add(pMem, pLastMem)) // Validate that all evaluations ∈ F - + checkField(calldataload(add(_pubSignals, 0))) - + checkField(calldataload(add(_pubSignals, 32))) - + checkField(calldataload(add(_pubSignals, 64))) - // Validate all evaluations let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) mstore(0, isValid) - return(0, 0x20) - } - } - } + return(0, 0x20) + } + } +} diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 9f50c7802..d28342d2f 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -1,7 +1,7 @@ import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; require("dotenv").config({ - path: process.env.CI ? ".env.test" : ".env" + path: process.env.CI ? ".env.test" : ".env", }); import "hardhat-contract-sizer"; import "@nomicfoundation/hardhat-ignition-ethers"; @@ -16,14 +16,10 @@ const config: HardhatUserConfig = { optimizer: { enabled: true, runs: 200, - details: { - yul: true, - }, }, metadata: { bytecodeHash: "none", }, - viaIR: false, }, }, contractSizer: { @@ -58,32 +54,36 @@ const config: HardhatUserConfig = { celo: { chainId: 42220, url: process.env.CELO_RPC_URL || "https://forno.celo.org", - accounts: [process.env.CELO_KEY as string], + accounts: [process.env.PRIVATE_KEY as string], }, - celoAlfajores: { + alfajores: { chainId: 44787, url: process.env.CELO_ALFAJORES_RPC_URL || "https://alfajores-forno.celo-testnet.org", accounts: [process.env.PRIVATE_KEY as string], }, - celoBaklava: { - chainId: 62320, - url: process.env.CELO_BAKLAVA_RPC_URL || "https://baklava-forno.celo-testnet.org", - accounts: [process.env.PRIVATE_KEY as string], - }, }, etherscan: { apiKey: { sepolia: process.env.ETHERSCAN_API_KEY as string, ethereum: process.env.ETHERSCAN_API_KEY as string, celo: process.env.CELOSCAN_API_KEY as string, + alfajores: process.env.CELOSCAN_API_KEY as string, }, customChains: [ { network: "celo", chainId: 42220, urls: { - apiURL: "https://api.celoscan.io/api", - browserURL: "https://celoscan.io", + apiURL: "https://api.etherscan.io/v2/api?chainid=42220", + browserURL: "https://celoscan.io/", + }, + }, + { + network: "alfajores", + chainId: 44787, + urls: { + apiURL: "https://api.etherscan.io/v2/api?chainid=44787", + browserURL: "https://alfajores.celoscan.io", }, }, ], diff --git a/contracts/ignition/modules/deployTestSelfVerificationRoot.ts b/contracts/ignition/modules/deployTestSelfVerificationRoot.ts new file mode 100644 index 000000000..61d0cf753 --- /dev/null +++ b/contracts/ignition/modules/deployTestSelfVerificationRoot.ts @@ -0,0 +1,34 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +/** + * TestSelfVerificationRoot Deployment Module + * + * Deploys the TestSelfVerificationRoot contract for testing self-verification functionality. + * + * USAGE: + * npx hardhat ignition deploy ignition/modules/deployTestSelfVerificationRoot.ts --network alfajores --verify + * + * VERIFICATION: + * npx hardhat verify 0x3e2487a250e2A7b56c7ef5307Fb591Cc8C83623D 12345 --network alfajores + * + * PARAMETERS: + * - identityVerificationHubV2Address: Hub V2 contract address (default: 0x3e2487a250e2A7b56c7ef5307Fb591Cc8C83623D) + * - scopeValue: Proof scope value (default: 12345 - TEMPORARY VALUE, you have to calculate it yourself after getting the address and called setScopeValue) + */ + +export default buildModule("DeployTestSelfVerificationRoot", (m) => { + const identityVerificationHubV2Address = m.getParameter( + "identityVerificationHubV2Address", + "0x3e2487a250e2A7b56c7ef5307Fb591Cc8C83623D", + ); + const scopeValue = m.getParameter("scopeValue", 12345); + + const testSelfVerificationRoot = m.contract("TestSelfVerificationRoot", [ + identityVerificationHubV2Address, + scopeValue, + ]); + + return { + testSelfVerificationRoot, + }; +}); diff --git a/contracts/ignition/modules/hub/deployHub.ts b/contracts/ignition/modules/hub/deployHub.ts index b8747d6e4..cbdee499c 100644 --- a/contracts/ignition/modules/hub/deployHub.ts +++ b/contracts/ignition/modules/hub/deployHub.ts @@ -18,14 +18,7 @@ export default buildModule("DeployHubV1", (m) => { const identityVerificationHubImplV1 = m.contract("IdentityVerificationHubImplV1"); const hubInterface = getHubInitializeData(); - const initializeData = hubInterface.encodeFunctionData("initialize", [ - "", - "", - [], - [], - [], - [], - ]); + const initializeData = hubInterface.encodeFunctionData("initialize", ["", "", [], [], [], []]); // Deploy proxy with V1 implementation const hubV1 = m.contract("IdentityVerificationHub", [identityVerificationHubImplV1, initializeData]); diff --git a/contracts/ignition/modules/verifiers/deployAllVerifiers.ts b/contracts/ignition/modules/verifiers/deployAllVerifiers.ts index 1cca736a7..cae65f8f3 100644 --- a/contracts/ignition/modules/verifiers/deployAllVerifiers.ts +++ b/contracts/ignition/modules/verifiers/deployAllVerifiers.ts @@ -7,7 +7,7 @@ import * as path from "path"; * Get enum keys (circuit names) excluding numeric values */ function getEnumKeys>(enumObject: T): string[] { - return Object.keys(enumObject).filter(key => isNaN(Number(key))); + return Object.keys(enumObject).filter((key) => isNaN(Number(key))); } /** @@ -22,7 +22,7 @@ function contractExists(contractName: string): boolean { path.join(contractsDir, "verifiers", `${contractName}.sol`), ]; - return possiblePaths.some(filePath => fs.existsSync(filePath)); + return possiblePaths.some((filePath) => fs.existsSync(filePath)); } export default buildModule("DeployAllVerifiers", (m) => { @@ -64,8 +64,12 @@ export default buildModule("DeployAllVerifiers", (m) => { console.log(`Total verifiers deployment summary:`); console.log(` - VC and Disclose: 1`); - console.log(` - Register: ${successfulRegisterDeployments}/${registerCircuits.length} (${registerCircuits.length - successfulRegisterDeployments} skipped)`); - console.log(` - DSC: ${successfulDscDeployments}/${dscCircuits.length} (${dscCircuits.length - successfulDscDeployments} skipped)`); + console.log( + ` - Register: ${successfulRegisterDeployments}/${registerCircuits.length} (${registerCircuits.length - successfulRegisterDeployments} skipped)`, + ); + console.log( + ` - DSC: ${successfulDscDeployments}/${dscCircuits.length} (${dscCircuits.length - successfulDscDeployments} skipped)`, + ); console.log(` - Total successful deployments: ${1 + successfulRegisterDeployments + successfulDscDeployments}`); return deployedContracts; diff --git a/contracts/package.json b/contracts/package.json index 255232583..80d35f2b0 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -15,15 +15,15 @@ "contracts/abstract/*" ], "scripts": { - "build": "npx hardhat clean && npx hardhat compile", + "build": "yarn hardhat clean && yarn hardhat compile", "deploy:all": "npm run deploy:verifiers:all && npm run deploy:registry && npm run deploy:registry:idcard && npm run deploy:hub:v2", - "deploy:hub": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/hub/deployHub.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:hub:v2": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/hub/deployHubV2.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:pcr0": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/utils/deployPCR0.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:registry": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/registry/deployRegistry.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:registry:idcard": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/registry/deployIdCardRegistry.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:verifiers": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/verifiers/deployVerifiers.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "deploy:verifiers:all": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/verifiers/deployAllVerifiers.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:hub": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/hub/deployHub.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:hub:v2": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/hub/deployHubV2.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:pcr0": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/utils/deployPCR0.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:registry": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/registry/deployRegistry.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:registry:idcard": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/registry/deployIdCardRegistry.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:verifiers": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/verifiers/deployVerifiers.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "deploy:verifiers:all": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/verifiers/deployAllVerifiers.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", "export-prod": "bash ./scripts/prod.sh", "prettier:check": "prettier --list-different '**/*.{json,md,yml,sol,ts}'", "prettier:write": "prettier --write '**/*.{json,md,yml,sol,ts}'", @@ -31,32 +31,33 @@ "set:hub:v2": "npx dotenv-cli -- bash -c 'NETWORK=${NETWORK:-staging} npx ts-node scripts/setHubV2.ts'", "set:registry": "npx dotenv-cli -- bash -c 'NETWORK=${NETWORK:-staging} npx ts-node scripts/setRegistry.ts'", "set:registry:idcard": "npx dotenv-cli -- bash -c 'NETWORK=${NETWORK:-staging} npx ts-node scripts/setRegistryId.ts'", - "test": "npx hardhat test", + "test": "yarn hardhat test", "test:airdrop": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/example/airdrop.test.ts'", "test:attribute": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/CircuitAttributeHandler.test.ts'", - "test:coverage": "npx hardhat coverage", - "test:coverage:local": "TEST_ENV=local npx hardhat coverage", - "test:disclose": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/integration/vcAndDisclose.test.ts'", - "test:endtoend": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/Integration/endToEnd.test.ts'", - "test:example": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/example/*'", - "test:formatter": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/formatter.test.ts'", - "test:hub": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/IdentityVerificationHub.test.ts'", - "test:integration": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/integration/*'", - "test:local": "TEST_ENV=local npx hardhat test", - "test:pcr": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/PCR0Manager.test.ts'", - "test:register": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/integration/commitmentRegistration.test.ts'", - "test:registry": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/IdentityRegistry.test.ts'", - "test:sdkcore": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/sdk/sdkCore.test.ts --network localhost'", - "test:unit": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/unit/*'", - "test:verifyall": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} npx hardhat test test/integration/verifyAll.test.ts'", - "test:view": "npx hardhat test test/view.ts", + "test:coverage": "yarn hardhat coverage", + "test:coverage:local": "TEST_ENV=local yarn hardhat coverage", + "test:disclose": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/integration/vcAndDisclose.test.ts'", + "test:endtoend": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/Integration/endToEnd.test.ts'", + "test:example": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/example/*'", + "test:formatter": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/unit/formatter.test.ts'", + "test:hub": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/unit/IdentityVerificationHub.test.ts'", + "test:integration": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/integration/*'", + "test:local": "TEST_ENV=local yarn hardhat test", + "test:pcr": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/unit/PCR0Manager.test.ts'", + "test:register": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/integration/commitmentRegistration.test.ts'", + "test:registry": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/unit/IdentityRegistry.test.ts'", + "test:sdkcore": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/sdk/sdkCore.test.ts --network localhost'", + "test:unit": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/unit/*'", + "test:verifyall": "npx dotenv-cli -- bash -c 'TEST_ENV=${TEST_ENV:-local} yarn hardhat test test/integration/verifyAll.test.ts'", + "test:view": "yarn hardhat test test/view.ts", + "test:v2": "npx hardhat test test/v2/selfVerificationFlow.test.ts --network localhost", "types": "tsc -noEmit", - "update:cscaroot": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/scripts/updateRegistryCscaRoot.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "update:cscaroot": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/scripts/updateRegistryCscaRoot.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", "update:hub": "npx dotenv-cli -- bash -c 'NETWORK=${NETWORK:-staging} npx ts-node scripts/setRegistry.ts'", - "update:ofacroot": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/scripts/updateRegistryOfacRoot.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "update:pcr0": "npx dotenv-cli -- bash -c 'PCR0_ACTION=${PCR0_ACTION:-add} PCR0_KEY=${PCR0_KEY} npx hardhat ignition deploy ignition/modules/scripts/updatePCR0.ts --network ${NETWORK:-localhost} --reset'", - "upgrade:hub": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/upgrade/deployNewHubAndUpgrade.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", - "upgrade:registry": "npx dotenv-cli -- bash -c 'npx hardhat ignition deploy ignition/modules/upgrade/deployNewRegistryAndUpgrade.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'" + "update:ofacroot": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/scripts/updateRegistryOfacRoot.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "update:pcr0": "npx dotenv-cli -- bash -c 'PCR0_ACTION=${PCR0_ACTION:-add} PCR0_KEY=${PCR0_KEY} yarn hardhat ignition deploy ignition/modules/scripts/updatePCR0.ts --network ${NETWORK:-localhost} --reset'", + "upgrade:hub": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/upgrade/deployNewHubAndUpgrade.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'", + "upgrade:registry": "npx dotenv-cli -- bash -c 'yarn hardhat ignition deploy ignition/modules/upgrade/deployNewRegistryAndUpgrade.ts --network ${NETWORK:-localhost} ${VERIFY:+--verify}'" }, "dependencies": { "@ashpect/smt": "https://github.com/ashpect/smt#main", @@ -108,5 +109,6 @@ "ts-node": "^10.9.1", "typechain": "^8.3.2", "typescript": "^5.1.6" - } + }, + "packageManager": "yarn@4.5.3" } diff --git a/contracts/scripts/README.md b/contracts/scripts/README.md new file mode 100644 index 000000000..603ee45ab --- /dev/null +++ b/contracts/scripts/README.md @@ -0,0 +1,153 @@ +# Scripts Directory + +This directory contains utility scripts for the Self contracts project. + +## Available Scripts + +### Test Scripts (`test.sh`) + +Run various types of tests for the contracts. + +```bash +# Show all available test commands +./scripts/test.sh help + +# Run V2 verification flow tests +./scripts/test.sh v2 + +# Run all contract tests +./scripts/test.sh all + +# Run unit tests +./scripts/test.sh unit + +# Run integration tests +./scripts/test.sh integration + +# Run test coverage +./scripts/test.sh coverage + +# Run specific test types +./scripts/test.sh airdrop +./scripts/test.sh attribute +./scripts/test.sh formatter +./scripts/test.sh hub +./scripts/test.sh registry +./scripts/test.sh sdk + +# Clean test artifacts +./scripts/test.sh clean +``` + +### Development Scripts (`dev.sh`) + +Development and deployment utilities. + +```bash +# Show all available development commands +./scripts/dev.sh help + +# Start local Hardhat node +./scripts/dev.sh node + +# Compile contracts +./scripts/dev.sh build + +# Clean build artifacts +./scripts/dev.sh clean + +# Check contract sizes +./scripts/dev.sh size + +# Deploy contracts +./scripts/dev.sh deploy +./scripts/dev.sh deploy:hub +./scripts/dev.sh deploy:hub:v2 +./scripts/dev.sh deploy:registry + +# Open Hardhat console +./scripts/dev.sh console +``` + +## Usage Examples + +### Quick Test Workflow + +```bash +# Navigate to contracts directory +cd contracts + +# Run V2 tests +./scripts/test.sh v2 + +# If tests fail, check build +./scripts/dev.sh build + +# Run coverage to see test completeness +./scripts/test.sh coverage +``` + +### Development Workflow + +```bash +# Start local development node (in terminal 1) +./scripts/dev.sh node + +# In another terminal, deploy contracts +./scripts/dev.sh deploy:hub:v2 + +# Run tests against local node +./scripts/test.sh integration +``` + +## Script Features + +- **Colored Output**: Scripts provide colored status messages for better readability +- **Error Handling**: Scripts will exit on errors and provide meaningful error messages +- **Path Detection**: Scripts automatically detect if you're running from `contracts/` or `contracts/scripts/` +- **Environment Variables**: Test scripts automatically set appropriate environment variables + +## Running from Different Directories + +The scripts are smart about directory detection: + +```bash +# From contracts directory +./scripts/test.sh v2 + +# From contracts/scripts directory +./test.sh v2 + +# Both will work correctly +``` + +## Troubleshooting + +### Script Permission Issues + +If you get permission denied errors: + +```bash +chmod +x scripts/test.sh scripts/dev.sh +``` + +### "hardhat.config.ts not found" Error + +This means the script couldn't find the Hardhat configuration. Make sure you're running from: + +- The `contracts/` directory, or +- The `contracts/scripts/` directory + +### Yarn 4 Workspace Issues + +If you encounter Yarn workspace issues, these scripts are designed to work directly with `npx hardhat` to avoid the +workspace complexities. + +## Integration with Package.json + +The scripts complement the existing `package.json` scripts: + +- Package.json scripts: Can be run from anywhere using `yarn` commands +- Shell scripts: Run directly from contracts directory, providing more control and better output + +Choose the approach that works best for your workflow! diff --git a/contracts/scripts/dev.sh b/contracts/scripts/dev.sh new file mode 100755 index 000000000..2d4271ef9 --- /dev/null +++ b/contracts/scripts/dev.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# Development script for Self contracts +# Usage: ./scripts/dev.sh [command] + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to show help +show_help() { + echo "Self Contracts Development Tools" + echo "" + echo "Usage: ./scripts/dev.sh [command]" + echo "" + echo "Commands:" + echo " node Start local Hardhat node" + echo " build Compile contracts" + echo " clean Clean build artifacts" + echo " size Check contract sizes" + echo " deploy Deploy all contracts" + echo " deploy:hub Deploy hub contracts" + echo " deploy:hub:v2 Deploy hub V2 contracts" + echo " deploy:registry Deploy registry contracts" + echo " console Open Hardhat console" + echo " help Show this help message" + echo "" + echo "Examples:" + echo " ./scripts/dev.sh node" + echo " ./scripts/dev.sh build" + echo " ./scripts/dev.sh deploy:hub:v2" + echo "" +} + +# Function to run development commands +run_dev_command() { + local command=$1 + + case $command in + "node") + print_status "Starting Hardhat node..." + npx hardhat node + ;; + "build") + print_status "Compiling contracts..." + npx hardhat clean + npx hardhat compile + print_success "Contracts compiled successfully" + ;; + "clean") + print_status "Cleaning build artifacts..." + npx hardhat clean + rm -rf cache/ + rm -rf artifacts/ + rm -rf typechain-types/ + print_success "Build artifacts cleaned" + ;; + "size") + print_status "Checking contract sizes..." + npx hardhat compile + npx hardhat size-contracts + ;; + "deploy") + print_status "Deploying all contracts..." + npm run deploy:all + print_success "All contracts deployed" + ;; + "deploy:hub") + print_status "Deploying hub contracts..." + npm run deploy:hub + print_success "Hub contracts deployed" + ;; + "deploy:hub:v2") + print_status "Deploying hub V2 contracts..." + npm run deploy:hub:v2 + print_success "Hub V2 contracts deployed" + ;; + "deploy:registry") + print_status "Deploying registry contracts..." + npm run deploy:registry + print_success "Registry contracts deployed" + ;; + "console") + print_status "Opening Hardhat console..." + npx hardhat console + ;; + *) + print_error "Unknown command: $command" + show_help + exit 1 + ;; + esac +} + +# Main execution +main() { + # Change to contracts directory if not already there + if [[ ! -f "hardhat.config.ts" ]]; then + if [[ -f "../hardhat.config.ts" ]]; then + cd .. + else + print_error "Cannot find hardhat.config.ts. Please run from contracts directory or contracts/scripts directory." + exit 1 + fi + fi + + case ${1:-help} in + "help"|"--help"|"-h") + show_help + ;; + *) + run_dev_command $1 + ;; + esac +} + +# Run main function with all arguments +main "$@" diff --git a/contracts/scripts/setHubV2.ts b/contracts/scripts/setHubV2.ts index e35e32b56..1138da559 100644 --- a/contracts/scripts/setHubV2.ts +++ b/contracts/scripts/setHubV2.ts @@ -13,9 +13,9 @@ const PRIVATE_KEY = process.env.CELO_KEY; // Network to Chain ID mapping const NETWORK_TO_CHAIN_ID: Record = { - "localhost": "31337", - "celoAlfajores": "44787", - "celo": "42220", + localhost: "31337", + celoAlfajores: "44787", + celo: "42220", }; // Get chain ID from network name @@ -34,7 +34,10 @@ const AttestationId = { // Dynamic paths based on chain ID const deployedAddressesPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/deployed_addresses.json`); -const contractAbiPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployHubV2#IdentityVerificationHubImplV2.json`); +const contractAbiPath = path.join( + __dirname, + `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployHubV2#IdentityVerificationHubImplV2.json`, +); // Debug logs for paths and files console.log("Network:", NETWORK); @@ -222,7 +225,7 @@ try { } } -main().catch((error) => { + main().catch((error) => { console.error("Execution error:", error); process.exitCode = 1; }); diff --git a/contracts/scripts/setRegistry.ts b/contracts/scripts/setRegistry.ts index 821883524..ebddb0b79 100644 --- a/contracts/scripts/setRegistry.ts +++ b/contracts/scripts/setRegistry.ts @@ -16,9 +16,9 @@ const CSCA_ROOT = process.env.CSCA_ROOT; // Allow manual CSCA root setting // Network to Chain ID mapping const NETWORK_TO_CHAIN_ID: Record = { - "localhost": "31337", - "celoAlfajores": "44787", - "celo": "42220", + localhost: "31337", + celoAlfajores: "44787", + celo: "42220", }; // Get chain ID from network name @@ -30,7 +30,10 @@ const CHAIN_ID = getChainId(NETWORK); // Dynamic paths based on chain ID const deployedAddressesPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/deployed_addresses.json`); -const contractAbiPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployRegistryModule#IdentityRegistryImplV1.json`); +const contractAbiPath = path.join( + __dirname, + `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployRegistryModule#IdentityRegistryImplV1.json`, +); // Debug logs for paths and files console.log("Network:", NETWORK); diff --git a/contracts/scripts/setRegistryId.ts b/contracts/scripts/setRegistryId.ts index bc7d9d295..47193e7ca 100644 --- a/contracts/scripts/setRegistryId.ts +++ b/contracts/scripts/setRegistryId.ts @@ -16,9 +16,9 @@ const CSCA_ROOT = process.env.CSCA_ROOT; // Allow manual CSCA root setting // Network to Chain ID mapping const NETWORK_TO_CHAIN_ID: Record = { - "localhost": "31337", - "celoAlfajores": "44787", - "celo": "42220", + localhost: "31337", + celoAlfajores: "44787", + celo: "42220", }; // Get chain ID from network name @@ -30,7 +30,10 @@ const CHAIN_ID = getChainId(NETWORK); // Dynamic paths based on chain ID const deployedAddressesPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/deployed_addresses.json`); -const contractAbiPath = path.join(__dirname, `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployIdCardRegistryModule#IdentityRegistryIdCardImplV1.json`); +const contractAbiPath = path.join( + __dirname, + `../ignition/deployments/chain-${CHAIN_ID}/artifacts/DeployIdCardRegistryModule#IdentityRegistryIdCardImplV1.json`, +); // Debug logs for paths and files console.log("Network:", NETWORK); @@ -83,7 +86,11 @@ try { throw new Error("Hub address not found in deployed_addresses.json"); } - const identityRegistryIdCard = new ethers.Contract(registryIdCardAddress as string, identityRegistryIdCardAbi, wallet); + const identityRegistryIdCard = new ethers.Contract( + registryIdCardAddress as string, + identityRegistryIdCardAbi, + wallet, + ); console.log("Registry ID Card contract instance created"); // Update hub address diff --git a/contracts/scripts/test.sh b/contracts/scripts/test.sh new file mode 100755 index 000000000..29c89066a --- /dev/null +++ b/contracts/scripts/test.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +# Test execution script for Self contracts +# Usage: ./scripts/test.sh [test-type] + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to show help +show_help() { + echo "Self Contracts Test Runner" + echo "" + echo "Usage: ./scripts/test.sh [command]" + echo "" + echo "Commands:" + echo " all Run all contract tests" + echo "" + echo "V2 Tests (Individual):" + echo " v2-disclose-passport Run V2 passport disclosure tests" + echo " v2-disclose-id Run V2 ID disclosure tests" + echo " v2-register-id Run V2 ID registration tests" + echo " v2-register-passport Run V2 passport registration tests" + echo " v2-hub-other Run V2 hub other functionality tests" + echo "" + echo "V2 Tests (Groups):" + echo " v2-disclose Run all V2 disclosure tests" + echo " v2-register Run all V2 registration tests" + echo " v2-all Run all V2 tests" + echo "" + echo "Legacy Tests:" + echo " unit Run unit tests" + echo " integration Run integration tests" + echo " coverage Run test coverage" + echo " airdrop Run airdrop tests" + echo " attribute Run attribute handler tests" + echo " formatter Run formatter tests" + echo " hub Run hub tests" + echo " registry Run registry tests" + echo " sdk Run SDK core tests" + echo "" + echo "Utilities:" + echo " clean Clean test artifacts" + echo " help Show this help message" + echo "" + echo "Examples:" + echo " ./scripts/test.sh v2-disclose-passport" + echo " ./scripts/test.sh v2-register-id" + echo " ./scripts/test.sh v2-all" + echo " ./scripts/test.sh coverage" + echo "" +} + +# Function to run tests +run_test() { + local test_type=$1 + print_status "Running $test_type tests..." + + case $test_type in + "all") + npx hardhat test + ;; + # V2 Individual Tests + "v2-disclose-passport") + npx hardhat test test/v2/disclosePassport.test.ts --network localhost + ;; + "v2-disclose-id") + npx hardhat test test/v2/discloseId.test.ts --network localhost + ;; + "v2-register-id") + npx hardhat test test/v2/registerId.test.ts --network localhost + ;; + "v2-register-passport") + npx hardhat test test/v2/registerPassport.test.ts --network localhost + ;; + "v2-hub-other") + npx hardhat test test/v2/hubOther.test.ts --network localhost + ;; + # V2 Group Tests + "v2-disclose") + npx hardhat test test/v2/disclosePassport.test.ts test/v2/discloseId.test.ts --network localhost + ;; + "v2-register") + npx hardhat test test/v2/registerId.test.ts test/v2/registerPassport.test.ts --network localhost + ;; + "v2-all") + npx hardhat test test/v2/ --network localhost + ;; + # Legacy Tests + "unit") + TEST_ENV=local npx hardhat test test/unit/* + ;; + "integration") + TEST_ENV=local npx hardhat test test/integration/* + ;; + "coverage") + npx hardhat coverage + ;; + "airdrop") + TEST_ENV=local npx hardhat test test/example/airdrop.test.ts + ;; + "attribute") + TEST_ENV=local npx hardhat test test/unit/CircuitAttributeHandler.test.ts + ;; + "formatter") + TEST_ENV=local npx hardhat test test/unit/formatter.test.ts + ;; + "hub") + TEST_ENV=local npx hardhat test test/unit/IdentityVerificationHub.test.ts + ;; + "registry") + TEST_ENV=local npx hardhat test test/unit/IdentityRegistry.test.ts + ;; + "sdk") + TEST_ENV=local npx hardhat test test/sdk/sdkCore.test.ts --network localhost + ;; + *) + print_error "Unknown test type: $test_type" + show_help + exit 1 + ;; + esac +} + +# Function to clean test artifacts +clean_tests() { + print_status "Cleaning test artifacts..." + rm -rf cache/ + rm -rf artifacts/ + rm -rf typechain-types/ + rm -rf coverage/ + rm -rf coverage.json + print_success "Test artifacts cleaned" +} + +# Main execution +main() { + # Change to contracts directory if not already there + if [[ ! -f "hardhat.config.ts" ]]; then + if [[ -f "../hardhat.config.ts" ]]; then + cd .. + else + print_error "Cannot find hardhat.config.ts. Please run from contracts directory or contracts/scripts directory." + exit 1 + fi + fi + + case ${1:-help} in + "clean") + clean_tests + ;; + "help"|"--help"|"-h") + show_help + ;; + *) + run_test $1 + print_success "$1 tests completed" + ;; + esac +} + +# Run main function with all arguments +main "$@" diff --git a/contracts/test/example/airdrop.test.ts b/contracts/test/example/airdrop.test.ts index f9685f87f..3ef303a20 100644 --- a/contracts/test/example/airdrop.test.ts +++ b/contracts/test/example/airdrop.test.ts @@ -32,7 +32,7 @@ describe("Airdrop", () => { before(async () => { deployedActors = await deploySystemFixtures(); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); registerSecret = generateRandomFieldElement(); nullifier = generateRandomFieldElement(); attestationIds = [BigInt(ATTESTATION_ID.E_PASSPORT)]; @@ -74,15 +74,13 @@ describe("Airdrop", () => { ); const airdropFactory = await ethers.getContractFactory("Airdrop"); - airdrop = await airdropFactory - .connect(deployedActors.owner) - .deploy( - deployedActors.hub.target, - hashEndpointWithScope("https://test.com", "test-scope"), - 0, // the types show we need a contract version here - attestationIds, - token.target, - ); + airdrop = await airdropFactory.connect(deployedActors.owner).deploy( + deployedActors.hub.target, + hashEndpointWithScope("https://test.com", "test-scope"), + 0, // the types show we need a contract version here + attestationIds, + token.target, + ); await airdrop.waitForDeployment(); const verificationConfig = { @@ -275,7 +273,6 @@ describe("Airdrop", () => { }); it("should not able to register address by user if attestation id is invalid", async () => { - const { registry, owner, user1 } = deployedActors; const invalidCommitment = generateCommitment( @@ -290,7 +287,7 @@ describe("Airdrop", () => { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); const invalidImt = new LeanIMT(hashFunction); await invalidImt.insert(BigInt(commitment)); await invalidImt.insert(BigInt(invalidCommitment)); @@ -352,7 +349,7 @@ describe("Airdrop", () => { const airdropFactory = await ethers.getContractFactory("Airdrop"); const newAirdrop = await airdropFactory .connect(owner) - .deploy(hub.target, hashEndpointWithScope("https://test.com", "test-scope"),0, attestationIds, token.target); + .deploy(hub.target, hashEndpointWithScope("https://test.com", "test-scope"), 0, attestationIds, token.target); await newAirdrop.waitForDeployment(); const verificationConfig = { diff --git a/contracts/test/integration/commitmentRegistration.test.ts b/contracts/test/integration/commitmentRegistration.test.ts index 975c57131..1301bb8ed 100644 --- a/contracts/test/integration/commitmentRegistration.test.ts +++ b/contracts/test/integration/commitmentRegistration.test.ts @@ -5,8 +5,8 @@ import { poseidon2 } from "poseidon-lite"; import { CIRCUIT_CONSTANTS, DscVerifierId, RegisterVerifierId } from "@selfxyz/common/constants/constants"; import { ATTESTATION_ID } from "../utils/constants"; import { deploySystemFixtures } from "../utils/deployment"; -import { generateDscProof, generateRegisterProof } from "../utils/generateProof.js"; -import serialized_dsc_tree from "../utils/pubkeys/serialized_dsc_tree.json"; +import { generateDscProof, generateRegisterProof } from "../utils/generateProof"; +import serialized_dsc_tree from "../../../common/pubkeys/serialized_dsc_tree.json"; import { DeployedActors } from "../utils/types"; import { generateRandomFieldElement } from "../utils/utils"; @@ -59,7 +59,7 @@ describe("Commitment Registration Tests", function () { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); const imt = new LeanIMT(hashFunction); await imt.insert(BigInt(dscProof.pubSignals[CIRCUIT_CONSTANTS.DSC_TREE_LEAF_INDEX])); @@ -243,7 +243,7 @@ describe("Commitment Registration Tests", function () { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); const imt = new LeanIMT(hashFunction); await imt.insert(BigInt(registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_COMMITMENT_INDEX])); diff --git a/contracts/test/integration/endToEnd.test.ts b/contracts/test/integration/endToEnd.test.ts index 4985125fc..7cf10c1f3 100644 --- a/contracts/test/integration/endToEnd.test.ts +++ b/contracts/test/integration/endToEnd.test.ts @@ -1,4 +1,3 @@ - import { expect } from "chai"; import { BigNumberish, TransactionReceipt } from "ethers"; import { ethers } from "hardhat"; @@ -10,8 +9,9 @@ import { ATTESTATION_ID } from "../utils/constants"; import { deploySystemFixtures } from "../utils/deployment"; import BalanceTree from "../utils/example/balance-tree"; import { Formatter } from "../utils/formatter"; -import { generateDscProof, generateRegisterProof, generateVcAndDiscloseProof } from "../utils/generateProof.js"; -import serialized_dsc_tree from "../utils/pubkeys/serialized_dsc_tree.json"; +import { generateDscProof, generateRegisterProof, generateVcAndDiscloseProof } from "../utils/generateProof"; +import { LeanIMT } from "@openpassport/zk-kit-lean-imt"; +import serialized_dsc_tree from "../../../common/pubkeys/serialized_dsc_tree.json"; import { DeployedActors, VcAndDiscloseHubProof } from "../utils/types"; import { generateRandomFieldElement, splitHexFromBack } from "../utils/utils"; @@ -86,7 +86,7 @@ describe("End to End Tests", function () { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); const imt = new LeanIMT(hashFunction); await imt.insert(BigInt(registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_COMMITMENT_INDEX])); @@ -183,20 +183,18 @@ describe("End to End Tests", function () { await token.waitForDeployment(); const airdropFactory = await ethers.getContractFactory("Airdrop"); - const airdrop = await airdropFactory - .connect(owner) - .deploy( - hub.target, - castFromScope("test-scope"), - ATTESTATION_ID.E_PASSPORT, - token.target, - true, - 20, - // @ts-expect-error - true, - countriesListPacked as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], - [true, true, true], - ); + const airdrop = await airdropFactory.connect(owner).deploy( + hub.target, + castFromScope("test-scope"), + ATTESTATION_ID.E_PASSPORT, + token.target, + true, + 20, + // @ts-expect-error + true, + countriesListPacked as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + [true, true, true], + ); await airdrop.waitForDeployment(); await token.connect(owner).mint(airdrop.target, BigInt(1000000000000000000)); diff --git a/contracts/test/integration/vcAndDisclose.test.ts b/contracts/test/integration/vcAndDisclose.test.ts index dc6591d39..c15d799c8 100644 --- a/contracts/test/integration/vcAndDisclose.test.ts +++ b/contracts/test/integration/vcAndDisclose.test.ts @@ -10,11 +10,7 @@ import { generateCommitment } from "@selfxyz/common/utils/passports/passport"; import { BigNumberish } from "ethers"; import { generateRandomFieldElement, getStartOfDayTimestamp, splitHexFromBack } from "../utils/utils"; import { Formatter, CircuitAttributeHandler } from "../utils/formatter"; -import { - formatCountriesList, - reverseBytes, - reverseCountryBytes, -} from "@selfxyz/common/utils/circuits/formatInputs"; +import { formatCountriesList, reverseBytes, reverseCountryBytes } from "@selfxyz/common/utils/circuits/formatInputs"; import { getPackedForbiddenCountries } from "@selfxyz/common/utils/contracts/forbiddenCountries"; import { countries, Country3LetterCode } from "@selfxyz/common/constants/countries"; import fs from "fs"; @@ -47,7 +43,7 @@ describe("VC and Disclose", () => { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); imt = new LeanIMT(hashFunction); await imt.insert(BigInt(commitment)); @@ -93,7 +89,7 @@ describe("VC and Disclose", () => { "ABC", "CBA", ] as Country3LetterCode[]; - forbiddenCountriesListPacked = getPackedForbiddenCountries(forbiddenCountriesList) + forbiddenCountriesListPacked = getPackedForbiddenCountries(forbiddenCountriesList); invalidForbiddenCountriesList = ["AAA", "ABC", "CBA", "CBA"]; // const invalidWholePacked = reverseBytes(Formatter.bytesToHexString(new Uint8Array(formatCountriesList(invalidForbiddenCountriesList)))); @@ -133,11 +129,16 @@ describe("VC and Disclose", () => { it("should verify and get result successfully", async () => { const { hub, registry, owner } = deployedActors; - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, - forbiddenCountriesListPacked: forbiddenCountriesListPacked, + forbiddenCountriesListPacked: forbiddenCountriesListPacked.slice(0, 4) as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], ofacEnabled: [true, true, true] as [boolean, boolean, boolean], vcAndDiscloseProof: vcAndDiscloseProof, }; diff --git a/contracts/test/integration/verifyAll.test.ts b/contracts/test/integration/verifyAll.test.ts index 3562311b7..6fe782c73 100644 --- a/contracts/test/integration/verifyAll.test.ts +++ b/contracts/test/integration/verifyAll.test.ts @@ -41,7 +41,7 @@ describe("VerifyAll", () => { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); imt = new LeanIMT(hashFunction); await imt.insert(BigInt(commitment)); @@ -178,7 +178,7 @@ describe("VerifyAll", () => { await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -199,7 +199,7 @@ describe("VerifyAll", () => { await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -222,7 +222,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.a[0] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: false, olderThan: "20", forbiddenCountriesEnabled: false, @@ -245,7 +245,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0; - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -266,7 +266,7 @@ describe("VerifyAll", () => { const { registry, owner } = deployedActors; await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); - const vcAndDiscloseHubProof : VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "21", // Higher than the age in proof forbiddenCountriesEnabled: false, @@ -304,7 +304,7 @@ describe("VerifyAll", () => { "0", ); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: false, @@ -329,7 +329,7 @@ describe("VerifyAll", () => { const { registry, owner } = deployedActors; await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -350,7 +350,7 @@ describe("VerifyAll", () => { const { registry, owner } = deployedActors; await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -378,7 +378,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_PASSPORT_NO_SMT_ROOT_INDEX] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -402,7 +402,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_DOB_SMT_ROOT_INDEX] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -426,7 +426,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_YOB_SMT_ROOT_INDEX] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -479,7 +479,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.a[0] = generateRandomFieldElement(); - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, @@ -502,7 +502,7 @@ describe("VerifyAll", () => { vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0; - const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { + const vcAndDiscloseHubProof: VcAndDiscloseHubProof = { olderThanEnabled: true, olderThan: "20", forbiddenCountriesEnabled: true, diff --git a/contracts/test/unit/CustomVerifier.test.ts b/contracts/test/unit/CustomVerifier.test.ts new file mode 100644 index 000000000..ab168b0c5 --- /dev/null +++ b/contracts/test/unit/CustomVerifier.test.ts @@ -0,0 +1,411 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { TestCustomVerifier, CustomVerifier } from "../../typechain-types"; + +export const AttestationId = { + E_PASSPORT: "0x0000000000000000000000000000000000000000000000000000000000000001", + EU_ID_CARD: "0x0000000000000000000000000000000000000000000000000000000000000002", +} as const; + +describe("CustomVerifier", function () { + let testVerifier: TestCustomVerifier; + let customVerifier: CustomVerifier; + + before(async function () { + const CustomVerifierFactory = await ethers.getContractFactory("CustomVerifier"); + customVerifier = await CustomVerifierFactory.deploy(); + await customVerifier.waitForDeployment(); + + const TestVerifierFactory = await ethers.getContractFactory("TestCustomVerifier", { + libraries: { + CustomVerifier: await customVerifier.getAddress(), + }, + }); + testVerifier = await TestVerifierFactory.deploy(); + await testVerifier.waitForDeployment(); + }); + + describe("Passport Verification", function () { + const mrz = ethers.toUtf8Bytes( + "P + await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ), + ).to.be.revertedWithCustomError(customVerifier, "INVALID_OFAC"); + }); + + it("should return proper OFAC results", async function () { + const config = [ + false, + 0, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); + expect(result.ofac[0]).to.equal(true); + expect(result.ofac[1]).to.equal(false); + expect(result.ofac[2]).to.equal(true); + }); + + it("should verify passport with forbidden countries check", async function () { + const config = [ + false, + 0, + true, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); + }); + + it("should throw an error if age is not valid", async function () { + const config = [ + true, + 19, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + expect( + async () => + await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ), + ).to.be.revertedWithCustomError(customVerifier, "INVALID_OLDER_THAN"); + }); + + it("should not throw an error if older than is not enabled", async function () { + const config = [ + false, + 19, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); + }); + + it("should not throw an error if age is valid", async function () { + const config = [ + true, + 18, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.E_PASSPORT, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [samplePassportOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); + expect(result.olderThan).to.equal(18); + }); + }); + + describe("ID Card Verification", function () { + let mrz = "I + await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ), + ).to.be.revertedWithCustomError(customVerifier, "INVALID_OFAC"); + }); + + it("should return proper OFAC results", async function () { + const config = [ + false, + 0, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); + expect(result.ofac[0]).to.equal(false); + expect(result.ofac[1]).to.equal(true); + expect(result.ofac[2]).to.equal(false); + }); + + it("should verify ID card with OFAC checks", async function () { + const config = [ + false, + 0, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); + }); + + it("should verify ID card with forbidden countries check", async function () { + const config = [ + false, + 0, + true, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); + }); + + it("should throw an error if age is not valid", async function () { + const config = [ + true, + 19, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + expect( + async () => + await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ), + ).to.be.revertedWithCustomError(customVerifier, "INVALID_OLDER_THAN"); + }); + + it("should not throw an error if older than is not enabled", async function () { + const config = [ + false, + 19, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); + }); + + it("should verify ID card with age check", async function () { + const config = [ + true, + 18, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const result = await testVerifier.testCustomVerify( + AttestationId.EU_ID_CARD, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [sampleIdCardOutput], + ), + ); + + expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); + expect(result.olderThan).to.equal(18); + }); + }); + + it("should revert with invalid attestation ID", async function () { + const config = [ + false, + 0, + false, + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], + [false, false, false], + ]; + + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + + await expect( + testVerifier.testCustomVerify( + invalidAttestationId, + ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), + ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], + [ + [ + ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // attestationId (uint256) + ethers.randomBytes(88), // revealedDataPacked (bytes) + ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // userIdentifier (uint256) + ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // nullifier (uint256) + [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], // forbiddenCountriesListPacked + ], + ], + ), + ), + ).to.be.revertedWithCustomError(customVerifier, "INVALID_ATTESTATION_ID"); + }); +}); diff --git a/contracts/test/unit/GenericFormatter.test.ts b/contracts/test/unit/GenericFormatter.test.ts new file mode 100644 index 000000000..4e84a601a --- /dev/null +++ b/contracts/test/unit/GenericFormatter.test.ts @@ -0,0 +1,165 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { TestGenericFormatter } from "../../typechain-types"; +import type { SelfStructs } from "../../typechain-types/contracts/tests/testGenericFormatter.sol/TestGenericFormatter"; + +describe("GenericFormatter", function () { + let testGenericFormatter: TestGenericFormatter; + + before(async function () { + const TestGenericFormatterFactory = await ethers.getContractFactory("TestGenericFormatter"); + testGenericFormatter = await TestGenericFormatterFactory.deploy(); + await testGenericFormatter.waitForDeployment(); + }); + + it("should convert from v1 to the latest config struct", async function () { + // Create a sample VerificationConfigV1 struct + const verificationConfigV1: SelfStructs.VerificationConfigV1Struct = { + olderThanEnabled: true, + olderThan: 18, + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n], + ofacEnabled: [false, false, false], + }; + + const verificationConfigV2 = await testGenericFormatter.testFromV1Config(verificationConfigV1); + + // Add your assertions here + expect(verificationConfigV2.olderThanEnabled).to.equal(verificationConfigV1.olderThanEnabled); + expect(verificationConfigV2.olderThan).to.equal(verificationConfigV1.olderThan); + expect(verificationConfigV2.forbiddenCountriesEnabled).to.equal(verificationConfigV1.forbiddenCountriesEnabled); + expect(verificationConfigV2.forbiddenCountriesListPacked).to.deep.equal( + verificationConfigV1.forbiddenCountriesListPacked, + ); + expect(verificationConfigV2.ofacEnabled).to.deep.equal(verificationConfigV1.ofacEnabled); + }); + + it("should convert from bytes to the latest config struct", async function () { + // Create a sample VerificationConfigV2 struct + const verificationConfigV2: SelfStructs.VerificationConfigV2Struct = { + olderThanEnabled: true, + olderThan: 18, + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n], + ofacEnabled: [false, false, false], + }; + + //abi encode the verificationConfigV2 struct + const verificationConfigV2Bytes = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(bool,uint256,bool,uint256[4],bool[3])"], + [ + [ + verificationConfigV2.olderThanEnabled, + verificationConfigV2.olderThan, + verificationConfigV2.forbiddenCountriesEnabled, + verificationConfigV2.forbiddenCountriesListPacked, + verificationConfigV2.ofacEnabled, + ], + ], + ); + + const verificationConfigV2BytesDecoded = + await testGenericFormatter.testVerificationConfigFromBytes(verificationConfigV2Bytes); + + // Add your assertions here + expect(verificationConfigV2BytesDecoded.olderThanEnabled).to.equal(verificationConfigV2.olderThanEnabled); + expect(verificationConfigV2BytesDecoded.olderThan).to.equal(verificationConfigV2.olderThan); + expect(verificationConfigV2BytesDecoded.forbiddenCountriesEnabled).to.equal( + verificationConfigV2.forbiddenCountriesEnabled, + ); + expect(verificationConfigV2BytesDecoded.forbiddenCountriesListPacked).to.deep.equal( + verificationConfigV2.forbiddenCountriesListPacked, + ); + expect(verificationConfigV2BytesDecoded.ofacEnabled).to.deep.equal(verificationConfigV2.ofacEnabled); + }); + + it("should convert v1 config to bytes of the latest config struct", async function () { + // Create a sample VerificationConfigV1 struct + const verificationConfigV1: SelfStructs.VerificationConfigV1Struct = { + olderThanEnabled: true, + olderThan: 18, + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n], + ofacEnabled: [false, false, false], + }; + + const verificationConfigLatest = await testGenericFormatter.testFormatV1Config(verificationConfigV1); + + const verificationConfigLatestDecoded = ethers.AbiCoder.defaultAbiCoder().decode( + ["tuple(bool,uint256,bool,uint256[4],bool[3])"], + verificationConfigLatest, + ); + + // Add your assertions here + expect(verificationConfigLatestDecoded[0][0]).to.equal(verificationConfigV1.olderThanEnabled); + expect(verificationConfigLatestDecoded[0][1]).to.equal(verificationConfigV1.olderThan); + expect(verificationConfigLatestDecoded[0][2]).to.equal(verificationConfigV1.forbiddenCountriesEnabled); + expect(verificationConfigLatestDecoded[0][3]).to.deep.equal(verificationConfigV1.forbiddenCountriesListPacked); + expect(verificationConfigLatestDecoded[0][4]).to.deep.equal(verificationConfigV1.ofacEnabled); + }); + + it("should convert v2 config to bytes of the latest config struct", async function () { + // Create a sample VerificationConfigV2 struct + const verificationConfigV2: SelfStructs.VerificationConfigV2Struct = { + olderThanEnabled: true, + olderThan: 18, + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n], + ofacEnabled: [false, false, false], + }; + + const verificationConfigV2Bytes = await testGenericFormatter.testFormatV2Config(verificationConfigV2); + + const verificationConfigLatest = ethers.AbiCoder.defaultAbiCoder().decode( + ["tuple(bool,uint256,bool,uint256[4],bool[3])"], + verificationConfigV2Bytes, + ); + + // Add your assertions here + expect(verificationConfigLatest[0][0]).to.equal(verificationConfigV2.olderThanEnabled); + expect(verificationConfigLatest[0][1]).to.equal(verificationConfigV2.olderThan); + expect(verificationConfigLatest[0][2]).to.equal(verificationConfigV2.forbiddenCountriesEnabled); + expect(verificationConfigLatest[0][3]).to.deep.equal(verificationConfigV2.forbiddenCountriesListPacked); + expect(verificationConfigLatest[0][4]).to.deep.equal(verificationConfigV2.ofacEnabled); + }); + + it("should convert v2 struct to bytes of the latest config struct", async function () { + // Create a sample GenericDiscloseOutputV2 struct + const genericDiscloseOutputV2: SelfStructs.GenericDiscloseOutputV2Struct = { + attestationId: "0x0000000000000000000000000000000000000000000000000000000000000001", + userIdentifier: 1, + nullifier: 1, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n], + issuingState: "US", + name: ["John", "Doe"], + idNumber: "1234567890", + nationality: "US", + dateOfBirth: "1990-01-01", + gender: "Male", + expiryDate: "2025-01-01", + olderThan: 18, + ofac: [false, false, false], + }; + + const genericDiscloseOutputV2Bytes = await testGenericFormatter.testToV2Struct(genericDiscloseOutputV2); + + const genericDiscloseOutputLatest = ethers.AbiCoder.defaultAbiCoder().decode( + ["tuple(bytes32,uint256,uint256,uint256[4],string,string[],string,string,string,string,string,uint256,bool[3])"], + genericDiscloseOutputV2Bytes, + ); + + expect(genericDiscloseOutputV2.attestationId.toString()).to.equal(genericDiscloseOutputV2.attestationId); + expect(genericDiscloseOutputLatest[0][1]).to.equal(genericDiscloseOutputV2.userIdentifier); + expect(genericDiscloseOutputLatest[0][2]).to.equal(genericDiscloseOutputV2.nullifier); + expect(genericDiscloseOutputLatest[0][3]).to.deep.equal(genericDiscloseOutputV2.forbiddenCountriesListPacked); + expect(genericDiscloseOutputLatest[0][4]).to.equal(genericDiscloseOutputV2.issuingState); + expect(genericDiscloseOutputLatest[0][5]).to.deep.equal(genericDiscloseOutputV2.name); + expect(genericDiscloseOutputLatest[0][6]).to.equal(genericDiscloseOutputV2.idNumber); + expect(genericDiscloseOutputLatest[0][7]).to.equal(genericDiscloseOutputV2.nationality); + expect(genericDiscloseOutputLatest[0][8]).to.equal(genericDiscloseOutputV2.dateOfBirth); + expect(genericDiscloseOutputLatest[0][9]).to.equal(genericDiscloseOutputV2.gender); + expect(genericDiscloseOutputLatest[0][10]).to.equal(genericDiscloseOutputV2.expiryDate); + expect(genericDiscloseOutputLatest[0][11]).to.equal(genericDiscloseOutputV2.olderThan); + expect(genericDiscloseOutputLatest[0][12]).to.deep.equal(genericDiscloseOutputV2.ofac); + }); +}); diff --git a/contracts/test/unit/IdentityRegistry.test.ts b/contracts/test/unit/IdentityRegistry.test.ts index cd6738e33..8a387762b 100644 --- a/contracts/test/unit/IdentityRegistry.test.ts +++ b/contracts/test/unit/IdentityRegistry.test.ts @@ -192,7 +192,7 @@ describe("Unit Tests for IdentityRegistry", () => { const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3 - const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then(mod => mod.LeanIMT); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); const imt = new LeanIMT(hashFunction); imt.insert(BigInt(commitment)); expect(imt.root).to.equal(root); diff --git a/contracts/test/unit/formatter.test.ts b/contracts/test/unit/formatter.test.ts index fbbfa94e4..568ce8bdd 100644 --- a/contracts/test/unit/formatter.test.ts +++ b/contracts/test/unit/formatter.test.ts @@ -150,13 +150,26 @@ describe("Formatter", function () { describe("extractForbiddenCountriesFromPacked", function () { it("should match contract and ts implementation", async function () { - const input = "0x414141424242434343"; - const contractResult = await testFormatter.testExtractForbiddenCountriesFromPacked([input, 0n, 0n, 0n]); - const tsResult = Formatter.extractForbiddenCountriesFromPacked(BigInt(input)); - expect(contractResult).to.deep.equal(tsResult); - expect(contractResult[0]).to.equal("CCC"); - expect(contractResult[1]).to.equal("BBB"); - expect(contractResult[2]).to.equal("AAA"); + const input1 = "0x414754414154414149414f4741444e414d5341415a44424c41414c41474641"; + const input2 = "0x4542524c42425242444742524842534842455a415355415742414d52414752"; + const input3 = "0x4e41434d484b5650434e52424c4f424e5442554d424e45425a4c42554d424c"; + const input4 = "0x4853454d4559424d5a45575a5455564b4e445453454e4843564943"; + const contractResult = await testFormatter.testExtractForbiddenCountriesFromPacked([ + input1, + input2, + input3, + input4, + ]); + const tsResult: string[] = Formatter.extractForbiddenCountriesFromPacked([input1, input2, input3, input4], "id"); + let formattedTsResult = tsResult + .map((item: string, index: number) => { + if (index % 3 === 0) { + return item + tsResult[index + 1] + tsResult[index + 2]; + } + return undefined; + }) + .filter(Boolean); + expect(contractResult).to.deep.equal(formattedTsResult); }); it("should revert when field element is out of range", async function () { diff --git a/contracts/test/utils/constants.ts b/contracts/test/utils/constants.ts index e9c37b753..3ac0134f9 100644 --- a/contracts/test/utils/constants.ts +++ b/contracts/test/utils/constants.ts @@ -1,6 +1,7 @@ export const ATTESTATION_ID = { INVALID_ATTESTATION_ID: "0x0000000000000000000000000000000000000000000000000000000000000000", E_PASSPORT: "0x0000000000000000000000000000000000000000000000000000000000000001", + EU_ID_CARD: "0x0000000000000000000000000000000000000000000000000000000000000002", }; export const FIELD_PRIME = BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); diff --git a/contracts/test/utils/deploymentV2.ts b/contracts/test/utils/deploymentV2.ts new file mode 100644 index 000000000..5c1fdf935 --- /dev/null +++ b/contracts/test/utils/deploymentV2.ts @@ -0,0 +1,239 @@ +import { ethers } from "hardhat"; +import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; +import { Signer } from "ethers"; +import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common/constants/constants"; +import { genAndInitMockPassportData } from "@selfxyz/common/utils/passports/genMockPassportData"; +import { getCscaTreeRoot } from "@selfxyz/common/utils/trees"; +import { PassportData } from "@selfxyz/common/utils/types"; +import { getSMTs } from "./generateProof"; +import serialized_csca_tree from "../../../common/pubkeys/serialized_csca_tree.json"; +import { DeployedActorsV2 } from "./types"; +import { hashEndpointWithScope } from "@selfxyz/common/utils/scope"; + +// Verifier artifacts (local staging) +import VcAndDiscloseVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/disclose/Verifier_vc_and_disclose_staging.sol/Verifier_vc_and_disclose_staging.json"; +import VcAndDiscloseIdVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/disclose/Verifier_vc_and_disclose_id_staging.sol/Verifier_vc_and_disclose_id_staging.json"; +import RegisterVerifierArtifactLocal from "../../artifacts/contracts/verifiers/local/staging/register/Verifier_register_sha256_sha256_sha256_rsa_65537_4096_staging.sol/Verifier_register_sha256_sha256_sha256_rsa_65537_4096_staging.json"; +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 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 { PoseidonT3 } from "poseidon-solidity"; + +export async function deploySystemFixturesV2(): Promise { + let identityVerificationHubV2: any; + let identityVerificationHubImplV2: any; + let identityRegistryProxy: any; + let identityRegistryImpl: any; + let identityRegistryIdProxy: any; + let identityRegistryIdImpl: any; + let vcAndDiscloseVerifier: any; + let vcAndDiscloseIdVerifier: any; + let registerVerifier: any; + let registerIdVerifier: any; + let dscVerifier: any; + let testSelfVerificationRoot: any; + let owner: HardhatEthersSigner; + let user1: HardhatEthersSigner; + let user2: HardhatEthersSigner; + let mockPassport: PassportData; + + [owner, user1, user2] = await ethers.getSigners(); + + const newBalance = "0x" + ethers.parseEther("10000").toString(16); + + await ethers.provider.send("hardhat_setBalance", [await owner.getAddress(), newBalance]); + await ethers.provider.send("hardhat_setBalance", [await user1.getAddress(), newBalance]); + await ethers.provider.send("hardhat_setBalance", [await user2.getAddress(), newBalance]); + + mockPassport = genAndInitMockPassportData("sha256", "sha256", "rsa_sha256_65537_4096", "FRA", "940131", "401031"); + + // Deploy verifiers using artifacts + const vcAndDiscloseVerifierArtifact = VcAndDiscloseVerifierArtifactLocal; + const vcAndDiscloseVerifierFactory = await ethers.getContractFactory( + vcAndDiscloseVerifierArtifact.abi, + vcAndDiscloseVerifierArtifact.bytecode, + ); + vcAndDiscloseVerifier = await vcAndDiscloseVerifierFactory.connect(owner).deploy(); + await vcAndDiscloseVerifier.waitForDeployment(); + + // Deploy VC and Disclose ID verifier + const vcAndDiscloseIdVerifierArtifact = VcAndDiscloseIdVerifierArtifactLocal; + const vcAndDiscloseIdVerifierFactory = await ethers.getContractFactory( + vcAndDiscloseIdVerifierArtifact.abi, + vcAndDiscloseIdVerifierArtifact.bytecode, + ); + vcAndDiscloseIdVerifier = await vcAndDiscloseIdVerifierFactory.connect(owner).deploy(); + await vcAndDiscloseIdVerifier.waitForDeployment(); + + // Deploy register verifier + const registerVerifierArtifact = RegisterVerifierArtifactLocal; + const registerVerifierFactory = await ethers.getContractFactory( + registerVerifierArtifact.abi, + registerVerifierArtifact.bytecode, + ); + registerVerifier = await registerVerifierFactory.connect(owner).deploy(); + await registerVerifier.waitForDeployment(); + + // Deploy register ID verifier + const registerIdVerifierArtifact = RegisterIdVerifierArtifactLocal; + const registerIdVerifierFactory = await ethers.getContractFactory( + registerIdVerifierArtifact.abi, + registerIdVerifierArtifact.bytecode, + ); + registerIdVerifier = await registerIdVerifierFactory.connect(owner).deploy(); + await registerIdVerifier.waitForDeployment(); + + // Deploy dsc verifier + const dscVerifierArtifact = DscVerifierArtifactLocal; + const dscVerifierFactory = await ethers.getContractFactory(dscVerifierArtifact.abi, dscVerifierArtifact.bytecode); + dscVerifier = await dscVerifierFactory.connect(owner).deploy(); + await dscVerifier.waitForDeployment(); + + // Deploy PoseidonT3 + const PoseidonT3Factory = await ethers.getContractFactory("PoseidonT3"); + const poseidonT3 = await PoseidonT3Factory.connect(owner).deploy(); + await poseidonT3.waitForDeployment(); + + // Deploy CustomVerifier library + const CustomVerifierFactory = await ethers.getContractFactory("CustomVerifier"); + const customVerifier = await CustomVerifierFactory.connect(owner).deploy(); + await customVerifier.waitForDeployment(); + + // Deploy GenericFormatter library + const GenericFormatterFactory = await ethers.getContractFactory("GenericFormatter"); + const genericFormatter = await GenericFormatterFactory.connect(owner).deploy(); + await genericFormatter.waitForDeployment(); + + // Deploy IdentityRegistryImplV1 (same registry as V1) + const IdentityRegistryImplFactory = await ethers.getContractFactory("IdentityRegistryImplV1", { + libraries: { + PoseidonT3: poseidonT3.target, + }, + }); + identityRegistryImpl = await IdentityRegistryImplFactory.connect(owner).deploy(); + await identityRegistryImpl.waitForDeployment(); + + // Deploy IdentityRegistryIdCardImplV1 for ID cards + const IdentityRegistryIdImplFactory = await ethers.getContractFactory("IdentityRegistryIdCardImplV1", { + libraries: { + PoseidonT3: poseidonT3.target, + }, + }); + identityRegistryIdImpl = await IdentityRegistryIdImplFactory.connect(owner).deploy(); + await identityRegistryIdImpl.waitForDeployment(); + // Deploy IdentityVerificationHubImplV2 + const IdentityVerificationHubImplV2Factory = await ethers.getContractFactory("IdentityVerificationHubImplV2", { + libraries: { + CustomVerifier: customVerifier.target, + }, + }); + identityVerificationHubImplV2 = await IdentityVerificationHubImplV2Factory.connect(owner).deploy(); + await identityVerificationHubImplV2.waitForDeployment(); + + // Deploy registry with temporary hub address + const temporaryHubAddress = "0x0000000000000000000000000000000000000000"; + const registryInitData = identityRegistryImpl.interface.encodeFunctionData("initialize", [temporaryHubAddress]); + const registryProxyFactory = await ethers.getContractFactory("IdentityRegistry"); + identityRegistryProxy = await registryProxyFactory + .connect(owner) + .deploy(identityRegistryImpl.target, registryInitData); + await identityRegistryProxy.waitForDeployment(); + + // Deploy ID card registry with temporary hub address + const registryIdInitData = identityRegistryIdImpl.interface.encodeFunctionData("initialize", [temporaryHubAddress]); + const registryIdProxyFactory = await ethers.getContractFactory("IdentityRegistry"); + identityRegistryIdProxy = await registryIdProxyFactory + .connect(owner) + .deploy(identityRegistryIdImpl.target, registryIdInitData); + await identityRegistryIdProxy.waitForDeployment(); + + // Deploy hub V2 with simple initialization (V2 has different initialization) + const initializeDataV2 = identityVerificationHubImplV2.interface.encodeFunctionData("initialize"); + const hubFactory = await ethers.getContractFactory("IdentityVerificationHub"); + identityVerificationHubV2 = await hubFactory + .connect(owner) + .deploy(identityVerificationHubImplV2.target, initializeDataV2); + await identityVerificationHubV2.waitForDeployment(); + + // Get contracts with implementation ABI and update hub address + const registryContract = await ethers.getContractAt("IdentityRegistryImplV1", identityRegistryProxy.target); + const updateHubTx = await registryContract.updateHub(identityVerificationHubV2.target); + await updateHubTx.wait(); + + const registryIdContract = await ethers.getContractAt("IdentityRegistryIdCardImplV1", identityRegistryIdProxy.target); + const updateIdHubTx = await registryIdContract.updateHub(identityVerificationHubV2.target); + await updateIdHubTx.wait(); + + const hubContract = (await ethers.getContractAt( + "IdentityVerificationHubImplV2", + identityVerificationHubV2.target, + )) as any; + + // Initialize roots + const csca_root = getCscaTreeRoot(serialized_csca_tree); + await registryContract.updateCscaRoot(csca_root, { from: owner }); + await registryIdContract.updateCscaRoot(csca_root, { from: owner }); + + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + await registryContract.updatePassportNoOfacRoot(passportNo_smt.root, { from: owner }); + await registryContract.updateNameAndDobOfacRoot(nameAndDob_smt.root, { from: owner }); + await registryIdContract.updateNameAndDobOfacRoot(nameAndDob_smt.root, { from: owner }); + await registryContract.updateNameAndYobOfacRoot(nameAndYob_smt.root, { from: owner }); + await registryIdContract.updateNameAndYobOfacRoot(nameAndYob_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)); + + // Update registries in the hub + await hubContract.updateRegistry(E_PASSPORT, identityRegistryProxy.target); + await hubContract.updateRegistry(EU_ID_CARD, identityRegistryIdProxy.target); + + // Update VC and Disclose verifiers + await hubContract.updateVcAndDiscloseCircuit(E_PASSPORT, vcAndDiscloseVerifier.target); + await hubContract.updateVcAndDiscloseCircuit(EU_ID_CARD, vcAndDiscloseIdVerifier.target); + + // Update register verifiers + await hubContract.updateRegisterCircuitVerifier( + E_PASSPORT, + RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096, + registerVerifier.target, + ); + await hubContract.updateRegisterCircuitVerifier( + EU_ID_CARD, + RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096, + registerIdVerifier.target, + ); + + // Update DSC verifiers + await hubContract.updateDscVerifier(E_PASSPORT, DscVerifierId.dsc_sha256_rsa_65537_4096, dscVerifier.target); + // Add DSC verifier for EU_ID_CARD as well + await hubContract.updateDscVerifier(EU_ID_CARD, DscVerifierId.dsc_sha256_rsa_65537_4096, dscVerifier.target); + + // Deploy TestSelfVerificationRoot + const testScope = hashEndpointWithScope("example.com", "test-scope"); + const testRootFactory = await ethers.getContractFactory("TestSelfVerificationRoot"); + testSelfVerificationRoot = await testRootFactory.deploy(identityVerificationHubV2.target, testScope); + await testSelfVerificationRoot.waitForDeployment(); + + return { + hubImplV2: identityVerificationHubImplV2, + hub: hubContract, + registryImpl: identityRegistryImpl, + registry: registryContract, + registryIdImpl: identityRegistryIdImpl, + registryId: registryIdContract, + vcAndDisclose: vcAndDiscloseVerifier, + vcAndDiscloseId: vcAndDiscloseIdVerifier, + register: registerVerifier, + registerId: RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096, + dsc: dscVerifier, + dscId: DscVerifierId.dsc_sha256_rsa_65537_4096, + testSelfVerificationRoot: testSelfVerificationRoot, + customVerifier: customVerifier, + owner: owner as any, + user1: user1 as any, + user2: user2 as any, + mockPassport: mockPassport, + }; +} diff --git a/contracts/test/utils/formatter.ts b/contracts/test/utils/formatter.ts index aa6822f9b..a74ef9fe5 100644 --- a/contracts/test/utils/formatter.ts +++ b/contracts/test/utils/formatter.ts @@ -88,19 +88,25 @@ export class Formatter { ); } - static extractForbiddenCountriesFromPacked(publicSignal: bigint): string[] { - const forbiddenCountries: string[] = new Array(Formatter.MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH); - for (let j = 0; j < Formatter.MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH; j++) { - const byteIndex = BigInt(j * 3); - const shift = byteIndex * 8n; - const mask = 0xffffffn; - const packedData = (publicSignal >> shift) & mask; - const char1 = String.fromCharCode(Number((packedData >> 16n) & 0xffn)); - const char2 = String.fromCharCode(Number((packedData >> 8n) & 0xffn)); - const char3 = String.fromCharCode(Number(packedData & 0xffn)); - forbiddenCountries[j] = char1 + char2 + char3; - } - return forbiddenCountries; + static extractForbiddenCountriesFromPacked( + revealedData_packed: string | string[], + id_type: "passport" | "id", + ): string[] { + // If revealedData_packed is not an array, convert it to an array + const packedArray = Array.isArray(revealedData_packed) ? revealedData_packed : [revealedData_packed]; + + const bytesCount = id_type === "passport" ? [31, 31, 31] : [31, 31, 31, 27]; // nb of bytes in each of the first three field elements + const bytesArray = packedArray.flatMap((element: string, index: number) => { + const bytes = bytesCount[index] || 31; // Use 31 as default if index is out of range + const elementBigInt = BigInt(element); + const byteMask = BigInt(255); // 0xFF + const bytesOfElement = [...Array(bytes)].map((_, byteIndex) => { + return (elementBigInt >> (BigInt(byteIndex) * BigInt(8))) & byteMask; + }); + return bytesOfElement; + }); + + return bytesArray.map((byte: bigint) => String.fromCharCode(Number(byte))); } static proofDateToUnixTimestamp(dateNum: number[]): number { diff --git a/contracts/test/utils/generateProof.ts b/contracts/test/utils/generateProof.ts index cef65bf0d..52520a578 100644 --- a/contracts/test/utils/generateProof.ts +++ b/contracts/test/utils/generateProof.ts @@ -1,10 +1,5 @@ -const CYAN = "\x1b[36m"; -const YELLOW = "\x1b[33m"; -const GREEN = "\x1b[32m"; -const RESET = "\x1b[0m"; - -import { LeanIMT } from "@openpassport/zk-kit-lean-imt" -import { ChildNodes, SMT } from "@openpassport/zk-kit-smt" +import { LeanIMT } from "@openpassport/zk-kit-lean-imt"; +import { ChildNodes, SMT } from "@openpassport/zk-kit-smt"; import fs from "fs"; import path from "path"; import { poseidon2, poseidon3 } from "poseidon-lite"; @@ -19,8 +14,9 @@ import { generateCircuitInputsRegister, generateCircuitInputsVCandDisclose, } from "@selfxyz/common/utils/circuits/generateInputs"; -import serialized_csca_tree from "./pubkeys/serialized_csca_tree.json"; -import serialized_dsc_tree from "./pubkeys/serialized_dsc_tree.json"; +import { getCircuitNameFromPassportData } from "@selfxyz/common/utils/circuits/circuitsName"; +import serialized_csca_tree from "../../../common/pubkeys/serialized_csca_tree.json"; +import serialized_dsc_tree from "../../../common/pubkeys/serialized_dsc_tree.json"; const registerCircuits: CircuitArtifacts = { register_sha256_sha256_sha256_rsa_65537_4096: { @@ -29,6 +25,13 @@ const registerCircuits: CircuitArtifacts = { vkey: "../circuits/build/register/register_sha256_sha256_sha256_rsa_65537_4096/register_sha256_sha256_sha256_rsa_65537_4096_vkey.json", }, }; +const registerCircuitsId: CircuitArtifacts = { + register_id_sha256_sha256_sha256_rsa_65537_4096: { + wasm: "../circuits/build/register_id/register_id_sha256_sha256_sha256_rsa_65537_4096/register_id_sha256_sha256_sha256_rsa_65537_4096_js/register_id_sha256_sha256_sha256_rsa_65537_4096.wasm", + zkey: "../circuits/build/register_id/register_id_sha256_sha256_sha256_rsa_65537_4096/register_id_sha256_sha256_sha256_rsa_65537_4096_final.zkey", + vkey: "../circuits/build/register_id/register_id_sha256_sha256_sha256_rsa_65537_4096/register_id_sha256_sha256_sha256_rsa_65537_4096_vkey.json", + }, +}; const dscCircuits: CircuitArtifacts = { dsc_sha256_rsa_65537_4096: { wasm: "../circuits/build/dsc/dsc_sha256_rsa_65537_4096/dsc_sha256_rsa_65537_4096_js/dsc_sha256_rsa_65537_4096.wasm", @@ -43,10 +46,15 @@ const vcAndDiscloseCircuits: CircuitArtifacts = { vkey: "../circuits/build/disclose/vc_and_disclose/vc_and_disclose_vkey.json", }, }; +const vcAndDiscloseIdCircuits: CircuitArtifacts = { + vc_and_disclose_id: { + wasm: "../circuits/build/disclose/vc_and_disclose_id/vc_and_disclose_id_js/vc_and_disclose_id.wasm", + zkey: "../circuits/build/disclose/vc_and_disclose_id/vc_and_disclose_id_final.zkey", + vkey: "../circuits/build/disclose/vc_and_disclose_id/vc_and_disclose_id_vkey.json", + }, +}; export async function generateRegisterProof(secret: string, passportData: PassportData): Promise { - console.log(CYAN, "=== Start generateRegisterProof ===", RESET); - // Get the circuit inputs const registerCircuitInputs: CircuitSignals = await generateCircuitInputsRegister( secret, @@ -55,8 +63,6 @@ export async function generateRegisterProof(secret: string, passportData: Passpo ); // Generate the proof - const startTime = performance.now(); - const registerProof: { proof: Groth16Proof; publicSignals: PublicSignals; @@ -66,9 +72,6 @@ export async function generateRegisterProof(secret: string, passportData: Passpo registerCircuits["register_sha256_sha256_sha256_rsa_65537_4096"].zkey, ); - const endTime = performance.now(); - console.log(GREEN, `groth16.fullProve execution time: ${((endTime - startTime) / 1000).toFixed(2)} seconds`, RESET); - // Verify the proof const vKey = JSON.parse( fs.readFileSync(registerCircuits["register_sha256_sha256_sha256_rsa_65537_4096"].vkey, "utf8"), @@ -77,28 +80,72 @@ export async function generateRegisterProof(secret: string, passportData: Passpo if (!isValid) { throw new Error("Generated register proof verification failed"); } - console.log(GREEN, "Register proof verified successfully", RESET); const rawCallData = await groth16.exportSolidityCallData(registerProof.proof, registerProof.publicSignals); const fixedProof = parseSolidityCalldata(rawCallData, {} as RegisterCircuitProof); - console.log(CYAN, "=== End generateRegisterProof ===", RESET); return fixedProof; } -export async function generateDscProof(passportData: PassportData): Promise { - console.log(CYAN, "=== Start generateDscProof ===", RESET); +export async function generateRegisterIdProof( + secret: string, + passportData: PassportData, +): Promise { + // Get the correct circuit name based on passport data + const circuitName = getCircuitNameFromPassportData(passportData, "register"); + + // Get the circuit inputs for ID card - passportData should already be parsed from genMockIdDocAndInitDataParsing + const registerCircuitInputs: CircuitSignals = await generateCircuitInputsRegister( + secret, + passportData, + serialized_dsc_tree as string, + ); + + // Use the correct circuit artifacts based on the generated circuit name + let circuitArtifacts; + let artifactKey; + + // Check if this is an ID circuit + if (circuitName.startsWith("register_id_")) { + circuitArtifacts = registerCircuitsId; + // Use the actual circuit name as the key + artifactKey = circuitName; + } else { + circuitArtifacts = registerCircuits; + artifactKey = "register_sha256_sha256_sha256_rsa_65537_4096"; + } + + // Generate the proof + const registerProof: { + proof: Groth16Proof; + publicSignals: PublicSignals; + } = await groth16.fullProve( + registerCircuitInputs, + circuitArtifacts[artifactKey].wasm, + circuitArtifacts[artifactKey].zkey, + ); + + // Verify the proof + const vKey = JSON.parse(fs.readFileSync(circuitArtifacts[artifactKey].vkey, "utf8")); + const isValid = await groth16.verify(vKey, registerProof.publicSignals, registerProof.proof); + if (!isValid) { + throw new Error("Generated register ID proof verification failed"); + } + + const rawCallData = await groth16.exportSolidityCallData(registerProof.proof, registerProof.publicSignals); + const fixedProof = parseSolidityCalldata(rawCallData, {} as RegisterCircuitProof); + return fixedProof; +} + +export async function generateDscProof(passportData: PassportData): Promise { const dscCircuitInputs: CircuitSignals = await generateCircuitInputsDSC(passportData, serialized_csca_tree); - const startTime = performance.now(); const dscProof = await groth16.fullProve( dscCircuitInputs, dscCircuits["dsc_sha256_rsa_65537_4096"].wasm, dscCircuits["dsc_sha256_rsa_65537_4096"].zkey, ); - const endTime = performance.now(); - console.log(GREEN, `groth16.fullProve execution time: ${((endTime - startTime) / 1000).toFixed(2)} seconds`, RESET); // Verify the proof const vKey = JSON.parse(fs.readFileSync(dscCircuits["dsc_sha256_rsa_65537_4096"].vkey, "utf8")); @@ -106,12 +153,10 @@ export async function generateDscProof(passportData: PassportData): Promise, + majority: string = "20", + passportNo_smt?: SMT, + nameAndDob_smt?: SMT, + nameAndYob_smt?: SMT, + selectorOfac: string | number = "1", + forbiddenCountriesList: string[] = [ + "AAA", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "AAA", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "AAA", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "AAA", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + "000", + ], + userIdentifier: string = "0000000000000000000000000000000000000000", +): Promise { + // Initialize all three SMTs if not provided + if (!passportNo_smt || !nameAndDob_smt || !nameAndYob_smt) { + const smts = getSMTs(); + passportNo_smt = smts.passportNo_smt; + nameAndDob_smt = smts.nameAndDob_smt; + nameAndYob_smt = smts.nameAndYob_smt; + } + + const idCardPassportData = { + ...passportData, + documentType: passportData.documentType.includes("id") ? passportData.documentType : "id_card", + documentCategory: "id_card" as const, + }; + + const vcAndDiscloseCircuitInputs: CircuitSignals = generateCircuitInputsVCandDisclose( + secret, + attestationId, + idCardPassportData, + scope, + selectorDg1, + selectorOlderThan, + merkletree, + majority, + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + selectorOfac, + forbiddenCountriesList, + userIdentifier, + ); + + const vcAndDiscloseProof = await groth16.fullProve( + vcAndDiscloseCircuitInputs, + vcAndDiscloseIdCircuits["vc_and_disclose_id"].wasm, + vcAndDiscloseIdCircuits["vc_and_disclose_id"].zkey, + ); + + // Verify the proof + const vKey = JSON.parse(fs.readFileSync(vcAndDiscloseIdCircuits["vc_and_disclose_id"].vkey, "utf8")); + const isValid = await groth16.verify(vKey, vcAndDiscloseProof.publicSignals, vcAndDiscloseProof.proof); + if (!isValid) { + throw new Error("Generated VC and Disclose ID proof verification failed"); + } + + const rawCallData = await groth16.exportSolidityCallData(vcAndDiscloseProof.proof, vcAndDiscloseProof.publicSignals); + const fixedProof = parseSolidityCalldata(rawCallData, {} as VcAndDiscloseProof); + + return fixedProof; +} + export function parseSolidityCalldata(rawCallData: string, _type: T): T { const parsed = JSON.parse("[" + rawCallData + "]"); @@ -272,7 +417,14 @@ export function parseSolidityCalldata(rawCallData: string, _type: T): T { [BigNumberish, BigNumberish], ], c: parsed[2].map((x: string) => x.replace(/"/g, "")) as [BigNumberish, BigNumberish], - pubSignals: parsed[3].map((x: string) => x.replace(/"/g, "")) as BigNumberish[], + pubSignals: parsed[3].map((x: string) => { + const cleaned = x.replace(/"/g, ""); + // Convert hex strings to decimal strings for Solidity compatibility + if (cleaned.startsWith("0x")) { + return BigInt(cleaned).toString(); + } + return cleaned; + }) as BigNumberish[], } as T; } @@ -300,7 +452,6 @@ function importSMTFromJsonFile(filePath?: string): SMT | null { return smt; } catch (error) { - console.error("Failed to import SMT from JSON file:", error); return null; } } diff --git a/contracts/test/utils/pubkeys/serialized_csca_tree.json b/contracts/test/utils/pubkeys/serialized_csca_tree.json deleted file mode 100644 index 5139722da..000000000 --- a/contracts/test/utils/pubkeys/serialized_csca_tree.json +++ /dev/null @@ -1,90 +0,0 @@ -[ - [ - "6302746167612040169287204224641965049119379670159808996613022200426959969278", - "21737912865216631366336567244260032647310946375673351181140174093591714702999", - "7881627741362630218419203394369410748786507764316669620068500512816306974393", - "8442633355440465296842644318461346259324083140085137778501389055937910431110", - "494385956299168270408334656570463268819757224023693256178124768603625095689", - "11109705732184239012583404749930109480114669765649070936031155493622876369432", - "9074991679283645951358641479142018086508433068636738897852818247691550887353", - "10472104103456953748165921858843921722705273802507936987918628317450502368318", - "20465532314290048641249890589020580844800312880610998262795900425795687925759", - "5768994172638224755740597462572068991220057867415414997645244086458792645415", - "17252018052637913533753543738759416074689182570352156984838315665730273174771", - "344641985496327935255151802075808884620413685031595062530048227920050721780", - "12136951745768356780790830952320550859256567348204838329686829291956271851018", - "13156935969312787083658542670212591426438912414983737359002368687207144158384", - "18390019689329531194486865663275817993149098196912806933141622083576329149060", - "1481242557340385890029242958318001323542042109291864424212505135403557049174", - "8212379972296569224239707053291801266656219357105654879157065434106153446780", - "7259130865988598378063439736597905343524876834653292276109931166452499429748", - "9121308753649396222680496889506939509201230922178179924059434299141020697403", - "285292161892340475671724520102600999462489619312686773735450615184611138494", - "17039352924793721634937165985544670409252882635692632479205349210469115588765", - "13502358060740841171380532205068310953416088597412723446166411697331808464867", - "17340560759412667275187297637986710225182012906580596771637656874104617617955", - "8161679470983166059226129385619085265731972285960057248143860608525733203270", - "14871986472052100593919450740854089518175775672170855933096343961866149319949", - "1024796798868617073580401107121867347946885220866292564654180021134775438463", - "21314659513316629128269900118046844671368217281573948618189189184438357521850", - "14333285970232052794263361289909650744651387298949229098454892979931317772146", - "16041205263585308774562352509747184978808349452049402919724529400974025427436", - "8087267757933126132764313502987988617372965137423098839133763536652762365681", - "7962106263240616478489255388356842229007064058701247603002333884146997650489", - "3623426348190205637422491853880154438593931070755716928634661523298474873370", - "14890281186129558220608231498920908810133225689204820445535572821472349664447" - ], - [ - "4799972325846543794225228491143787399389885942417063987224237164999385319062", - "17050236804818394861130974609766586541491094962728898163841781451223822854686", - "1684095988446507706929542511950029896329456076438958417914434742534053808377", - "13030822995128201263800907485086206983654704449426873876221363197647850166314", - "20387868117709928393743787975391876407731857373450679028712293718320824421501", - "20648800321790649263930241990062778433044036026899293567267368546697502978404", - "5558822243190898430854422659247277485120763541538425901094235849734898971547", - "9648977827828540671109446184233701627175773049876679003145259446306367526913", - "19587958295993125277460383800858337068930180629959346593667253473373677697838", - "10766098235994178632473997874302736133480358322525035521842128765122396106753", - "3280132879539287366527818935691748975940933587498820629810825597324185825847", - "16042507993949674348775016509851234008694527541085892473255432193590272155228", - "9861886961854997054898644300025435424974733812770562105962523420323474270014", - "19963900440588427317645840967905315109665755922636714102274837921808725924490", - "14560929249637716209472399173281335447881032559475124155250089695314652709191", - "8793029054134443177154661146037690681847213703147023923126117330651746975093", - "6925999197894078032454979151597762706585652495739163647097172857061948107548" - ], - [ - "15437505910104448767291373721892514134533670716520577686244116418756186347964", - "9662712081254759511361246703401148719683866951663061909834810685640445739155", - "20383431234416469352301291449238452506080771017490889548224583250446902949522", - "17761227464350859107613675961034420867642506074271853781885405739945665021951", - "10107612039899335485435001531034291183382103402117414413277201288890819890175", - "21676120760606796382962041245156922927516003007606533210349079976883427407876", - "3959481944782480427438878998268686710659856580112036162216134326047024223619", - "13995366414942085322718873409710308506843557459098667415203661966308146712276", - "12396189675521664477208213044494994395570714180213788407180369449372794337406" - ], - [ - "17536551248416856833253545290007826015310552834679591084728236812275380736581", - "21178262016621282270578676828655596120453358323099758552458721672074592774466", - "12983142270089439210893516110450393549941947745609655791579563598275214147990", - "11138438821067972642938006246604783995156242377512994534882399065269415238242", - "14367141578614776950464394914864658179440566498674064519890241555879050349273" - ], - [ - "4746628767395628818871695814217923898815372663453343963780833567597879413422", - "6217935900653585035630246253466782187759116959924419206414312068302028006200", - "1712622252469401905020836297393811034367718131168934306349084470952949672370" - ], - [ - "9591986692462415575100546764405459060632901984266333538073859143124986153857", - "16005335605576341683358111497065243375958891362902160878740195332217005325867" - ], - ["10058083772386987881503691291273436622272886362704429356343750534180295442877"], - ["948496844530378519444411419272223562136844993455458676689351273655202389660"], - ["6104686411816540186205486815934621935504228294686310666920439592650163266817"], - ["8785911549693694407543433563052767959786709016516642293679450790050523979623"], - ["7409592596312085101815420137623073822216578588711762918861029979315261400521"], - ["21777804325204060904854919426171461175668073322071471253268661582106674611134"], - ["13859398115974385161464830211947258005860166431741677064758266112192747818198"] -] diff --git a/contracts/test/utils/pubkeys/serialized_dsc_tree.json b/contracts/test/utils/pubkeys/serialized_dsc_tree.json deleted file mode 100644 index fbf51fc8c..000000000 --- a/contracts/test/utils/pubkeys/serialized_dsc_tree.json +++ /dev/null @@ -1 +0,0 @@ -"[[\"8474170120361574158328936749210134677109057903005360945237099789945718842442\",\"19025861045901247405057316482734230273999651461753587376586889481054653237298\",\"20875820196105056284418196645437121025521090457969915100313025042226816593058\",\"7981401722738051151242865671764881670381691410051713896829121611466467295296\",\"12686075888445000028034879614337002534166281820554518240319859431277458776808\",\"14407479994300627796369211860752956065461957169462957624471349543175814297361\",\"12876099927862331079950419893066049696538807114168859906501896216679946602822\",\"5034430740274171017815797630858587451285547946739275122278422412563124952340\",\"124908299050395035311905641407789814479238558810338620545288553719611907579\",\"2220350286514662949665617433093307231741026918951518572442081261648362984066\",\"21054071841429471407849176541802267087608621767405046215729266220057231321239\",\"18615459511690451805285056890862312778437329715516723596790967668107849472332\",\"11005834873878236310149874426944776526137242691148625759790072174524730632293\",\"7750466501575524692208442425341714971523444376628469247291115085823741362258\",\"2825614199585564216616864222833372928389506766845048349547149599270041996580\",\"20178939917842893412863622473123830356625340961044353255941385554773117435807\",\"15457105913874757357155517217216962392853062937896722147907639311387695489612\",\"5769570513706963538956166571458035734925811338270969027092827256594315896305\",\"6944618873207772930654947866168069208208574383743967671528812057261674809023\",\"481787392403338571656555722870122978065125892949434958835001773033712625191\",\"629022117628670814916597453011668822767584986875266116143558377822126606210\",\"3477506405023338639718612883193130086582505996283986141234891023161625314400\",\"10391239348681537631698595933529223926008268217047488115607852208836329547314\",\"17714411760364866672536495662484312224393687256599208863125247267615177780962\",\"8235397798041831527134655625941532067772455314854641402993505266475178259142\",\"15400445794279992494417489709867566126537687907753955918275441261129856435204\",\"18390538379285507212129312705208118101486722955290795425636438098737923067560\",\"15884158870062763074209623120979824036430500099471957276287699843774740810060\",\"9761474784835077830881823851138622604776507060902897946796201272804305644780\",\"10691342730033436831098118713873643843887824911850191956325145412899736489783\",\"5383646477412575449009401478396232205746537027068927954390800800393113212132\",\"11221442935955024550310715250831163771206851175519681722264731998826151062912\",\"5908215522026944047821144963285306601790999208803054898792188809472216445547\",\"19125477641235279033749474384585292663869320556945218215852551798484901700632\",\"21131596906673841534294586137917770250418344721734587506304435102735580889655\",\"5546854205853827616610180972262457239247839686812479293725221982292586246857\",\"765319165068330175794491754566055878846660871087781618280248834367406785408\",\"9065563084454046530671534818701959328556136219713201237904842104821385096277\",\"11685470115846281888274197814651339961028617777494077059927246879793227459012\",\"2276790636588619756427393596069501098393513502175223999114797598139979501715\"],[\"18261435412082991275184532065290531009107742677653928657546608300990409875179\",\"9319096001557865141309312824962941754323190215020661725351078769489865210042\",\"19426464515945862948128564234105343408552273980845098594209919356069483229628\",\"4821438189762812946550415462056480603193509374059280985662653954928168448767\",\"5172906179275109031852701363533115355308886025681591977544612584826814597738\",\"3030902410998504999074059222657043445867065651115237138539258929106073952351\",\"14984550843964273185801085401106206042254593799102067736545138712711200363110\",\"4913017693235246056337618677701835414584892336316530224150731143499438377822\",\"20331547282693860184739325401078246632991653782842932001956973617899699067126\",\"7600383600608310101623426738393844905406553598472129359788500052979517101086\",\"21052687276768682440237728714031588951028862448534763565173935420275983308030\",\"8624573291232390725167327242752231606002232362298782976538648069452315809692\",\"8822425521071097948786926466502634257594788443097595142360595191654091518800\",\"19870347064194260309549332912586515029667844641153191360540616815967059032631\",\"20465460310501582547409465331218341819661912832562849210077024323229630431309\",\"8822852684497325396969645265731037061910702688625880340802544167587243049164\",\"4478528672717298316804099458930548551969390361723990676862003909749451604942\",\"17325287090866702355475285665146878940121103201057390207999938983310817624720\",\"19625874220796709797520370627316734190983871032135923532916997267931941944017\",\"4971210922480782538363635536321057597816923124821190325639868004751176123095\"],[\"4116500508658592197045562123902818266144060908634297057533152651751621275415\",\"6279942219928883797763183575386930078658513224739644044432142134698996392345\",\"17873714886463212348626929321462768984929311072311394677407846329308137071177\",\"1780903854488782716523110881333093026159313079337979149518816941412656424372\",\"20050373159836077479057811893536206817195523291436452658040605882811525003132\",\"5410620983195375911090727814270361454832036795917695206544043001420960637777\",\"11266551165651302260349077780564641889328703387362942837789171445336788206333\",\"3608626782139895235764576982540708534353226535204704760149123479387449221471\",\"3145665689117343568678004953880446893036465022181894889004516583481449637793\",\"8073537774997617083133123196297054007342256527983221664627563913756598041137\"],[\"16950176155260599508276620633155897140104757247891462208942656524243675299741\",\"4384637840548698893518161520012906111962786493558848227457354530627659879521\",\"5124677781615023074976959243179487140944992271935523984403489366636038434778\",\"12988207380549681248970615897816015977834414112005771449262709089864569444208\",\"4960783735404364608985140352905530473941590990406201882678348579000881422078\"],[\"20387009608350563521735170556423317268483084337333204688511143658578884542027\",\"19972334535313243417117998358484532425461333194385844246074835217244635372928\",\"4960783735404364608985140352905530473941590990406201882678348579000881422078\"],[\"1003947683617565493626440885069112088208918036484637499642204220769104979880\",\"4960783735404364608985140352905530473941590990406201882678348579000881422078\"],[\"17493683025876340868978454534142017149014501237522261427894104407551129583657\"]]" diff --git a/contracts/test/utils/types.ts b/contracts/test/utils/types.ts index f5482ff81..3f1ef2539 100644 --- a/contracts/test/utils/types.ts +++ b/contracts/test/utils/types.ts @@ -3,20 +3,34 @@ import type { PassportData } from "@selfxyz/common/utils/types"; import type { PublicSignals, Groth16Proof } from "snarkjs"; -// Contract imports import { IdentityVerificationHub, IdentityVerificationHubImplV1, + IdentityVerificationHubImplV2, IdentityRegistry, IdentityRegistryImplV1, -} from "../../typechain-types"; - -import type { + IdentityRegistryIdCardImplV1, + TestSelfVerificationRoot, + Verifier_vc_and_disclose_staging as LocalVerifier, + Verifier_vc_and_disclose_id_staging as LocalIdCardVerifier, + Verifier_vc_and_disclose as ProdVerifier, + Verifier_vc_and_disclose_id as ProdIdCardVerifier, + Verifier_register_sha256_sha256_sha256_rsa_65537_4096 as ProdRegisterVerifier, + Verifier_register_sha256_sha256_sha256_rsa_65537_4096_staging as LocalRegisterVerifier, + Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096 as ProdIdCardRegisterVerifier, + Verifier_register_id_sha256_sha256_sha256_rsa_65537_4096_staging as LocalIdCardRegisterVerifier, + Verifier_dsc_sha256_rsa_65537_4096 as ProdDscVerifier, + Verifier_dsc_sha256_rsa_65537_4096_staging as LocalDscVerifier, IIdentityVerificationHubV1, + IIdentityVerificationHubV2, + IIdentityRegistryIdCardV1, + IIdentityRegistryV1, IRegisterCircuitVerifier, IDscCircuitVerifier, IVcAndDiscloseCircuitVerifier, -} from "../../typechain-types/contracts/IdentityVerificationHubImplV1"; +} from "../../typechain-types"; + +import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common"; export type PassportProof = IIdentityVerificationHubV1.PassportProofStruct; export type RegisterCircuitProof = IRegisterCircuitVerifier.RegisterCircuitProofStruct; @@ -24,19 +38,17 @@ export type DscCircuitProof = IDscCircuitVerifier.DscCircuitProofStruct; export type VcAndDiscloseHubProof = IIdentityVerificationHubV1.VcAndDiscloseHubProofStruct; export type VcAndDiscloseProof = IVcAndDiscloseCircuitVerifier.VcAndDiscloseProofStruct; -// Verifier type imports -import type { Verifier_vc_and_disclose as ProdVerifier } from "../../typechain-types/contracts/verifiers/disclose/Verifier_vc_and_disclose"; -import type { Verifier_vc_and_disclose as LocalVerifier } from "../../typechain-types/contracts/verifiers/local/disclose/Verifier_vc_and_disclose"; -import type { Verifier_register_rsa_65537_sha256_sha256_sha256_rsa_65537_4096 as ProdRegisterVerifier } from "../../typechain-types/contracts/verifiers/register/Verifier_register_rsa_65537_sha256_sha256_sha256_rsa_65537_4096"; -import type { Verifier_register_sha256_sha256_sha256_rsa_65537_4096 as LocalRegisterVerifier } from "../../typechain-types/contracts/verifiers/local/register/Verifier_register_sha256_sha256_sha256_rsa_65537_4096"; -import type { Verifier_dsc_rsa_65537_sha256_4096 as ProdDscVerifier } from "../../typechain-types/contracts/verifiers/dsc/Verifier_dsc_rsa_65537_sha256_4096"; -import type { Verifier_dsc_rsa_sha256_65537_4096 as LocalDscVerifier } from "../../typechain-types/contracts/verifiers/local/dsc/Verifier_dsc_rsa_sha256_65537_4096"; - // Type definitions export type VcAndDiscloseVerifier = typeof process.env.TEST_ENV extends "local" ? LocalVerifier : ProdVerifier; +export type VcAndDiscloseIdVerifier = typeof process.env.TEST_ENV extends "local" + ? LocalIdCardVerifier + : ProdIdCardVerifier; export type RegisterVerifier = typeof process.env.TEST_ENV extends "local" ? LocalRegisterVerifier : ProdRegisterVerifier; +export type IdCardRegisterVerifier = typeof process.env.TEST_ENV extends "local" + ? LocalIdCardRegisterVerifier + : ProdIdCardRegisterVerifier; export type DscVerifier = typeof process.env.TEST_ENV extends "local" ? LocalDscVerifier : ProdDscVerifier; export interface DeployedActors { @@ -53,12 +65,36 @@ export interface DeployedActors { mockPassport: PassportData; } +export interface DeployedActorsV2 { + hubImplV2: IdentityVerificationHubImplV2; + hub: IdentityVerificationHubImplV2; + registryImpl: IdentityRegistryImplV1; + registry: IdentityRegistryImplV1; + registryIdImpl: IdentityRegistryIdCardImplV1; + registryId: IdentityRegistryIdCardImplV1; + vcAndDisclose: VcAndDiscloseVerifier; + vcAndDiscloseId: VcAndDiscloseIdVerifier; + register: RegisterVerifier; + registerId: RegisterVerifierId; + dsc: DscVerifier; + dscId: DscVerifierId; + testSelfVerificationRoot: TestSelfVerificationRoot; + customVerifier: any; + owner: Signer; + user1: Signer; + user2: Signer; + mockPassport: PassportData; +} + // Contract type exports export type { IdentityVerificationHub, IdentityVerificationHubImplV1, + IdentityVerificationHubImplV2, IdentityRegistry, IdentityRegistryImplV1, + IdentityRegistryIdCardImplV1, + TestSelfVerificationRoot, Groth16Proof, PublicSignals, }; diff --git a/contracts/test/v2/discloseId.test.ts b/contracts/test/v2/discloseId.test.ts new file mode 100644 index 000000000..de9237e66 --- /dev/null +++ b/contracts/test/v2/discloseId.test.ts @@ -0,0 +1,899 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { generateVcAndDiscloseIdProof, getSMTs } from "../utils/generateProof"; +import { poseidon2 } from "poseidon-lite"; +import { generateCommitment } from "@selfxyz/common/utils/passports/passport"; +import { BigNumberish } from "ethers"; +import { generateRandomFieldElement, getStartOfDayTimestamp } from "../utils/utils"; +import { getPackedForbiddenCountries } from "@selfxyz/common/utils/contracts/forbiddenCountries"; +import { countries } from "@selfxyz/common/constants/countries"; +import { deploySystemFixturesV2 } from "../utils/deploymentV2"; +import { DeployedActorsV2 } from "../utils/types"; +import { Country3LetterCode } from "@selfxyz/common/constants/countries"; +import { hashEndpointWithScope } from "@selfxyz/common/utils/scope"; +import { createHash } from "crypto"; +import { ID_CARD_ATTESTATION_ID } from "@selfxyz/common/constants/constants"; +import { genMockIdDocAndInitDataParsing } from "@selfxyz/common/utils/passports/genMockIdDoc"; + +// Helper function to calculate user identifier hash (same as passport test) +function calculateUserIdentifierHash(userContextData: string): string { + const sha256Hash = createHash("sha256") + .update(Buffer.from(userContextData.slice(2), "hex")) + .digest(); + const ripemdHash = createHash("ripemd160").update(sha256Hash).digest(); + return "0x" + ripemdHash.toString("hex").padStart(40, "0"); +} + +describe("Self Verification Flow V2 - ID Card", () => { + let deployedActors: DeployedActorsV2; + let snapshotId: string; + let baseVcAndDiscloseProof: any; + let pristineBaseVcAndDiscloseProof: any; + let vcAndDiscloseProof: any; + let registerSecret: any; + let imt: any; + let commitment: any; + let nullifier: any; + let mockIdCardData: any; + + let forbiddenCountriesList: Country3LetterCode[]; + let forbiddenCountriesListPacked: string[]; + let verificationConfigV2: any; + let configId: string; + + before(async () => { + deployedActors = await deploySystemFixturesV2(); + + // Generate mock ID card data + mockIdCardData = genMockIdDocAndInitDataParsing({ + idType: "mock_id_card", + dgHashAlgo: "sha256", + eContentHashAlgo: "sha256", + signatureType: "rsa_sha256_65537_2048", + nationality: "USA", + birthDate: "920315", + expiryDate: "321231", + }); + + registerSecret = generateRandomFieldElement(); + nullifier = generateRandomFieldElement(); + commitment = generateCommitment(registerSecret, ID_CARD_ATTESTATION_ID.toString(), mockIdCardData); + + const attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + await deployedActors.registry + .connect(deployedActors.owner) + .devAddIdentityCommitment(attestationIdBytes32, nullifier, commitment); + + await deployedActors.registryId + .connect(deployedActors.owner) + .devAddIdentityCommitment(attestationIdBytes32, nullifier, commitment); + + const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); + // must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until version 3 + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); + imt = new LeanIMT(hashFunction); + await imt.insert(BigInt(commitment)); + + forbiddenCountriesList = [countries.AFGHANISTAN, "ABC", "CBA", "AAA"] as Country3LetterCode[]; + forbiddenCountriesListPacked = getPackedForbiddenCountries(forbiddenCountriesList); + + verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const tempUserContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(tempUserContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + baseVcAndDiscloseProof = await generateVcAndDiscloseIdProof( + registerSecret, + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + scopeAsBigIntString, + new Array(90).fill("1"), + "1", + imt, + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + pristineBaseVcAndDiscloseProof = structuredClone(baseVcAndDiscloseProof); + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + beforeEach(async () => { + baseVcAndDiscloseProof = structuredClone(pristineBaseVcAndDiscloseProof); + vcAndDiscloseProof = structuredClone(pristineBaseVcAndDiscloseProof); + + // Re-register the commitment after snapshot revert to ensure registry state is consistent + // Check if commitment already exists to avoid LeafAlreadyExists error + const currentRoot = await deployedActors.hub.getIdentityCommitmentMerkleRoot( + ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32), + ); + + if (currentRoot.toString() === "0") { + const attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + await deployedActors.registry + .connect(deployedActors.owner) + .devAddIdentityCommitment(attestationIdBytes32, nullifier, commitment); + + await deployedActors.registryId + .connect(deployedActors.owner) + .devAddIdentityCommitment(attestationIdBytes32, nullifier, commitment); + } + }); + + afterEach(async () => { + await ethers.provider.send("evm_revert", [snapshotId]); + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + describe("Complete V2 Verification Flow - ID Card", () => { + it("should complete full ID card verification flow with proper proof encoding", async () => { + // Use the already configured verificationConfigV2 and configId from before hook + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await deployedActors.testSelfVerificationRoot.resetTestState(); + + const tx = await deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData); + + await expect(tx).to.emit(deployedActors.testSelfVerificationRoot, "VerificationCompleted"); + + expect(await deployedActors.testSelfVerificationRoot.verificationSuccessful()).to.be.true; + + const lastOutput = await deployedActors.testSelfVerificationRoot.lastOutput(); + expect(lastOutput).to.not.equal("0x"); + + const expectedUserData = ethers.solidityPacked(["bytes"], [userData]); + const actualUserData = await deployedActors.testSelfVerificationRoot.lastUserData(); + expect(actualUserData).to.equal(expectedUserData); + }); + + it("should fail verification with invalid length of proofData", async () => { + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + // Create proofData with less than 32 bytes (invalid) + const invalidProofData = ethers.toUtf8Bytes("short"); // Only 5 bytes + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(invalidProofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "InvalidDataFormat"); + }); + + it("should fail verification with invalid length of userContextData", async () => { + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // Create userContextData with less than 96 bytes (invalid) + const invalidUserContextData = ethers.toUtf8Bytes("short_data"); // Only 10 bytes + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, invalidUserContextData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "InvalidDataFormat"); + }); + + it("should fail verification with invalid scope", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Create a separate commitment and register it + const scopeRegisterSecret = generateRandomFieldElement(); + const scopeNullifier = generateRandomFieldElement(); + const scopeCommitment = generateCommitment( + scopeRegisterSecret, + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + ); + + const attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + await deployedActors.registryId + .connect(deployedActors.owner) + .devAddIdentityCommitment(attestationIdBytes32, scopeNullifier, scopeCommitment); + + // Create IMT for this specific commitment + const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); + const scopeIMT = new LeanIMT(hashFunction); + await scopeIMT.insert(BigInt(scopeCommitment)); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + // Generate proof with a different scope (this will create a valid proof but with wrong scope) + const differentScopeFromHash = hashEndpointWithScope("different.com", "different-scope"); + const differentScopeAsBigInt = BigInt(differentScopeFromHash); + const differentScopeAsBigIntString = differentScopeAsBigInt.toString(); + + const differentScopeProof = await generateVcAndDiscloseIdProof( + scopeRegisterSecret, + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + differentScopeAsBigIntString, // Different scope + new Array(90).fill("1"), + "1", + scopeIMT, + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[differentScopeProof.a, differentScopeProof.b, differentScopeProof.c, differentScopeProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with ScopeMismatch because the proof has a different scope + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "ScopeMismatch"); + }); + + it("should fail verification with invalid user identifier", async () => { + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + // Create invalid userContextData by changing the user address to a different value + const invalidUserAddress = await deployedActors.user2.getAddress(); + const invalidUserContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(invalidUserAddress, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the original valid proof without modification + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with InvalidUserIdentifierInProof because the userContextData doesn't match the proof + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, invalidUserContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidUserIdentifierInProof"); + }); + + it("should fail verification with invalid root", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Create proof with invalid merkle root - for ID card, merkle root is at index 10 + const modifiedVcAndDiscloseProof = { ...vcAndDiscloseProof }; + modifiedVcAndDiscloseProof.pubSignals[10] = "999999999"; // ID card merkle root index is 10 + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [ + [ + modifiedVcAndDiscloseProof.a, + modifiedVcAndDiscloseProof.b, + modifiedVcAndDiscloseProof.c, + modifiedVcAndDiscloseProof.pubSignals, + ], + ], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidIdentityCommitmentRoot"); + }); + + it("should fail verification with invalid current date + 1 day", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Get current block timestamp and calculate future date + const currentBlock = await ethers.provider.getBlock("latest"); + const oneDayAfter = getStartOfDayTimestamp(currentBlock!.timestamp) + 24 * 60 * 60; + + const date = new Date(oneDayAfter * 1000); + const dateComponents = [ + Math.floor((date.getUTCFullYear() % 100) / 10), + date.getUTCFullYear() % 10, + Math.floor((date.getUTCMonth() + 1) / 10), + (date.getUTCMonth() + 1) % 10, + Math.floor(date.getUTCDate() / 10), + date.getUTCDate() % 10, + ]; + + // Modify the current date fields in the proof (index 11-16 for ID card) + for (let i = 0; i < 6; i++) { + vcAndDiscloseProof.pubSignals[11 + i] = dateComponents[i].toString(); + } + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CurrentDateNotInValidRange because the date is in the future + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CurrentDateNotInValidRange"); + }); + + it("should fail verification with invalid current date - 1 day", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Get current block timestamp and calculate past date + const currentBlock = await ethers.provider.getBlock("latest"); + const oneDayBefore = getStartOfDayTimestamp(currentBlock!.timestamp) - 1; + + const date = new Date(oneDayBefore * 1000); + const dateComponents = [ + Math.floor((date.getUTCFullYear() % 100) / 10), + date.getUTCFullYear() % 10, + Math.floor((date.getUTCMonth() + 1) / 10), + (date.getUTCMonth() + 1) % 10, + Math.floor(date.getUTCDate() / 10), + date.getUTCDate() % 10, + ]; + + // Modify the current date fields in the proof (index 11-16 for ID card) + for (let i = 0; i < 6; i++) { + vcAndDiscloseProof.pubSignals[11 + i] = dateComponents[i].toString(); + } + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CurrentDateNotInValidRange because the date is in the past + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CurrentDateNotInValidRange"); + }); + + it("should fail verification with invalid groth16 proof", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the valid proof but modify only the groth16 proof components + // but keep the pubSignals valid so it doesn't fail at earlier checks + const invalidGrothProof = { ...vcAndDiscloseProof }; + invalidGrothProof.a = ["999999999", "888888888"]; // Invalid proof components + invalidGrothProof.b = [ + ["777777777", "666666666"], + ["555555555", "444444444"], + ]; + invalidGrothProof.c = ["333333333", "222222222"]; + // Keep pubSignals unchanged so other validations pass + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[invalidGrothProof.a, invalidGrothProof.b, invalidGrothProof.c, invalidGrothProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with InvalidVcAndDiscloseProof because the groth16 proof is invalid + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidVcAndDiscloseProof"); + }); + + it("should fail verification with invalid attestation Id", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + // Use invalid attestation ID + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999999), 32); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [invalidAttestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWith("Invalid attestation ID"); + }); + + it("should fail verification with invalid ofac check", async () => { + // Create a completely separate proof and setup for OFAC failure + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, true, false] as [boolean, boolean, boolean], // ID card: [passport_no: false, name_dob: true, name_yob: false] + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the existing commitment and merkle root instead of creating new ones + // Get OFAC SMTs that will cause validation failure + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + // Generate proof that will fail OFAC verification (with ofacCheck = "0") using existing IMT + const ofacFailingProof = await generateVcAndDiscloseIdProof( + registerSecret, // Use existing registerSecret + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + scopeAsBigIntString, + new Array(90).fill("1"), + "1", + imt, // Use existing IMT + "20", + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + "0", // This will make OFAC verification fail + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[ofacFailingProof.a, ofacFailingProof.b, ofacFailingProof.c, ofacFailingProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidOfacCheck"); + }); + + it("should fail verification with invalid forbidden countries check", async () => { + // Create a completely separate proof and setup for forbidden countries failure + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], // Empty forbidden countries list + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], // All OFAC checks disabled + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the existing commitment and merkle root instead of creating new ones + // Get OFAC SMTs + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + // Generate proof with the original forbidden countries list (this will create a mismatch) using existing commitment + const forbiddenCountryProof = await generateVcAndDiscloseIdProof( + registerSecret, // Use existing registerSecret + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + scopeAsBigIntString, + new Array(90).fill("1"), + "1", + imt, // Use existing IMT + "20", + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + "1", + forbiddenCountriesList, // Use the original forbidden countries list (different from config) + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[forbiddenCountryProof.a, forbiddenCountryProof.b, forbiddenCountryProof.c, forbiddenCountryProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail because the forbidden countries list in the proof doesn't match the config + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidForbiddenCountries"); + }); + + it("should fail verification with invalid older than check", async () => { + // Create a verification config that requires age > 25, but generate proof with age 20 + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "25", // Require age > 25 (our proof will have age 20) + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], // All OFAC checks disabled + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the existing commitment and merkle root instead of creating new ones + // Get OFAC SMTs + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + // Generate proof with age 20 (which is less than required 25) using existing commitment + const youngerAgeProof = await generateVcAndDiscloseIdProof( + registerSecret, // Use existing registerSecret + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + scopeAsBigIntString, + new Array(90).fill("1"), + "1", + imt, // Use existing IMT + "20", // Age 20, which is less than required 25 + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + "1", + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[youngerAgeProof.a, youngerAgeProof.b, youngerAgeProof.c, youngerAgeProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail because age 20 is less than required 25 + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidOlderThan"); + }); + + it("should fail verification with invalid dest chain Id", async () => { + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], // All OFAC checks disabled + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + // Use an invalid destination chain ID that's different from current chain (31337) + const invalidDestChainId = ethers.zeroPadValue(ethers.toBeHex(999999), 32); + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [invalidDestChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + + // Use the existing commitment and merkle root instead of creating new ones + // Get OFAC SMTs + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + // Generate proof with the correct user identifier that matches the userContextData using existing commitment + const validProof = await generateVcAndDiscloseIdProof( + registerSecret, // Use existing registerSecret + ID_CARD_ATTESTATION_ID.toString(), + mockIdCardData, + scopeAsBigIntString, + new Array(90).fill("1"), + "1", + imt, // Use existing IMT + "20", + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + "1", + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[validProof.a, validProof.b, validProof.c, validProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CrossChainIsNotSupportedYet because destChainId (999999) != block.chainid (31337) + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CrossChainIsNotSupportedYet"); + }); + + it("should fail verification with invalid msg sender to call onVerificationSuccess", async () => { + const mockOutput = ethers.toUtf8Bytes("mock-verification-output"); + const mockUserData = ethers.toUtf8Bytes("mock-user-data"); + + // Try to call onVerificationSuccess directly from a non-hub address + await expect( + deployedActors.testSelfVerificationRoot + .connect(deployedActors.user1) + .onVerificationSuccess(mockOutput, mockUserData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "UnauthorizedCaller"); + + // Also test with owner account (should still fail) + await expect( + deployedActors.testSelfVerificationRoot + .connect(deployedActors.owner) + .onVerificationSuccess(mockOutput, mockUserData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "UnauthorizedCaller"); + }); + }); +}); diff --git a/contracts/test/v2/disclosePassport.test.ts b/contracts/test/v2/disclosePassport.test.ts new file mode 100644 index 000000000..5082488e9 --- /dev/null +++ b/contracts/test/v2/disclosePassport.test.ts @@ -0,0 +1,919 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { ATTESTATION_ID } from "../utils/constants"; +import { generateVcAndDiscloseProof, getSMTs } from "../utils/generateProof"; +import { poseidon2 } from "poseidon-lite"; +import { generateCommitment } from "@selfxyz/common/utils/passports/passport"; +import { BigNumberish } from "ethers"; +import { generateRandomFieldElement, getStartOfDayTimestamp } from "../utils/utils"; +import { getPackedForbiddenCountries } from "@selfxyz/common/utils/contracts/forbiddenCountries"; +import { countries } from "@selfxyz/common/constants/countries"; +import { deploySystemFixturesV2 } from "../utils/deploymentV2"; +import { DeployedActorsV2 } from "../utils/types"; +import { Country3LetterCode } from "@selfxyz/common/constants/countries"; +import { hashEndpointWithScope } from "@selfxyz/common/utils/scope"; +import { createHash } from "crypto"; + +// Helper function to format date for passport (YYMMDD format) +function formatDateForPassport(date: Date): string { + const year = date.getUTCFullYear().toString().slice(-2); // Get last 2 digits of year + const month = (date.getUTCMonth() + 1).toString().padStart(2, "0"); // Month is 0-indexed + const day = date.getUTCDate().toString().padStart(2, "0"); + return year + month + day; +} + +describe("Self Verification Flow V2", () => { + let deployedActors: DeployedActorsV2; + let snapshotId: string; + let baseVcAndDiscloseProof: any; + let pristineBaseVcAndDiscloseProof: any; + let vcAndDiscloseProof: any; + let registerSecret: any; + let imt: any; + let commitment: any; + let nullifier: any; + + let forbiddenCountriesList: Country3LetterCode[]; + let forbiddenCountriesListPacked: string[]; + let verificationConfigV2: any; + let configId: string; + + function calculateUserIdentifierHash(userContextData: string): string { + const sha256Hash = createHash("sha256") + .update(Buffer.from(userContextData.slice(2), "hex")) + .digest(); + const ripemdHash = createHash("ripemd160").update(sha256Hash).digest(); + return "0x" + ripemdHash.toString("hex").padStart(40, "0"); + } + + before(async () => { + deployedActors = await deploySystemFixturesV2(); + + // Take snapshot after deployment and balance setting + snapshotId = await ethers.provider.send("evm_snapshot", []); + + registerSecret = generateRandomFieldElement(); + nullifier = generateRandomFieldElement(); + commitment = generateCommitment(registerSecret, ATTESTATION_ID.E_PASSPORT, deployedActors.mockPassport); + + await deployedActors.registry + .connect(deployedActors.owner) + .devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); + + await deployedActors.registryId + .connect(deployedActors.owner) + .devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); + + const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); + imt = new LeanIMT(hashFunction); + await imt.insert(BigInt(commitment)); + + forbiddenCountriesList = [countries.AFGHANISTAN, "ABC", "CBA", "AAA"] as Country3LetterCode[]; + forbiddenCountriesListPacked = getPackedForbiddenCountries(forbiddenCountriesList); + + verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const tempUserContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(tempUserContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + baseVcAndDiscloseProof = await generateVcAndDiscloseProof( + registerSecret, + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + imt, + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + pristineBaseVcAndDiscloseProof = structuredClone(baseVcAndDiscloseProof); + }); + + beforeEach(async () => { + baseVcAndDiscloseProof = structuredClone(pristineBaseVcAndDiscloseProof); + vcAndDiscloseProof = structuredClone(pristineBaseVcAndDiscloseProof); + + // Re-register the commitment after snapshot revert to ensure registry state is consistent + // Check if commitment already exists to avoid LeafAlreadyExists error + const currentRoot = await deployedActors.hub.getIdentityCommitmentMerkleRoot(ATTESTATION_ID.E_PASSPORT); + + if (currentRoot.toString() === "0") { + await deployedActors.registry + .connect(deployedActors.owner) + .devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); + + await deployedActors.registryId + .connect(deployedActors.owner) + .devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment); + } + }); + + afterEach(async () => { + await ethers.provider.send("evm_revert", [snapshotId]); + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + describe("Complete V2 Verification Flow", () => { + it("should complete full verification flow with proper proof encoding", async () => { + // Use the already configured verificationConfigV2 and configId from before hook + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await deployedActors.testSelfVerificationRoot.resetTestState(); + + const tx = await deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData); + + await expect(tx).to.emit(deployedActors.testSelfVerificationRoot, "VerificationCompleted"); + + expect(await deployedActors.testSelfVerificationRoot.verificationSuccessful()).to.be.true; + + const lastOutput = await deployedActors.testSelfVerificationRoot.lastOutput(); + expect(lastOutput).to.not.equal("0x"); + + const expectedUserData = ethers.solidityPacked(["bytes"], [userData]); + const actualUserData = await deployedActors.testSelfVerificationRoot.lastUserData(); + expect(actualUserData).to.equal(expectedUserData); + }); + + it("should fail verification with invalid length of proofData", async () => { + // Use the already configured verificationConfigV2 and configId from before hook + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + // Create proofData with less than 32 bytes (invalid) + const invalidProofData = ethers.toUtf8Bytes("short"); // Only 5 bytes + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(invalidProofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "InvalidDataFormat"); + }); + + it("should fail verification with invalid length of userContextData", async () => { + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // Create userContextData with less than 96 bytes (invalid) + const invalidUserContextData = ethers.toUtf8Bytes("short_data"); // Only 10 bytes + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, invalidUserContextData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "InvalidDataFormat"); + }); + + it("should fail verification with invalid scope", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Create a separate commitment and register it + const scopeRegisterSecret = generateRandomFieldElement(); + const scopeNullifier = generateRandomFieldElement(); + const scopeCommitment = generateCommitment( + scopeRegisterSecret, + ATTESTATION_ID.E_PASSPORT, + deployedActors.mockPassport, + ); + + await deployedActors.registry + .connect(deployedActors.owner) + .devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, scopeNullifier, scopeCommitment); + + // Create IMT for this specific commitment + const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); + const scopeIMT = new LeanIMT(hashFunction); + await scopeIMT.insert(BigInt(scopeCommitment)); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + // Generate proof with a different scope (this will create a valid proof but with wrong scope) + const differentScopeFromHash = hashEndpointWithScope("different.com", "different-scope"); + const differentScopeAsBigInt = BigInt(differentScopeFromHash); + const differentScopeAsBigIntString = differentScopeAsBigInt.toString(); + + const differentScopeProof = await generateVcAndDiscloseProof( + scopeRegisterSecret, + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + differentScopeAsBigIntString, // Different scope + new Array(88).fill("1"), + "1", + scopeIMT, + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[differentScopeProof.a, differentScopeProof.b, differentScopeProof.c, differentScopeProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with ScopeMismatch because the proof has a different scope + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "ScopeMismatch"); + }); + + it("should fail verification with invalid user identifier", async () => { + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + // Create invalid userContextData by changing the user address to a different value + const invalidUserAddress = await deployedActors.user2.getAddress(); + const invalidUserContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(invalidUserAddress, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Use the original valid proof without modification + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with InvalidUserIdentifierInProof because the userContextData doesn't match the proof + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, invalidUserContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidUserIdentifierInProof"); + }); + + it("should fail verification with invalid root", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Create a separate commitment with a different secret to generate a different merkle root + const differentRegisterSecret = generateRandomFieldElement(); + const differentNullifier = generateRandomFieldElement(); + const differentCommitment = generateCommitment( + differentRegisterSecret, + ATTESTATION_ID.E_PASSPORT, + deployedActors.mockPassport, + ); + + // Create a new IMT with different commitment (different root) + const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]); + const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT); + const differentIMT = new LeanIMT(hashFunction); + await differentIMT.insert(BigInt(differentCommitment)); + + // Generate proof with different merkle root + const differentRootProof = await generateVcAndDiscloseProof( + differentRegisterSecret, + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + differentIMT, // Different IMT = different root + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[differentRootProof.a, differentRootProof.b, differentRootProof.c, differentRootProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidIdentityCommitmentRoot"); + }); + + it("should fail verification with invalid current date + 1 day", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Get current block timestamp and calculate future date + const currentBlock = await ethers.provider.getBlock("latest"); + const oneDayAfter = getStartOfDayTimestamp(currentBlock!.timestamp) + 24 * 60 * 60; + + const date = new Date(oneDayAfter * 1000); + const dateComponents = [ + Math.floor((date.getUTCFullYear() % 100) / 10), + date.getUTCFullYear() % 10, + Math.floor((date.getUTCMonth() + 1) / 10), + (date.getUTCMonth() + 1) % 10, + Math.floor(date.getUTCDate() / 10), + date.getUTCDate() % 10, + ]; + + // Modify the current date fields directly in the proof signals (index 10-15 for E_PASSPORT) + for (let i = 0; i < 6; i++) { + vcAndDiscloseProof.pubSignals[10 + i] = dateComponents[i].toString(); + } + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CurrentDateNotInValidRange because the date is in the future + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CurrentDateNotInValidRange"); + }); + + it("should fail verification with invalid current date - 1 day", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Get current block timestamp and calculate past date + const currentBlock = await ethers.provider.getBlock("latest"); + const oneDayBefore = getStartOfDayTimestamp(currentBlock!.timestamp) - 1; + + const date = new Date(oneDayBefore * 1000); + const dateComponents = [ + Math.floor((date.getUTCFullYear() % 100) / 10), + date.getUTCFullYear() % 10, + Math.floor((date.getUTCMonth() + 1) / 10), + (date.getUTCMonth() + 1) % 10, + Math.floor(date.getUTCDate() / 10), + date.getUTCDate() % 10, + ]; + + // Modify the current date fields directly in the proof signals (index 10-15 for E_PASSPORT) + for (let i = 0; i < 6; i++) { + vcAndDiscloseProof.pubSignals[10 + i] = dateComponents[i].toString(); + } + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CurrentDateNotInValidRange because the date is in the past + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CurrentDateNotInValidRange"); + }); + + it("should fail verification with invalid groth16 proof", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Use the valid proof but modify only the groth16 proof components to make it fail verification + // but keep the pubSignals valid so it doesn't fail at earlier checks + const invalidGrothProof = structuredClone(vcAndDiscloseProof); + invalidGrothProof.a = ["999999999", "888888888"]; // Invalid proof components + invalidGrothProof.b = [ + ["777777777", "666666666"], + ["555555555", "444444444"], + ]; + invalidGrothProof.c = ["333333333", "222222222"]; + // Keep pubSignals unchanged so other validations pass + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[invalidGrothProof.a, invalidGrothProof.b, invalidGrothProof.c, invalidGrothProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with InvalidVcAndDiscloseProof because the groth16 proof is invalid + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidVcAndDiscloseProof"); + }); + + it("should fail verification with invalid attestation Id", async () => { + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: forbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], + }; + + await deployedActors.hub.setVerificationConfigV2(verificationConfigV2); + const configId = await deployedActors.hub.generateConfigId(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + // Use invalid attestation ID + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999999), 32); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[vcAndDiscloseProof.a, vcAndDiscloseProof.b, vcAndDiscloseProof.c, vcAndDiscloseProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [invalidAttestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWith("Invalid attestation ID"); + }); + + it("should fail verification with invalid ofac check", async () => { + // Create a completely separate proof and setup for OFAC failure + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [true, true, true] as [boolean, boolean, boolean], // Enable OFAC checks + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Use the existing commitment and merkle root instead of creating new ones + // Get OFAC SMTs that will cause validation failure + const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs(); + + // Generate proof that will fail OFAC verification (with ofacCheck = "0") using existing IMT + const ofacFailingProof = await generateVcAndDiscloseProof( + registerSecret, // Use existing registerSecret + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + imt, // Use existing IMT + "20", + passportNo_smt, + nameAndDob_smt, + nameAndYob_smt, + "0", // This will make OFAC verification fail + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[ofacFailingProof.a, ofacFailingProof.b, ofacFailingProof.c, ofacFailingProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidOfacCheck"); + }); + + it("should fail verification with invalid forbidden countries check", async () => { + // Create a forbidden countries list that should NOT match the proof + const mismatchedForbiddenCountriesList = [ + countries.IRAN, // This should NOT match what's in the passport/proof + "ABC", + "CBA", + "AAA", + ] as Country3LetterCode[]; + const mismatchedForbiddenCountriesListPacked = getPackedForbiddenCountries(mismatchedForbiddenCountriesList); + + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: mismatchedForbiddenCountriesListPacked as [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + ], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Generate proof with the original forbidden countries list (this will create a mismatch) using existing commitment + const forbiddenCountryProof = await generateVcAndDiscloseProof( + registerSecret, // Use existing registerSecret + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + imt, // Use existing IMT + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, // Use the original forbidden countries list (different from config) + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[forbiddenCountryProof.a, forbiddenCountryProof.b, forbiddenCountryProof.c, forbiddenCountryProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail because the forbidden countries list in the proof doesn't match the config + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidForbiddenCountries"); + }); + + it("should fail verification with invalid older than check", async () => { + // Create a verification config that requires age > 25, but generate proof with age 20 + const verificationConfigV2 = { + olderThanEnabled: true, + olderThan: "25", // Require age > 25 (our proof will have age 20) + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const destChainId = ethers.zeroPadValue(ethers.toBeHex(31337), 32); + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [destChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Generate proof with age 20 (which is less than required 25) using existing commitment + const youngerAgeProof = await generateVcAndDiscloseProof( + registerSecret, // Use existing registerSecret + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + imt, // Use existing IMT + "20", // Age 20, which is less than required 25 + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[youngerAgeProof.a, youngerAgeProof.b, youngerAgeProof.c, youngerAgeProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail because age 20 is less than required 25 + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.customVerifier, "InvalidOlderThan"); + }); + + it("should fail verification with invalid dest chain Id", async () => { + const verificationConfigV2 = { + olderThanEnabled: false, + olderThan: "20", + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [0n, 0n, 0n, 0n] as [BigNumberish, BigNumberish, BigNumberish, BigNumberish], + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + await deployedActors.testSelfVerificationRoot.setVerificationConfig(verificationConfigV2); + + const user1Address = await deployedActors.user1.getAddress(); + const userData = ethers.toUtf8Bytes("test-user-data-for-verification"); + + // Use an invalid destination chain ID that's different from current chain (31337) + const invalidDestChainId = ethers.zeroPadValue(ethers.toBeHex(999999), 32); + const userContextData = ethers.solidityPacked( + ["bytes32", "bytes32", "bytes"], + [invalidDestChainId, ethers.zeroPadValue(user1Address, 32), userData], + ); + + const userIdentifierHash = calculateUserIdentifierHash(userContextData); + const userIdentifierBigInt = BigInt(userIdentifierHash); + + const expectedScopeFromHash = hashEndpointWithScope("example.com", "test-scope"); + const scopeAsBigInt = BigInt(expectedScopeFromHash); + const scopeAsBigIntString = scopeAsBigInt.toString(); + + const attestationId = ethers.zeroPadValue(ethers.toBeHex(BigInt(ATTESTATION_ID.E_PASSPORT)), 32); + + // Generate proof with the correct user identifier that matches the userContextData using existing commitment + const validProof = await generateVcAndDiscloseProof( + registerSecret, // Use existing registerSecret + BigInt(ATTESTATION_ID.E_PASSPORT).toString(), + deployedActors.mockPassport, + scopeAsBigIntString, + new Array(88).fill("1"), + "1", + imt, // Use existing IMT + "20", + undefined, + undefined, + undefined, + undefined, + forbiddenCountriesList, + userIdentifierBigInt.toString(16).padStart(64, "0"), + ); + + const encodedProof = ethers.AbiCoder.defaultAbiCoder().encode( + ["tuple(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[21] pubSignals)"], + [[validProof.a, validProof.b, validProof.c, validProof.pubSignals]], + ); + + const proofData = ethers.solidityPacked(["bytes32", "bytes"], [attestationId, encodedProof]); + + // This should fail with CrossChainIsNotSupportedYet because destChainId (999999) != block.chainid (31337) + await expect( + deployedActors.testSelfVerificationRoot.verifySelfProof(proofData, userContextData), + ).to.be.revertedWithCustomError(deployedActors.hub, "CrossChainIsNotSupportedYet"); + }); + + it("should fail verification with invalid msg sender to call onVerificationSuccess", async () => { + const mockOutput = ethers.toUtf8Bytes("mock-verification-output"); + const mockUserData = ethers.toUtf8Bytes("mock-user-data"); + + // Try to call onVerificationSuccess directly from a non-hub address + await expect( + deployedActors.testSelfVerificationRoot + .connect(deployedActors.user1) + .onVerificationSuccess(mockOutput, mockUserData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "UnauthorizedCaller"); + + // Also test with owner account (should still fail) + await expect( + deployedActors.testSelfVerificationRoot + .connect(deployedActors.owner) + .onVerificationSuccess(mockOutput, mockUserData), + ).to.be.revertedWithCustomError(deployedActors.testSelfVerificationRoot, "UnauthorizedCaller"); + }); + }); +}); diff --git a/contracts/test/v2/hubOther.test.ts b/contracts/test/v2/hubOther.test.ts new file mode 100644 index 000000000..b9ee2a38d --- /dev/null +++ b/contracts/test/v2/hubOther.test.ts @@ -0,0 +1,186 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { deploySystemFixturesV2 } from "../utils/deploymentV2"; +import { DeployedActorsV2 } from "../utils/types"; +import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common/constants/constants"; +import { ID_CARD_ATTESTATION_ID, PASSPORT_ATTESTATION_ID } from "@selfxyz/common/constants/constants"; + +describe("Hub Other Functions Test", function () { + this.timeout(0); + + let deployedActors: DeployedActorsV2; + let snapshotId: string; + let attestationIdBytes32: string; + let ePassportAttestationIdBytes32: string; + + before(async () => { + // Deploy contracts and setup initial state + deployedActors = await deploySystemFixturesV2(); + attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + ePassportAttestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(PASSPORT_ATTESTATION_ID)), 32); + + console.log("🎉 System deployment and initial setup completed!"); + }); + + beforeEach(async () => { + // Take snapshot before each test + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + afterEach(async () => { + // Revert to snapshot after each test + await ethers.provider.send("evm_revert", [snapshotId]); + }); + + describe("Batch Update Functions Error Tests", () => { + it("should fail with LengthMismatch when arrays have different lengths in batchUpdateRegisterCircuitVerifiers", async () => { + const attestationIds = [attestationIdBytes32, ePassportAttestationIdBytes32]; + const typeIds = [1]; // Different length + const verifierAddresses = [ethers.ZeroAddress, ethers.ZeroAddress]; + + await expect( + deployedActors.hub.batchUpdateRegisterCircuitVerifiers(attestationIds, typeIds, verifierAddresses), + ).to.be.revertedWithCustomError(deployedActors.hub, "LengthMismatch"); + }); + + it("should fail with LengthMismatch when arrays have different lengths in batchUpdateDscCircuitVerifiers", async () => { + const attestationIds = [attestationIdBytes32]; + const typeIds = [1, 2]; // Different length + const verifierAddresses = [ethers.ZeroAddress]; + + await expect( + deployedActors.hub.batchUpdateDscCircuitVerifiers(attestationIds, typeIds, verifierAddresses), + ).to.be.revertedWithCustomError(deployedActors.hub, "LengthMismatch"); + }); + + it("should successfully batch update register circuit verifiers with matching array lengths", async () => { + const attestationIds = [attestationIdBytes32, ePassportAttestationIdBytes32]; + const typeIds = [1, 2]; + const verifierAddresses = [ethers.ZeroAddress, ethers.ZeroAddress]; + + await expect(deployedActors.hub.batchUpdateRegisterCircuitVerifiers(attestationIds, typeIds, verifierAddresses)) + .to.not.be.reverted; + }); + + it("should successfully batch update DSC circuit verifiers with matching array lengths", async () => { + const attestationIds = [attestationIdBytes32, ePassportAttestationIdBytes32]; + const typeIds = [1, 2]; + const verifierAddresses = [ethers.ZeroAddress, ethers.ZeroAddress]; + + await expect(deployedActors.hub.batchUpdateDscCircuitVerifiers(attestationIds, typeIds, verifierAddresses)).to.not + .be.reverted; + }); + }); + + describe("Access Control Tests", () => { + it("should fail when non-owner tries to call onlyOwner functions", async () => { + const nonOwnerHub = deployedActors.hub.connect(deployedActors.user1); + + await expect(nonOwnerHub.updateRegistry(attestationIdBytes32, ethers.ZeroAddress)).to.be.reverted; // Should revert due to onlyOwner modifier + + await expect(nonOwnerHub.updateVcAndDiscloseCircuit(attestationIdBytes32, ethers.ZeroAddress)).to.be.reverted; // Should revert due to onlyOwner modifier + + await expect(nonOwnerHub.updateRegisterCircuitVerifier(attestationIdBytes32, 1, ethers.ZeroAddress)).to.be + .reverted; // Should revert due to onlyOwner modifier + + await expect(nonOwnerHub.updateDscVerifier(attestationIdBytes32, 1, ethers.ZeroAddress)).to.be.reverted; // Should revert due to onlyOwner modifier + }); + }); + + describe("View Functions Tests", () => { + it("should return correct registry address", async () => { + const registryAddress = await deployedActors.hub.registry(attestationIdBytes32); + expect(registryAddress).to.equal(await deployedActors.registryId.getAddress()); + }); + + it("should return correct disclose verifier address", async () => { + const discloseVerifierAddress = await deployedActors.hub.discloseVerifier(attestationIdBytes32); + expect(discloseVerifierAddress).to.not.equal(ethers.ZeroAddress); + }); + + it("should return correct register circuit verifier address", async () => { + const registerVerifierAddress = await deployedActors.hub.registerCircuitVerifiers( + attestationIdBytes32, + RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096, + ); + expect(registerVerifierAddress).to.not.equal(ethers.ZeroAddress); + }); + + it("should return correct DSC circuit verifier address", async () => { + const dscVerifierAddress = await deployedActors.hub.dscCircuitVerifiers( + attestationIdBytes32, + DscVerifierId.dsc_sha256_rsa_65537_4096, + ); + expect(dscVerifierAddress).to.not.equal(ethers.ZeroAddress); + }); + + it("should return correct identity commitment merkle root", async () => { + const merkleRoot = await deployedActors.hub.getIdentityCommitmentMerkleRoot(attestationIdBytes32); + expect(merkleRoot).to.be.a("bigint"); + }); + + it("should fail getIdentityCommitmentMerkleRoot with InvalidAttestationId", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + + await expect( + deployedActors.hub.getIdentityCommitmentMerkleRoot(invalidAttestationId), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidAttestationId"); + }); + + it("should fail rootTimestamp with InvalidAttestationId", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + + await expect(deployedActors.hub.rootTimestamp(invalidAttestationId, 123)).to.be.revertedWithCustomError( + deployedActors.hub, + "InvalidAttestationId", + ); + }); + }); + + describe("Verification Config V2 Tests", () => { + it("should successfully set and retrieve verification config V2", async () => { + const config = { + olderThanEnabled: true, + olderThan: 18, + forbiddenCountriesEnabled: true, + forbiddenCountriesListPacked: [840, 156, 0, 0] as [number, number, number, number], // USA, China + ofacEnabled: [true, false, false] as [boolean, boolean, boolean], + }; + + const configId = await deployedActors.hub.setVerificationConfigV2.staticCall(config); + await expect(deployedActors.hub.setVerificationConfigV2(config)) + .to.emit(deployedActors.hub, "VerificationConfigV2Set") + .withArgs(configId, [ + config.olderThanEnabled, + config.olderThan, + config.forbiddenCountriesEnabled, + config.forbiddenCountriesListPacked, + config.ofacEnabled, + ]); + + const exists = await deployedActors.hub.verificationConfigV2Exists(configId); + expect(exists).to.be.true; + }); + + it("should generate consistent config IDs for the same config", async () => { + const config = { + olderThanEnabled: false, + olderThan: 21, + forbiddenCountriesEnabled: false, + forbiddenCountriesListPacked: [392, 0, 0, 0] as [number, number, number, number], // Japan + ofacEnabled: [false, false, false] as [boolean, boolean, boolean], + }; + + const generatedId = await deployedActors.hub.generateConfigId(config); + const staticCallId = await deployedActors.hub.setVerificationConfigV2.staticCall(config); + + expect(generatedId).to.equal(staticCallId); + }); + + it("should return false for non-existent config", async () => { + const nonExistentConfigId = ethers.randomBytes(32); + const exists = await deployedActors.hub.verificationConfigV2Exists(nonExistentConfigId); + expect(exists).to.be.false; + }); + }); +}); diff --git a/contracts/test/v2/registerId.test.ts b/contracts/test/v2/registerId.test.ts new file mode 100644 index 000000000..1d43c6d06 --- /dev/null +++ b/contracts/test/v2/registerId.test.ts @@ -0,0 +1,266 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { generateRandomFieldElement } from "../utils/utils"; +import { deploySystemFixturesV2 } from "../utils/deploymentV2"; +import { DeployedActorsV2 } from "../utils/types"; +import { generateDscProof, generateRegisterIdProof } from "../utils/generateProof"; +import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common/constants/constants"; +import serialized_dsc_tree from "@selfxyz/common/pubkeys/serialized_dsc_tree.json"; +import { + CIRCUIT_CONSTANTS, + ID_CARD_ATTESTATION_ID, + PASSPORT_ATTESTATION_ID, +} from "@selfxyz/common/constants/constants"; +import { genMockIdDocAndInitDataParsing } from "@selfxyz/common/utils/passports/genMockIdDoc"; + +describe("ID Registration test", function () { + this.timeout(0); + + let deployedActors: DeployedActorsV2; + let snapshotId: string; + let attestationIdBytes32: string; + let ePassportAttestationIdBytes32: string; + + before(async () => { + // Deploy contracts and setup initial state + deployedActors = await deploySystemFixturesV2(); + attestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(ID_CARD_ATTESTATION_ID)), 32); + ePassportAttestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(PASSPORT_ATTESTATION_ID)), 32); + + console.log("🎉 System deployment and initial setup completed!"); + }); + + beforeEach(async () => { + // Take snapshot before each test + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + afterEach(async () => { + // Revert to snapshot after each test + await ethers.provider.send("evm_revert", [snapshotId]); + }); + + describe("DSC Commitment Registration", () => { + let dscProof: any; + let idCardData: any; + + before(async () => { + // Generate DSC proof once for all tests in this describe block + idCardData = genMockIdDocAndInitDataParsing({ + idType: "mock_id_card", + dgHashAlgo: "sha256", + eContentHashAlgo: "sha256", + signatureType: "rsa_sha256_65537_2048", + nationality: "USA", + birthDate: "900101", + expiryDate: "301231", + }); + + dscProof = await generateDscProof(idCardData); + console.log("✅ DSC proof generated for DSC commitment tests"); + }); + + it("should successfully register DSC key commitment", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + const initialDscRoot = await deployedActors.registryId.getDscKeyCommitmentMerkleRoot(); + const initialTreeSize = await deployedActors.registryId.getDscKeyCommitmentTreeSize(); + + // Register the DSC key commitment + await expect( + deployedActors.hub.registerDscKeyCommitment(attestationIdBytes32, dscCircuitVerifierId, dscProof), + ).to.emit(deployedActors.registryId, "DscKeyCommitmentRegistered"); + + // Verify DSC was added to tree + const updatedDscRoot = await deployedActors.registryId.getDscKeyCommitmentMerkleRoot(); + const updatedTreeSize = await deployedActors.registryId.getDscKeyCommitmentTreeSize(); + + expect(updatedDscRoot).to.not.equal(initialDscRoot); + expect(updatedTreeSize).to.equal(initialTreeSize + 1n); + + // Verify the commitment is registered + const isRegistered = await deployedActors.registryId.isRegisteredDscKeyCommitment( + dscProof.pubSignals[CIRCUIT_CONSTANTS.DSC_TREE_LEAF_INDEX], + ); + expect(isRegistered).to.be.true; + }); + + it("should fail with NoVerifierSet when using non-existent verifier ID", async () => { + const nonExistentVerifierId = 999999; // Non-existent verifier ID + + await expect( + deployedActors.hub.registerDscKeyCommitment(attestationIdBytes32, nonExistentVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with NoVerifierSet when using invalid attestation ID (no verifier configured)", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + await expect( + deployedActors.hub.registerDscKeyCommitment(invalidAttestationId, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with InvalidAttestationId when verifier exists but attestation ID is invalid", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // First, set up a verifier for the invalid attestation ID + await deployedActors.hub.updateDscVerifier( + invalidAttestationId, + dscCircuitVerifierId, + await deployedActors.dsc.getAddress(), + ); + + // Now the call should fail with InvalidAttestationId since verifier exists but attestation ID is not valid + await expect( + deployedActors.hub.registerDscKeyCommitment(invalidAttestationId, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidAttestationId"); + }); + + it("should fail with InvalidDscProof when providing invalid proof", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // Create invalid proof by modifying the original + const invalidDscProof = { + ...dscProof, + a: ["0x1", "0x2"], // Invalid proof values + b: [ + ["0x1", "0x2"], + ["0x3", "0x4"], + ], + c: ["0x1", "0x2"], + }; + + await expect( + deployedActors.hub.registerDscKeyCommitment(attestationIdBytes32, dscCircuitVerifierId, invalidDscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidDscProof"); + }); + + it("should fail with InvalidCscaRoot when CSCA root doesn't match", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // Manipulate the CSCA root in the registry to make it invalid + await deployedActors.registryId.updateCscaRoot(12345); // Invalid CSCA root + + await expect( + deployedActors.hub.registerDscKeyCommitment(attestationIdBytes32, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidCscaRoot"); + }); + }); + + describe("Identity Commitment Registration", () => { + let registerProof: any; + let registerSecret: string; + let idCardData: any; + + before(async () => { + const dscKeys = JSON.parse(serialized_dsc_tree); + for (let i = 0; i < dscKeys[0].length; i++) { + await deployedActors.registryId.devAddDscKeyCommitment(BigInt(dscKeys[0][i])); + } + + // Generate identity commitment proof + idCardData = genMockIdDocAndInitDataParsing({ + idType: "mock_id_card", + dgHashAlgo: "sha256", + eContentHashAlgo: "sha256", + signatureType: "rsa_sha256_65537_2048", + nationality: "GBR", + birthDate: "920315", + expiryDate: "321231", + }); + + registerSecret = generateRandomFieldElement(); + registerProof = await generateRegisterIdProof(registerSecret, idCardData); + console.log("✅ Identity commitment proof generated for identity tests"); + }); + + it("should successfully register identity commitment", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Register the identity commitment + await expect( + deployedActors.hub.registerCommitment(attestationIdBytes32, registerCircuitVerifierId, registerProof), + ).to.emit(deployedActors.registryId, "CommitmentRegistered"); + + // Verify the commitment is registered by checking the nullifier + const isRegistered = await deployedActors.registryId.nullifiers( + attestationIdBytes32, + registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_NULLIFIER_INDEX], + ); + expect(isRegistered).to.be.true; + }); + + it("should fail with NoVerifierSet when using non-existent register verifier ID", async () => { + const nonExistentVerifierId = 999999; // Non-existent verifier ID + + await expect( + deployedActors.hub.registerCommitment(attestationIdBytes32, nonExistentVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with NoVerifierSet when using invalid attestation ID for register (no verifier configured)", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + await expect( + deployedActors.hub.registerCommitment(invalidAttestationId, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with InvalidAttestationId when register verifier exists but attestation ID is invalid", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // First, set up a verifier for the invalid attestation ID + await deployedActors.hub.updateRegisterCircuitVerifier( + invalidAttestationId, + registerCircuitVerifierId, + await deployedActors.register.getAddress(), + ); + + // Now the call should fail with InvalidAttestationId since verifier exists but attestation ID is not valid + await expect( + deployedActors.hub.registerCommitment(invalidAttestationId, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidAttestationId"); + }); + + it("should fail with InvalidRegisterProof when providing invalid register proof", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Create invalid proof by modifying the original + const invalidRegisterProof = { + ...registerProof, + a: ["0x1", "0x2"], // Invalid proof values + b: [ + ["0x1", "0x2"], + ["0x3", "0x4"], + ], + c: ["0x1", "0x2"], + }; + + await expect( + deployedActors.hub.registerCommitment(attestationIdBytes32, registerCircuitVerifierId, invalidRegisterProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidRegisterProof"); + }); + + it("should fail with InvalidDscCommitmentRoot when DSC commitment root doesn't match", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Create a new registry snapshot to restore later + const tempSnapshot = await ethers.provider.send("evm_snapshot", []); + + // Add an invalid DSC key commitment to change the root + await deployedActors.registryId.devAddDscKeyCommitment(BigInt(999999)); + + // The proof was generated with the original root, so it should fail + await expect( + deployedActors.hub.registerCommitment(attestationIdBytes32, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidDscCommitmentRoot"); + + // Restore the snapshot + await ethers.provider.send("evm_revert", [tempSnapshot]); + }); + }); +}); diff --git a/contracts/test/v2/registerPassport.test.ts b/contracts/test/v2/registerPassport.test.ts new file mode 100644 index 000000000..88d5b62b2 --- /dev/null +++ b/contracts/test/v2/registerPassport.test.ts @@ -0,0 +1,268 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; +import { generateRandomFieldElement } from "../utils/utils"; +import { deploySystemFixturesV2 } from "../utils/deploymentV2"; +import { DeployedActorsV2 } from "../utils/types"; +import { generateDscProof, generateRegisterProof } from "../utils/generateProof"; +import { DscVerifierId, RegisterVerifierId } from "@selfxyz/common/constants/constants"; +import serialized_dsc_tree from "@selfxyz/common/pubkeys/serialized_dsc_tree.json"; +import { CIRCUIT_CONSTANTS, PASSPORT_ATTESTATION_ID } from "@selfxyz/common/constants/constants"; +import { genMockIdDocAndInitDataParsing } from "@selfxyz/common/utils/passports/genMockIdDoc"; + +describe("Passport Registration test", function () { + this.timeout(0); + + let deployedActors: DeployedActorsV2; + let snapshotId: string; + let ePassportAttestationIdBytes32: string; + + before(async () => { + // Deploy contracts and setup initial state + deployedActors = await deploySystemFixturesV2(); + ePassportAttestationIdBytes32 = ethers.zeroPadValue(ethers.toBeHex(BigInt(PASSPORT_ATTESTATION_ID)), 32); + + console.log("🎉 System deployment and initial setup completed!"); + }); + + beforeEach(async () => { + // Take snapshot before each test + snapshotId = await ethers.provider.send("evm_snapshot", []); + }); + + afterEach(async () => { + // Revert to snapshot after each test + await ethers.provider.send("evm_revert", [snapshotId]); + }); + + describe("DSC Commitment Registration for Passport", () => { + let dscProof: any; + let passportData: any; + + before(async () => { + // Generate DSC proof once for all tests in this describe block + passportData = genMockIdDocAndInitDataParsing({ + idType: "mock_passport", + dgHashAlgo: "sha256", + eContentHashAlgo: "sha256", + signatureType: "rsa_sha256_65537_2048", + nationality: "USA", + birthDate: "900101", + expiryDate: "301231", + }); + + dscProof = await generateDscProof(passportData); + console.log("✅ DSC proof generated for passport DSC commitment tests"); + }); + + it("should successfully register DSC key commitment for passport", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + const initialDscRoot = await deployedActors.registry.getDscKeyCommitmentMerkleRoot(); + const initialTreeSize = await deployedActors.registry.getDscKeyCommitmentTreeSize(); + + // Register the DSC key commitment + await expect( + deployedActors.hub.registerDscKeyCommitment(ePassportAttestationIdBytes32, dscCircuitVerifierId, dscProof), + ).to.emit(deployedActors.registry, "DscKeyCommitmentRegistered"); + + // Verify DSC was added to tree + const updatedDscRoot = await deployedActors.registry.getDscKeyCommitmentMerkleRoot(); + const updatedTreeSize = await deployedActors.registry.getDscKeyCommitmentTreeSize(); + + expect(updatedDscRoot).to.not.equal(initialDscRoot); + expect(updatedTreeSize).to.equal(initialTreeSize + 1n); + + // Verify the commitment is registered + const isRegistered = await deployedActors.registry.isRegisteredDscKeyCommitment( + dscProof.pubSignals[CIRCUIT_CONSTANTS.DSC_TREE_LEAF_INDEX], + ); + expect(isRegistered).to.be.true; + }); + + it("should fail with NoVerifierSet when using non-existent verifier ID for passport", async () => { + const nonExistentVerifierId = 999999; // Non-existent verifier ID + + await expect( + deployedActors.hub.registerDscKeyCommitment(ePassportAttestationIdBytes32, nonExistentVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with NoVerifierSet when using invalid attestation ID for passport (no verifier configured)", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + await expect( + deployedActors.hub.registerDscKeyCommitment(invalidAttestationId, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with InvalidAttestationId when verifier exists but attestation ID is invalid for passport", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // First, set up a verifier for the invalid attestation ID + await deployedActors.hub.updateDscVerifier( + invalidAttestationId, + dscCircuitVerifierId, + await deployedActors.dsc.getAddress(), + ); + + // Now the call should fail with InvalidAttestationId since verifier exists but attestation ID is not valid + await expect( + deployedActors.hub.registerDscKeyCommitment(invalidAttestationId, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidAttestationId"); + }); + + it("should fail with InvalidDscProof when providing invalid proof for passport", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // Create invalid proof by modifying the original + const invalidDscProof = { + ...dscProof, + a: ["0x1", "0x2"], // Invalid proof values + b: [ + ["0x1", "0x2"], + ["0x3", "0x4"], + ], + c: ["0x1", "0x2"], + }; + + await expect( + deployedActors.hub.registerDscKeyCommitment( + ePassportAttestationIdBytes32, + dscCircuitVerifierId, + invalidDscProof, + ), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidDscProof"); + }); + + it("should fail with InvalidCscaRoot when CSCA root doesn't match for passport", async () => { + const dscCircuitVerifierId = DscVerifierId.dsc_sha256_rsa_65537_4096; + + // Manipulate the CSCA root in the registry to make it invalid + await deployedActors.registry.updateCscaRoot(12345); // Invalid CSCA root + + await expect( + deployedActors.hub.registerDscKeyCommitment(ePassportAttestationIdBytes32, dscCircuitVerifierId, dscProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidCscaRoot"); + }); + }); + + describe("Passport Identity Commitment Registration", () => { + let registerProof: any; + let registerSecret: string; + let passportData: any; + + before(async () => { + const dscKeys = JSON.parse(serialized_dsc_tree); + for (let i = 0; i < dscKeys[0].length; i++) { + await deployedActors.registry.devAddDscKeyCommitment(BigInt(dscKeys[0][i])); + } + + // Generate passport identity commitment proof using passport-specific function + passportData = genMockIdDocAndInitDataParsing({ + idType: "mock_passport", + dgHashAlgo: "sha256", + eContentHashAlgo: "sha256", + signatureType: "rsa_sha256_65537_2048", + nationality: "GBR", + birthDate: "920315", + expiryDate: "321231", + }); + + registerSecret = generateRandomFieldElement(); + registerProof = await generateRegisterProof(registerSecret, passportData); + console.log("✅ Passport identity commitment proof generated for passport identity tests"); + }); + + it("should successfully register passport identity commitment", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Register the passport identity commitment + await expect( + deployedActors.hub.registerCommitment(ePassportAttestationIdBytes32, registerCircuitVerifierId, registerProof), + ).to.emit(deployedActors.registry, "CommitmentRegistered"); + + // Verify the commitment is registered by checking the nullifier + const isRegistered = await deployedActors.registry.nullifiers( + ePassportAttestationIdBytes32, + registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_NULLIFIER_INDEX], + ); + expect(isRegistered).to.be.true; + }); + + it("should fail with NoVerifierSet when using non-existent passport register verifier ID", async () => { + const nonExistentVerifierId = 999999; // Non-existent verifier ID + + await expect( + deployedActors.hub.registerCommitment(ePassportAttestationIdBytes32, nonExistentVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with NoVerifierSet when using invalid attestation ID for passport register (no verifier configured)", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + await expect( + deployedActors.hub.registerCommitment(invalidAttestationId, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "NoVerifierSet"); + }); + + it("should fail with InvalidAttestationId when passport register verifier exists but attestation ID is invalid", async () => { + const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // First, set up a verifier for the invalid attestation ID + await deployedActors.hub.updateRegisterCircuitVerifier( + invalidAttestationId, + registerCircuitVerifierId, + await deployedActors.register.getAddress(), + ); + + // Now the call should fail with InvalidAttestationId since verifier exists but attestation ID is not valid + await expect( + deployedActors.hub.registerCommitment(invalidAttestationId, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidAttestationId"); + }); + + it("should fail with InvalidRegisterProof when providing invalid passport register proof", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Create invalid proof by modifying the original + const invalidRegisterProof = { + ...registerProof, + a: ["0x1", "0x2"], // Invalid proof values + b: [ + ["0x1", "0x2"], + ["0x3", "0x4"], + ], + c: ["0x1", "0x2"], + }; + + await expect( + deployedActors.hub.registerCommitment( + ePassportAttestationIdBytes32, + registerCircuitVerifierId, + invalidRegisterProof, + ), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidRegisterProof"); + }); + + it("should fail with InvalidDscCommitmentRoot when DSC commitment root doesn't match for passport", async () => { + const registerCircuitVerifierId = RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096; + + // Create a new registry snapshot to restore later + const tempSnapshot = await ethers.provider.send("evm_snapshot", []); + + // Add an invalid DSC key commitment to change the root + await deployedActors.registry.devAddDscKeyCommitment(BigInt(999999)); + + // The proof was generated with the original root, so it should fail + await expect( + deployedActors.hub.registerCommitment(ePassportAttestationIdBytes32, registerCircuitVerifierId, registerProof), + ).to.be.revertedWithCustomError(deployedActors.hub, "InvalidDscCommitmentRoot"); + + // Restore the snapshot + await ethers.provider.send("evm_revert", [tempSnapshot]); + }); + }); +}); diff --git a/sdk/tests/web-app/.yarnrc.yml b/contracts/yarnrc.yml similarity index 100% rename from sdk/tests/web-app/.yarnrc.yml rename to contracts/yarnrc.yml diff --git a/package.json b/package.json index bf160db6d..ef991d10a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "circuits", "contracts", "sdk/*", - "sdk/tests/*", "prover/tests" ], "scripts": { diff --git a/sdk/tests/api-server/.env.sample b/sdk/tests/api-server/.env.sample deleted file mode 100644 index d6a1d35a5..000000000 --- a/sdk/tests/api-server/.env.sample +++ /dev/null @@ -1,2 +0,0 @@ -RPC_URL=https://forno.celo.org -SCOPE=test-scope \ No newline at end of file diff --git a/sdk/tests/api-server/.gitignore b/sdk/tests/api-server/.gitignore deleted file mode 100644 index fb94ae776..000000000 --- a/sdk/tests/api-server/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -**/*.trace -**/*.zip -**/*.tar.gz -**/*.tgz -**/*.log -package-lock.json -**/*.bun - -.env \ No newline at end of file diff --git a/sdk/tests/api-server/README.md b/sdk/tests/api-server/README.md deleted file mode 100644 index 688c87e69..000000000 --- a/sdk/tests/api-server/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Elysia with Bun runtime - -## Getting Started -To get started with this template, simply paste this command into your terminal: -```bash -bun create elysia ./elysia-example -``` - -## Development -To start the development server run: -```bash -bun run dev -``` - -Open http://localhost:3000/ with your browser to see the result. \ No newline at end of file diff --git a/sdk/tests/api-server/bun.lockb b/sdk/tests/api-server/bun.lockb deleted file mode 100755 index dea8b1fcb..000000000 Binary files a/sdk/tests/api-server/bun.lockb and /dev/null differ diff --git a/sdk/tests/api-server/package.json b/sdk/tests/api-server/package.json deleted file mode 100644 index 8dc306cbd..000000000 --- a/sdk/tests/api-server/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "backend-api", - "version": "1.0.50", - "module": "index.ts", - "scripts": { - "dev": "bun run --watch src/app.ts", - "init": "bash scripts/copy_abi.sh && bash scripts/copy_deployedAddress.sh", - "start:daemon": "bun run src/app.ts > app.log 2>&1 &", - "stop:daemon": "pkill -f 'bun run src/app.ts'", - "test": "echo \"Error: no test specified\" && exit 1", - "types": "tsc --noEmit" - }, - "dependencies": { - "@elysiajs/swagger": "^1.2.0", - "@openpassport/zk-kit-imt": "^0.0.5", - "@openpassport/zk-kit-lean-imt": "^0.0.6", - "@selfxyz/core": "^0.0.3", - "dotenv": "^16.4.7", - "elysia": "latest", - "logixlysia": "^4.1.1", - "pg": "^8.13.1", - "poseidon-lite": "^0.3.0", - "snarkjs": "^0.7.5", - "swagger": "^0.7.5", - "viem": "^2.22.23" - }, - "devDependencies": { - "@types/pg": "^8.11.11", - "bun-types": "latest", - "typescript": "^5.8.3" - } -} diff --git a/sdk/tests/api-server/src/app.routes.ts b/sdk/tests/api-server/src/app.routes.ts deleted file mode 100644 index 3870e30ed..000000000 --- a/sdk/tests/api-server/src/app.routes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Elysia from 'elysia'; - -import { ContractsController } from './contracts/infrastructure/contracts.controller'; - -const routes = new Elysia({ prefix: 'api/v1' }) - .use(ContractsController); - -export { routes as AppRoutes }; \ No newline at end of file diff --git a/sdk/tests/api-server/src/app.ts b/sdk/tests/api-server/src/app.ts deleted file mode 100644 index 34f2c3836..000000000 --- a/sdk/tests/api-server/src/app.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Elysia } from "elysia"; -import swagger from "@elysiajs/swagger"; -import logger from "logixlysia"; -import { AppRoutes } from "./app.routes.js"; -import dotenv from "dotenv"; - -dotenv.config(); - -const app = new Elysia() - .use(logger()) - .use( - swagger({ - exclude: ['/swagger'], - autoDarkMode: true, - documentation: { - info: { - title: 'backend-api', - description: - 'backend api to interact with the contracts', - version: '1.0.0', - }, - }, - }), - ) - .use(AppRoutes); - -app.listen({ port: process.env.PORT }); - -console.log( - `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`, -); \ No newline at end of file diff --git a/sdk/tests/api-server/src/contracts/infrastructure/contracts.controller.ts b/sdk/tests/api-server/src/contracts/infrastructure/contracts.controller.ts deleted file mode 100644 index 17aca6cff..000000000 --- a/sdk/tests/api-server/src/contracts/infrastructure/contracts.controller.ts +++ /dev/null @@ -1,52 +0,0 @@ -import Elysia, { t } from 'elysia'; -import { SelfBackendVerifier } from "@selfxyz/core"; - -export const ContractsController = new Elysia() - .post( - 'verify-vc-and-disclose-proof', - async (request: any) => { - try { - const selfBackendVerifier = new SelfBackendVerifier( - process.env.RPC_URL as string, - process.env.SCOPE as string, - ); - - const result = await selfBackendVerifier.verify( - request.body.proof, - request.body.publicSignals - ); - console.log(result); - - return { - status: "success", - result: result.isValid, - }; - } catch (error) { - return { - status: "error", - message: error instanceof Error ? error.message : "Unknown error", - }; - } - }, - { - body: t.Object({ - proof: t.Any(), - publicSignals: t.Any(), - }), - response: { - 200: t.Object({ - status: t.String(), - result: t.Boolean(), - }), - 500: t.Object({ - status: t.String(), - message: t.String(), - }), - }, - detail: { - tags: ['Contracts'], - summary: 'Verify a VC and disclose a proof', - description: 'Verify a VC and disclose a proof', - }, - }, - ); diff --git a/sdk/tests/api-server/tsconfig.json b/sdk/tests/api-server/tsconfig.json deleted file mode 100644 index 9facb1cae..000000000 --- a/sdk/tests/api-server/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2021", - "module": "NodeNext", - "moduleResolution": "nodenext", - "types": [ - "bun-types" - ], - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true, - "resolveJsonModule": true - } -} diff --git a/sdk/tests/web-app/.env.sample b/sdk/tests/web-app/.env.sample deleted file mode 100644 index 61b90ed7e..000000000 --- a/sdk/tests/web-app/.env.sample +++ /dev/null @@ -1,2 +0,0 @@ -END_POINT= -SCOPE= \ No newline at end of file diff --git a/sdk/tests/web-app/.eslintrc.json b/sdk/tests/web-app/.eslintrc.json deleted file mode 100644 index 372241854..000000000 --- a/sdk/tests/web-app/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["next/core-web-vitals", "next/typescript"] -} diff --git a/sdk/tests/web-app/.gitignore b/sdk/tests/web-app/.gitignore deleted file mode 100644 index b9f8d23e8..000000000 --- a/sdk/tests/web-app/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -.env \ No newline at end of file diff --git a/sdk/tests/web-app/README.md b/sdk/tests/web-app/README.md deleted file mode 100644 index e215bc4cc..000000000 --- a/sdk/tests/web-app/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/sdk/tests/web-app/next.config.mjs b/sdk/tests/web-app/next.config.mjs deleted file mode 100644 index 4678774e6..000000000 --- a/sdk/tests/web-app/next.config.mjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = {}; - -export default nextConfig; diff --git a/sdk/tests/web-app/package.json b/sdk/tests/web-app/package.json deleted file mode 100644 index f0b5ac853..000000000 --- a/sdk/tests/web-app/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "test-web-app", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "build": "next build", - "dev": "next dev", - "lint": "next lint", - "start": "next start", - "types": "yarn build" - }, - "dependencies": { - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/material": "^6.0.2", - "@selfxyz/common": "workspace:^", - "@selfxyz/qrcode": "workspace:^", - "axios": "^1.7.7", - "next": "14.2.8", - "react": "^18", - "react-dom": "^18", - "uuid": "^11.1.0" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "eslint": "^8", - "eslint-config-next": "14.2.8", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "typescript": "^5" - } -} diff --git a/sdk/tests/web-app/postcss.config.mjs b/sdk/tests/web-app/postcss.config.mjs deleted file mode 100644 index 1a69fd2a4..000000000 --- a/sdk/tests/web-app/postcss.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('postcss-load-config').Config} */ -const config = { - plugins: { - tailwindcss: {}, - }, -}; - -export default config; diff --git a/sdk/tests/web-app/src/app/api/verify/route.ts b/sdk/tests/web-app/src/app/api/verify/route.ts deleted file mode 100644 index 3a84e9b45..000000000 --- a/sdk/tests/web-app/src/app/api/verify/route.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { SelfBackendVerifier } from '@selfxyz/core'; -import { NextResponse } from 'next/server'; -import { countries } from '@selfxyz/common/constants/countries'; - -export async function POST(request: Request) { - try { - const body = await request.json(); - const { proof, publicSignals } = body; - - if (!proof || !publicSignals) { - return NextResponse.json( - { message: 'Proof and publicSignals are required' }, - { status: 400 } - ); - } - - const configuredVerifier = new SelfBackendVerifier( - 'https://forno.celo.org', - "self-workshop", - 'uuid', - ) - .setMinimumAge(18) - .excludeCountries( - countries.RUSSIA, - countries.CHINA, - countries.NORTH_KOREA, - countries.IRAN - ) - .setNationality(countries.JAPAN); - - const result = await configuredVerifier.verify(proof, publicSignals); - console.log("Verification result:", result); - - if (result.isValid) { - return NextResponse.json({ - status: 'success', - result: result.isValid, - credentialSubject: result.credentialSubject - }); - } else { - return NextResponse.json({ - status: 'error', - result: result.isValid, - message: 'Verification failed', - details: result.isValidDetails - }, { status: 400 }); - } - } catch (error) { - console.error('Error verifying proof:', error); - return NextResponse.json({ - message: 'Error verifying proof', - error: error instanceof Error ? error.message : 'Unknown error' - }, { status: 500 }); - } -} diff --git a/sdk/tests/web-app/src/app/disclose/logo.ts b/sdk/tests/web-app/src/app/disclose/logo.ts deleted file mode 100644 index 99557e1f6..000000000 --- a/sdk/tests/web-app/src/app/disclose/logo.ts +++ /dev/null @@ -1 +0,0 @@ -export const logo = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAG7AAABuwBHnU4NQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z15nCRHded/LyIz6+prqqen5z40mkMCHRYCxEgCpltCQgXiWGkkQMyMWCOvi2Xxmj2wsRdj88Felo+NvXbj9QG6QDBoDcZum0sSQhdgscYcQiOE0EzrnBnVHH1VZWZE7B/VPdNHHRlZmVlZ3fn9fPSB6c7IiJmq+MWLFy/eI6UUEqLh8et37SKiD0+UK9e/4quPTrV7PAkJrN0DWC78/LrLX01E/wzgmq506h+evnl3ut1jSkhIBCACDl532cWSya8D6Jn50VBl0v7Kk9dck2rnuBISEgEImceuu+xlYOobAHoX/Ooq0XXyAIioHeNKSAASAQgXIuJM/TWAFXWeuPbx63fti3JICQlzSQQgRJ647tJ/D+A1jZ4h4BM/ftfl9QQiISFUEgEIicff/up+ReqPPDw6YLnqD0MfUEJCDRIBCAtu/CGAfk/PKvXeg9dddnG4A0pIWEwiACHw5E2X9BBhr0YTBq6KoQ0oIaEOiQCEgHD4tQD0jvgU3vqDX7vYDGdECQm1SQQgBEjhBh/NVvQcT70h8MEkJDQgEYCAefptu/sU4GsiC6I9QY8nIaERiQAETNlwhgBYftqSUm8MeDgJCQ1JBCBgCHJjC80HkjsCCVGSCEDgsHWttHan7ZbaJyTokAhAwBBUawIg1fqgxpKQ0IxEAAJGElpdwRMLICEyEgEIGAKS230JHUMiAIFDYy2+4NlAhpGQ4IFEAIJGqZYEQCYCkBAhiQAEDLHWBKAnIgE4uOfSZKuSAKPdA1hqSIlDLeT4Obb+wMPTAQ5nEYf27j5XSvW3RPSqn994mWCMvWAY/JpNt9/3kzD7TYgniQUQMGSz+wFUfDVW+Fqwo5nP2L6hd1cqzk9s27lEKcWkVKbrig227fxwbN9QIcy+E+JJIgABs+PvHxwH8HU/bRXUFwMezmnG9g29e7ps36aUWmSfSKm4K+Qnw+o7Ib4kAhAGhC/5aHVC0qlvBD4WAGP7hm6qN/lncRx3xzM3Dy9MXJqwxEkEIAS4Kb4K3W0A4cvnHviJHfRYDu8beud02b690eQHAKUUKYXdQfefEG8SAQiBs+/87ikQPq/RRELQSNDjOLxv6B3lsn1ns8l/GqXOD3oMCfEmEYCQMBx8CMBxL88S8Dc77n7w0SD7n5n8n/M8+QEo4Owgx5AQfxIBCImtf/fQEQAf9vDoSy7UbwXZ9+F9QzfqTn7D4Mhm0+NBjiMh/iQCECI7Xvbw/wHwL42eIUUfOvfAw6Wg+jy8b+iGctn+vM7kZ4yhtycHRpRcRFpmJAIQJh9Rkhh7L4BTtR+gr22/+6G/Daq7sf3DbyyX7bt0Jj8RVSc/YwCwJaixJHQGiQCEzPYvPPBvCrgawELz+t4c5NsRUH32Z26+YmOlYv+9zuQHgJ7uHAyDz/4xEYBlRiIAEbDzwEOPENg1gJqc+dEDlXTXtUGF/Y7tHzZs23lUCKmVVry7KwvLmhcN3l0qFvJBjCmhM0gEICK2H3jgQQUUANyDChXOv/3rk00beUQI8YDjuAM6bbKZFNLpmrlLLwxmVAmdQHIZKEJ2Hnj4fgD3B/nOQ3t3f6pScS7RaZOyTORymXq/fg2Ae1semE+euPHyC5SUH62ku94VpEgm1CaxADqYw/uGrq9UnA/otDEMju7ubKNHdrU2Kv88dt1lL1NSfgvAW1LlidEfXHtxw4EmtA4F5INKiJjD+4a2VyrOT6WUnq04IkJ+Rfesx78eJQAr8yOjkX4xDu553RaC+4gCBuf8+N4dWPcGHDggohzLciKxADqQQ+/enXYc93s6kx+oOv2aTH4AyAPY4XtwvnH/csHkB4Chg3jmP0Y/luVDIgAdiJTye64r+nTapNMWUinPhwSRbgOe2HPZDahbTo1+/7E9r1od5XiWE4kAdBiH3r3707bjal3a4Zyhq77Trxav0RuVf57ZsyujoP6kwSM9Bsw/jGo8y41EADqIZ/YPv6piO7+m2667OwvSy1M2rNuHXyYUeyOANY2eUcANj+3Z3RXRkJYViQB0ELbj/oNupF82m4ZpaJ/2bikVC5FcDSZSXioiZxhV3hz6YJYhiQB0CIf27h5xHHeVThvT4Mhlfdcafavfhl55Zs+uDKrBUU0hlZROD4NEADqAsX1D51Qqzn/QaUNE6O7OtdLt21pp7IUpxrcD8GraXxTmWJYriQB0AI4rvqZr+nflMuC8pY/3wlKxsKmVFzRFqLUaT6/FRyn5vgZM8g8acw7t3f1xx3E36rQxTaNenL8uoW4DFEFHAIyf/ejyhXECCS2SCECMObx3aJNtO/9Nt53mkV8jrgvqRTVRslvncU5ukrU4YBIBiDGuEN+QUvHmT54hnbbm3u9vlctKxcI5Qb1sIQR6Qed5S6S0nk9oTiIAMeXQu3f/N8dxt+u0IaJWvP710I478AoxPKfx+NTmL993IqyxLFcSAYghz73nym7bcT+m2y6bSXmJ9ddlX6lYCGxPMRepDJ1Cqq2WXU+oQSIAMcRx3Vul1MvuwxlDJpMKYzh9AG4M48U7Dtz/SwBPeHqY6J/DGMNyJxGAmPHce67M27ar7X3P5TK64b46/HpYLwbhgJfHlJR+yq0lNCERgJgxs/prfS6maejc9PPDK0vFwhVhvFgp5UUAntl59yOPhNH/cicRgBjxzM1XrLJtR7tMd4DHfo0I5UbezgMP/xjAVxo9o5T6WFDZkxPmkwhAjHBdcZuUSuszSaUCPfZrxMWlYiGUuACDG/9pTsbkeSio7+28+5G/CqPfhEQAYsPY/uE1tu1cpdsuG47jrx4fKxULgavN1rvuH1OE36vxK8FB/yFZ/cMjEYCYIIS4Qzfe3zKNqFb/WXYA2B/Gi3ee+8gfK6Lb5/xIgrB/24GHfhhGfwlVkqSgMeDwvqEN5bJ9SFcAenu7YJmRZ3Z/BsC2/MhoOfA3f5TYEz/Zdaci3KCI3rPziw/eFngfCfNILIAYIIXUXv0Ng7dj8gPAegDvC+XNH1HyuWPWXgBXJpM/GhILoM0c3je0uVy2n9Kv6ZdFKhXIjT8/vATgrPzIaJ2ipwmdQmIBtBml1Iju5OeMtXPyA0A/gI+3cwAJwZBYAG2kVCxQ6fipim5Rz65cJqywX12uyY+MJiG6HUxiAbSRyany+3QnPxEFlewjCD5bKha0ipImxItEANqI6wqtun4AkMmkwoz512UQwN+0exAJ/kkEoE08e/MVaxzHPVu3XSY+q/8s15aKhdByBiSESyIAbcIV4o90/S+maYRx3z8I/iTMzEEJ4RHLb9NywHWFdtrtkG/8tUIGwBdKxUIsPJMJ3kkEoA2M7RsquK7QSogJoN1Hf804H8D/avcgEvRIBKANCCE/otvGskyw+Dj/6vH+UrGQlPDqIJI4gIg5vG8oU6nYE7rXftsc+afDMQAX5EdGdRJ+JrSJxAKIGKXU7+pOfiKCZcV2/7+QlQDuKBULyXerDgffcdnaH+29qqW6bUGRfEgRI4V8l24byzLidPbvhSEA2gVNlgM/uPbirBLqH1Pl8X/8wbUXZ9s9nkQAIuTILVebrhAbdNt1iOm/kD8oFQvntnsQcaM7bd1BwK8A9PpcOv33T9+8O/BCDjokAhAhFdt5l5R6F3+ICKnOMf/nYgD403YPIk78fM+lBQV6++yfCeqKymTl7x7b8/K2KXwiABHix/zv0Mk/yxWlYiHUAqOdhAT+x+Kf0hsN9P7v6Ecz03tyChAdv3jna4+7rujTadPdlY3T5R8/PAXg3PzIaCXIl5aKhfMBfBTABgDdAEYBfD4/MvpokP0ExcE9u64G6hY3UQq4dOeBhyJPfZ5YABHxzP7hVbqTH6iG/3Y4ZwH4YJAvLBULNwF4BNXy5a8AsB3AfwbwL6Vi4a5SsbAiyP6CgRo5RYmAT2PPnkgTPAKJAESGlEq7ug5nDJwviY/ot0vFwtogXlQqFnYDuANAPQ/6jQB+UioWXhtEf0Hwi7dfugrA65o8dsFBPPMfoxjPXJbEt6sTEFK+RbeNaXX86j9LDsD/bPUlpWKBAHzCw6NrAXytVCxop1kPA8HpWniaa/T7j+3Z3RX6gOaQCEBECCG0j8SWgPk/l3eVioXXtPiOGwBc7PHZDIC/j0NosiLl9eJXD0Pl2lAHs4Bl7QQ8tHf3p6RUV0spVwKwDM5HGWe/seHWe14MuJ+LymX7B7rt+vM9cb3+65dHAbwqPzLq60tXKhaeALBNs5kD4B35kdH/66fPVjn4lsu6kVJHAXi9KfnVHQce0rYW/bKkvl1eGds/zJ6+6fUPl8v2B2zb2eG6ot91RXe5Yt84PV15/vDeoY8G2Z9S+tV1OWdLbfID1dXb15d7Jt+A7uQHABPVq8qhlDhvBkurX4H3yQ8AVz215+LesMazkCX3DfOC67qPV2ynpjmqlKKKbf/O2P7hlwfVn5RyWLdN2OY/pVyos14ENh8FcsHX+GjAb/ps18p+3kD1fsKVLbzDFwrqPM0mKVdZiQUQFof3Dn3Mtt2GK4mUijmO+62g+pRSrtdtE6oArD0OZ/thuNlJOF3jcM96DhiILMX/5aViwes+fi5Xt9ivAeBLUYcnKzBdAYAiuiiMsdRiWQnA2P7hfMV2/ruXZx3HHRzbP7yn1T6ffc8VK3Qz/wIIr+rP2uNw8scx1/WjFCAHj4fTX220rIBSsZAGEMSxXi+Af4w0k7HStgCAavWlSFhWAiCEvFVK6XlmCVf8Tqt9SiG1zU7GKJz9/9oSnHztiS4gAMsNvs/aXF8qFnS+5K9F1asfBFsAfCXC9GXaW0kC1oUxkFq0TQCivgo5tn940LGdgk4bx3Vf/sKvviHfSr9SKe2Vi/MQAsLWleDkTzR+JmsH329tDADv13j+DQH3vwvAZwJ+5yJ+8GsXmwB6dNuppS4AP7vxsku60qknfnbjpYE52pohhLhTKr1EHFIqYoy9t5V+lVIX6LYxAhYAta4EZ0WTyQ8AmcgEAABuKRULXoNewnDevbNULPxeCO89TeZ4t18rY1WgA2lA5ALw5E2X9DCJLwNYxyW+dXDPZTvC7nNs//Am23a1PfHptAXD4O9opW8p1Vm6bQIN/11zHK6XyQ+AzEhjQvoA3NzsoVKxMIhqwtEw+EipWHhnSO+GYcDnXX+KzCETuQAIh30AUKsBQAGDgLrn8be/uj/UPoX4nG4BTgDIZtIAcEErceUzQUZacCMgC2DgFJx+b9+lVJohjJ1HEz7gIXVY2Ed3nykVC7vCeDGrTPsUAPVMsCOpT6QC8NSei3uhaKEHeB1xw0t8ty/G9g9vt21X+wNOp625K7GvwKCx/cNZIaT2XV4jCAuguwx39TFPj5oWg2kxUCoyJ+AsWwE088uEnU8ghapTMHjPu8n9bgGeDXQcDYhUAGxYBVRNv/kQbn7i+ssuD6NP4ba0+s/y+lKxoL2FgFJX6DYhCuAEwHIhNj8PL1HehkFIpav9USZyAQAaTPBSsbAOPiMHNRkAcGfQiUwls076akhLVABIod4kJ0XqU0H3N7Zv+ELbcbWDThas/rP8ge57/JwAtLz6k4Lc9iykh9nPOCGdOWP3U8YBDNla//q8ceaWXy1+DdUTgyh4HYDfDvKF2z9/3zEAL+m2I4mfBjmORkQrAESNVvmLnrhu184g+3OFuN3PZacFq/8srykVC2/UeY9SSjuiq9X9v9z2HASJps8xRshkObBg6rHuQBP3eGENgAsX/rBULFgAbol4LB8J4MbiQn6m+bwUkn854DHUJTIBeGzPrrwCGoZhKo7rg+pvbN/QLtt2tKOw0qmaq/8s/3Pmi+kJKdVW3f5bigFYV4KwvE3gdIahVqZx1h3pUeAs19T42S2olh+PEgPA50vFQnCXcQiPa7Z44Jz/+53nA+u/CZEJAAe7DIvWmwWoMxlTW8UV4rN+2mWzDR235wHwHB2olNI+3fC9Beidhtss0GeGVJqB8dofBUVvAQALBKBULOTh0/EaAJsB/J+gXkZK2wL4YlB9eyG6LUD9/f9ctgfR1di+oWHbdrXf1WT1n+W3SsWCJ9NeKaV9AuDLAWhIiI0venL6cYNgWvX7YF02QJHniHj1zKSf5fcAtBSB2SI3lIqFpjEKXhBMflvjcddwEWnegsgEgEhd5uGx7NNv262dOHMhrhCf9tOuyeo/iwHgs162AkopbQcWY/oVgNTWFyBVc+cdEeY5/WrCJdiKSK8HAwDHzHXfmXv/2vkTQuB/l4qFlhekc77wyP8j4LteniXCn279u4eOtNqnDpEJgILytJ9zTdFS8six/cNbHafxdd9apLyt/rOcjyZbgVKxwHSLgAAAkd5HolaOwzW9TdhUhtfc9y+Er5zUGkNAzG4D/gTRef4bkQNwl47Ppx6K8BceHnvWVdbvtdqXLhGeApCn5dWWsqUieELIT/nJcpbLasdsNNwKlMu2tgOLiDxN0NNwAaER7GMY3l7O8tMAj/w48KqZ/H2xSOQ5w0Xwcfy7ED7e+yUAR5s89hvnHrhvotW+dInyGNDbdU4mfXtAx/YPG47jan+BLMv0431vuBWQSm7UfaGu+a/OOgKF5mpHDLBSGh81U+D901pjCYABALdG3akHfnOmCIlvzv6nf6qAGjoWv77jwEN3t9KHX6IUAC8zrHzugYdLfjtQUn1YSv3kGxn/lXfOB/C7Ncei9JM6aFUA7p2Cm/I2SVMpb6b/XNhAW7YB7XT81cMA8JcNgpU8IdTJP1DAdxb+XEE9xsHf3cq7WyFKAXiq2QME/KKVDlxXvE+3DWMMVmv19367VCz8u4U/VEpp+zJ0LACxoZlFWYUbBMPU/+6y3jLIah5QtEx4DYCWroWfe+AntmOytwLz4gKekHCHzz7wHW8fZghEdwqg8FizZxTwFb/vH9s39DrHdbVTPbWw+s/CUI0jnx9BpvSDWDw7ADcdhYS3yTkb5+8H1h5nYFz5o1ZTiZ33uQeOA8Y1AI4AeIqghs498P0XghmeP6I7BWCqeUCEFAf8vl8I6etGYUCFN9MAvloqFs6e/YGC0k7q4MkCMAXcHm++ItNivo4VZ+EDU77bLkFWAPhkqy/ZceD+X0JSQYDt3n7g4cgu/dQjOgGQ/IFGvyfgpzvu/u6P/Lx7bP9wn+24r9Rtl7LMIHPvrQTwT6VioRr9p6CdB4B52KirTUfg5X4Dkabjr9Y7cna7QoPjyt5SsfD6Vl+y4+4HHz33wAOHAxhPy0QmADu/9MC3ARys93sF9V/8vltK+Uk/V35DKLu9DdWssz0KSrtCLTVbrS0XIuPN8Wela8f668I3egsvXkZ8OojYgLgQcUYgVTtCj+hLOw48/DW/b3UdoV31hbfu/KvHJQDuBbBat2Eza0RtPOYp3JcYYJrBfLSstwzWF3lkYJzZCeC/tnsQQRGpAKSc1G1YHBBxHAy/4fedh/cN7XOFyOm2C2H1n8srctnMTkPzai9vJACWC5Hxtie3GsT6+8HYlFgBC/hwqVjQzvUYRyIVgM1fvu8Ek+zNAGbt2FPEcNWOux58zu87hStqnsM3I2QBAOcMfb1dnvshooahyJ5Xf0LDyz5+oJwNtjJxCM4hA+CP2j2IIIg8Kei2ux/4HpF6J4BxkLxm+xce+he/7xrbP7zJcV3tO/cBO//qQkTo7sqiuyvbNMgnm03Vf8bUWP1bdPzVw9h4oh23BOPMdaViQTvle9xoS12A7V98+CuGi7N3fPGRh1p5j5Tyt/zE/afTURWFme3PQl9vV916f+mUVS8LEQC91d8IaO+/6N1pF3zNeCjv7lAIAdwTaDfkJ2VWXHjqXa973nFcLWcb5wz5FdrFWgLDdly4jgspFThnsCyj6T0Ecd4vPeX4s1IsNAsAACAJ9o9WQ02F4jztVF6dHxn9frsH4ZeOrQ04tn940HX1Jj9QXW3biWUayGbT6OrKIJNJNb+ENHjS0+QHgt/7L4IpmNteSrYC8/lYuwfQCh0rAFLKD/sxXqxUZ61est9b2W7D1LxK7BPK2TA2+st2vUS5spXCMe2mYwVACPk23Tacs8Dr7oVKyoFgjqdHgzr39wJfdwqsN4kNmEPHWgEdKQBj+4fzriu0r9umwgn8CQ211ltZL6Lqrb8oMba9BDIjTxoSVy4vFQtBVzCOhI4UACnlh/w4L0OK/AsNmfN29Bf63r8GZAkYW7VrXixlOvJEoCMFQAipXT+AMap7DBdL+qYg4W2F9XPfPwhYfjo5GjzDq0rFwrXtHoQuHScAY/uHe1xXbNJt12mrP1Z5c7RxTi1d+W0VY9MJUNabn2IZ8N/bPQBdOk4AlFQf9HPzr9P2/yLlrUBHu1b/05w+GmzvMGLCLq81I+JCxwmAEOKdum2ICKbZQQKQq3jK8w9E7/yrBeVs8MFkKzDD+9s9AB06SgDG9g+nHVdox/5blhHJGXlgrPR29s9Ye83/uRgbT4JarCzM+qdgbDpR3VbkOjYRyTtKxYJ2Mph20VECoKT6z8vB/Jc5b0k/4rD6n8aQ/pOHEGBsLcHccQx83SnwdadgXfACzHOOgsyOS0yaQvRVjX3TUQIgpNzjp11HOQCZgmCup0e9FvqICr56wtfKzVdNgA8uznPIVkzDvPB5UFfHWQO/XioWOuLIqaMEQAqpXfLLMg29fPvtps9bJt52BP94wdjiLXjpNFyBNwgtJlPCetkRsPZULfbLegBvbfcgvNAxAjC2f3iVn8w/ocf+d5Uhzx2DOO9piJc/DWw81lJZLeVRAHid8t7thvVUtJKH8FUTzc18LmGeewSsp6NEoCOcgR0jAEqqvX7aWWF6//sn4G55HoI5kEpCQsLpOQW1w3+2Z5Xx9iWP4+o/i7He+2UhlvdYgoyrqgh0jiXw2lZLikVBxwiAVLKg24axxmm2WsIUcNcerZmi22UOsN5fhTPJvDm9WEwtAACgrOMtkShXeqs6UzB2HgWlvflIYkDsrYCOEQAh5Hm6bUwjPD+M2vJiw/z8YoWPK7NdFU85/4H4bgFm4WubH2Wy3rJ2bgEyJcydR9tRvdgP7ywVC9l2D6IRHSEAY/uHLSGkduFII6zY/6wN12q8wkmlAI+3+U7T7W3vHOfVfxbWVwZlGocIsxX+KhBT1oG541gnRB9mAVzT7kE0oiMEQCl1nZ/zf1MzLbdX1EZvtRy9JvM4/d6ctzv2cV/9Z+FrG0QHEsDy/jMNs74yjC2+C0lHyXXtHkAjOkMApNJO/gEAunn5PZErwzW87VuFEqC89wKbyvK2t2UdktOED0zWzRnAesst5xPgqyc64Tbim0rFQqbdg6hHRwiAkPLVum0Mg4dy/q82HNN6Xq72vg3w6gDkMQn/bQpTYDUCfAAEVmfA2Hzc91YiInIArm73IOrRGQIgxFrdNqHc/e8uwzX0otIEt5vuhQEApKA83v/vBB/ALLxWiXFS4C2Y//PfNZOdyIp1yLB2/oqoiL0AjO0bukxKpW30hnECINd72/vPhXNqvBeeJettWxGXyz9eoawDSs2fnKyvDLR4cWheH4aEsS3W2YneVCoW6hd+aCOxFwCp1Lv8tDPNgDfKfVMQXD/xhZli1b1wqsn+vsubAFDsP7HFsL75Jjof9O4X8dxHbxl8vZ7TNUK6AVzV7kHUIvZfJymVdsplxljgpb/kWv0VhnGqeuyZgrG1icc65U1cOs0CAOYf97GeSkve/0YYG07EOVIwltuADhAAuVG3TeCr/4pJz+m55zK3Si/rK9e88XYajx7xIP2aihicNSsgVoVbKWluwI/2ZSEdZvwBMQ0SenOpWIi2Jp0HYi8AQkjtC0BB7/91PPmzMEaL0nUZm0/U3wp4DQEOyAJQlonpbQOodJmY7k2jsiXEHBYzIb98lb/rwjpQ2oXZzNpqDz0Ahts9iIXEWgDG9g9v8RMAZARoAVDKheD6X1rTqjFsLmGcXfvLqTyuWoH4AFIGypvz80qOuUFbTQtgK6fAN0VTUYitnAIfCN7PEABD7R7AQmItAErp7/8BwODBWQByvf7ev1GVXtZbBl9dYyvAPB4BtmoBmAamN62EWHDnQCkFmQ3PQuWDHq79Btnf5uOBnjQEROxKiMVdAC7WbcM5C3SfLLL6DivTajwGY/PxRc4qxbxdimnl76YsA1Nb+iHqJByVufYWTg0SMiWMTT5TlIXHRaVioavdg5hL3AXgXN02gXr/15zwfDtvLk0r9TBVzXc3J5++lyCgVnIAKM5Q3tzfsNKwTC8dAQCqVkfMTgU4gEvbPYi5xFsApNIuABLk/X+Z1z9X9lyl16hmuTkdJOPhWqxvASBCZctis38h0uqQSwYaGFtLcbs1GKttQKwFQCq1SrcND6r6b3cZgvQTT9Tb+9eCLFEVAUNCofHkJAJMw9/HZW/oh+thEsgOjDFoBmUdT7kJIiQRAK9IqX8EyAPaAqg1+kdJRPqZeinjwDjnSNOLS6k093UCIFZ2w055ayihoJagCBjrTzaPxIyOV8UpLDi2AjC2f3idlEp7fIFsAbiESHm7mz8XndV/LqzbRraLI5PjSKUZDJPAePU/wyRku7ivEmAqY6Gc10tIo0I8CWgbXMHYHBuHoAXgknYPYpbYCoBS6nV+2gUiAGuPw4fvr+U6fZwTTIshneHI5qr/pTPc39EfAZUNeS0nJhGBskvLETgL65+KU32B2GwD4iwAr9Rtw4gCyQEge/SDSKoJSONjPjvr++F6rC84i2VZoL5YnVIFiuG3clHwJALQDKXUy3TbsCBWf9P16fyLz+SXXWlU0nrBUJzzagHVXBqwOqKojTasrxyX2gLa8S1hEV8BkGqLbptATgAG/YWrxkkAKmt6gCanCgtJpeaY/vnuYAcUI3zXLwyW3lKxoH3CFQaxFQCplHYW4CD2/7JHP/KP8/hU6XVX90E34NY0TbC5iQbzS3cbwHoq3moWhM/2dg8AiLEAoOot1aLlI0BT+rr2G5vVnxHsHr0TNxWAgwAAHQJJREFUJiKGlLXA858ygaV4GjBDTHwBiQA0QimlvRFt2QJY5e+LYfgM0AkaZ90KSB+Ov5qRcqt6gxlUDKEu23tJsvBIBKARSiFyAZC9/rz/sUjTxTnsjF4dRCKqnzxlRdeStgJiEB2YCEBj9IOAWjoC5BLSR84/3ci/sLDX9WlfXDJNCw0D5ddqu2E6BtZTmXcZqw0kAtAIpfTH1pIADJ70FfwThyq9inM4msd+IILV7LivO1P9b4nS5qIiZ5eKhbbPv7YPoBZj+4ctP9dwW8GP+U8UDwEQq3v1V3/DgKdrcuv7gZiccAQNH5hsZ9KQFADtfJdBE0sBADCg26DVCEBp6JuDcYn8c3wk8jBNj/6CtAWs7dd+f0fAFPiqtqYOa/s2IJ4CoKAdJNGSAGRtX4k/4rD6y95M3Qw/9TAMQy9xykAP0BPrKte+4avbuw1oZ+dAXAUAyocF0EJ3+QbpuhsQh+M/p18/aMfz6j+XTQNASNWW2wml3XbWFmy7l7X93+AaKEDb5mzFAlA5/S9AHI7/FGdwNY8+ichfyLTBgU2xiF4NnIb1GsIl3IIMHoilAMCHMrYiANLysf+PgfkvBnqbZhJaSEsZk3sySzJAiPWV21VMpO2XLuIpAMqHAPjty3S1o+eAeDgA3Zy+Kc9bLZqyNl8NFV5KMAXensjAxAKohYJaodvGtwXQ788LzGKwHRbaIkSt+y2IgHUaOzTOqrcLu2KTBasmrD+ceoVNaLsAxPXit370iU8BUN36HzxR+4t0it6s9smF4fXsvxm92WqA0HiTVdMygG1rz+QXmCgDz5WAyVjcxpvH6W2AiHRNbLsAxNICIJD2rRy/BoBK6aeJavfkBwCheesPAIwgvfjrVzb/R1+Tn59cpCsNbFsD9Gnneg2f9mwDEh9ATQjHtJv4UQCmILVvz1fLfgeF7MlgetsgJrcPorJloGoye0D42IcHljIdANImsLLB99c0aucVIAI2r6peNooZbdgGJBZAHY7oNvAlAF0VTR96laAcgDKXxvRgNwQUlFJwDEJlo4f9NSNIzSEElS9xHqv66u8oehrs4oiqcQUxu2fQhtOARABqQcCL2o38zOScv71oUA7AypreRcN2DIJqkplX5lLax38syNV/FssAeuuY880iB4mALYPxOlFgCqw30pyBiQDUhOgF3SZ+QnlVWn//H5QDUORzEHXKgdmDjc/amwlELUIRAKB2XACjxhbALJwBZw163vZEAeuJ1EHZ9r942wdQh+d0G/i6PZjSDwAKav9vNwjhdU0GVS9RB3zu/4MsmjqXXBrILUgc0pMFvPaXtqo+gZgQcdbgtl5EAGIqABtuvUfbCejLAuD66b8DWf37uyAamPBKKbhr+ur+Xvrw5gdZNHUR/QssWV0HX082NslHKGdH6Qdoe1qiWAoAABB5KJc7h0Zlr+u2YfofdBALqZ1vfgxmp426prHUrT/IGEItkds7Z7/PyN/NwcG+eGQjpmqptohILIB6EJHW+Zy2BcCkL6uBWrQA3IGehqv/LEop2Otrr4raAUBh7f/PdHAmf+DKHv8JRDasjEVRkgj9AIkA1IMIWva59mTu8nkC0OJCavd5P/qyLQa58KiMc+0Dj1DN/1l6s1UhWK0dxX0GxoCN2jfBA4ei8wMkAlAPItKyw/QFwN+H3IoFIPI5SM3pW1nTMy/iTqb0VkjGCNyI4Khtdh/fqth0Z6pWRBthXTbAIklJlwhAPQikNUN1579K658AELWWeMRZoR8CS5wDc48FNS/zWFYqzN3/GbIpoD+gyNZ1+fZuBZgCpfUdxD5IBKAuBK3AbG0LwPQhAC2s/iplwvXxr20YBrA6fzrgRmkIgGVZMxeAOowYbAUoE0nK8EQA6kFE2mladERA+TDxWtn/O4P6Zi0RVScwoXpW3pWG8nAESERIp9PVqj+dSncmOIvCBxFZAMkxYD0Y0c9120ipMan1ThmrTfwqAEE/bz8wf/VmBJy1GqpOtR7GGEzTRDqdRi6b7cyVfyHr+tsWJRiRBVCKopNGxPZbQkTfB/AWnTZa2wAfAuA3BsAd6PF15LgoeSdnMFd0wwBAauY2gAJAradFjyWcVeMDnot+nlAmEgvg8Sg6aURsLQAiuke3TdgC4HeSuV7i4hfAGKubupuqgwERgVgIt/zixEAv0CAsOizIh5PYBz+NopNGxFYANtx2z/fCjAbUvU0H+DsBUCaH60NsfKXuXoowai22wCdkyrCrBo3nR0YPh9mBF2IrAADAGdPK0CCExgfmY1L6OU8TPh1ZS2IPHxT93W25NhyyI/CxMF/ulVgLAGP0vM7zwvUePewnzMOPoe126XviDcNY2ma9LkTV9GJRdxvupaC2m/9AzAWAGDuo87wrdK4PhG8BKIPB9TGPk9W/Bity1avDURLuFiARgGYwokd1ntfZAkRRfNiP+X/67D9hMRGHCBMP9UuSCEAziHCvzvNKKUjpQQR8xnnrmuVuV+0z+0Ykk78B+a5oS5UnW4A2Q/Sg9qRzPXxouhk1faJfuKMdAsChMhdBGYMR9+sDzqLNJhyeBXAqPzL6TFgv1yHWArDh1nuk/kmANz+AHx+bThvZk/FXcjzsu/sLWXE9jOwWUM8V0fbrl4HotgEhOgH/LawX6xJrAQAAxvQShHp3BIZrBYhu/cIdUU9+1ft2cFYNeOFUAVi80nTXJJNanIMwLMITgK+H9WJdYi8AxJjWnQCvjkDtqnqaDUS6zYU7mqC6r4YxL7WYgjLPiqz/lojKGRjeGjEa2ps1ib0AMKLv6Tzveo0FUHqfrq4172f/H5UAqNzlMKwae2lzTST9t0xvrrXEDF4Jx1f0bH5k9IdhvNgPsRcAInxa53mvJwGkKQBaY8hY2vt/IopEAFT6Ahjp1agZB2HUz0QcKziLZhvgJ4FDc/45jJf6JfYCsOG2e18wDH5Up42nbYDS/6t7ndOi19/ln9AhCyz3MgC1/30Y7wAfwCz1KhIFiBKhLBKxMf+BDhAAADA4/6bO854cgX4sAI8CIGO6/1fdbwBD/UxrDFNQqR2hjyMQen2kHtcl+FLhNoBvBf3SVugIASCiT+o878UPQD72d15vEErNvH1A+BaA4v3gZvNVkzLnhTqOwEiZoV8QUsELwHfyI6Pama7CpCMEYOPt9/4r52zS6/OO4+EWlwxvCyB9RKuFvgXouQJeMq0zzqFYDAp0eCFsKyD4LUCszH+gQwQAADjnj3h9VgjZ1A9Arg+T26MA+AkAClMAVGo7DOYxQAou0HNNaGMJlLDLiwdvASQC4BdGNKLzvG03yegyre9F9jKvVdrUvmcY9upPuVdC5/ajwWVn+AIy4Z4EqEqgfpkf5kdGtfNchk3HCEC5Yn+FMfKcocFutg04pb96ePEBSB+lu8N0ACpjZTXKT68VWO4iANGn4tLC5NVqRGEgCKoS6L2MPw3yZUHRMQKw48BDyuD8x16fdxy3sSk+ZenHknhYRP2cAIRqAaQvgp/cB4xsqO4rgx9P0PgQXC+o6UAdjC8CuCvIFwZFxwgAABCj270+q5Rq6gwkzVgAT1sAHytSmNl/yPJXYEPBhJ0agmLR5+PTIqRtgAxWAD6dHxmNrOCgDh0lAFKqP+eMBbYNIKFn4nmqO+DjBCAsAVCs14f5X6VM50FQH+zum+o+I8wd7T8xyIRkAUwFJgAVAH8Z1MuCpqME4KzP3e9alvFlr883cwRSRe/LI73EF8VIAJB9BfyY/zadBZeqloOwzoObevWiZ5yu61Hp+yDK+Y9DpC5udaT+CckCCHALcFd+ZPTFoF4WNB0lAADADeO9jHk70xJCNowKpCm9L48XC0D5mMx+BUDmdoP13wDV8+ba7zVXa79TYAUqdPa8nzld12PeV4VMuOlLAQCK0qj0vBci9UrtvgIhpJoBAVoAnwrqRWHQcQKw7jPfPGmaxle9Pl+eblBl3MdJQFMR0JzLRP4KeyjeDyM9AIILw7Sgcpcueob5SH1WYTux8C+hWA+E9fLTf3atX4GiuUE4hEr3XkjehtuEnAV/M1AwqHIgJwDfzo+Mxib5Ry06TgAAgDH6VSLydPG/XLHrnwb4OAlQTXrVtQB8m/9drwPhjHVDqc0L3wyCXnUbl1ZBoPZdezd9yen/L9I1VntKwe65BaA2FDQJuH6gPKGfzKUOsV79gQ4VgI233VsyTcNTVJVSCuVyfStA9yRAqwBpWLAcuDF/onEqQ6UvOP1nZfRDd/+/0PSfi7AugKIMFGUgzJfVfEYa62B33ajVZyD4uHvRCHk8kAjDgwD+IYgXhUlHCgAAQKl/79UKmC43uAFX0fUDNBmW1tv8WQAq9/qacf0s93KcDt7hq7Te6dIgJBqkMScTIvUKuNmrAKpvHrvpy6P3BwQcDCSPB2IBvD8/MhpqWuEg6FgB2PK5+4+aBveUW00IWfdEgI7ppZdqZgGEn6fGBLdqj5mhDNXzpuofDL3ze5s2NX3GzVwBJ9M8OMjufjeUpgC1RICRlGrCgnJaft8X8yOjWlfY20XHCgAASKV+lcjbojtdbxtwPKe1CjcVgJArjqiu14JQf0tjmCZU9hKAeRc2BRMCzbMBSWOtpz1+9WTgloaWQqAEqLoBmP/jAH4zgKFEQkcLwNbPf+c50zQ87bNs26l7Q5Db3uMBlGwcEein5qh3CCzV7GhPgWc2gkzvtfQErUTQtos0NsLJXBXoO+t3Ftw/umhdAH43PzL6XBBjiYKOFgAAMAzjBoNzT+Fu09O1H6PjetFswm3whQvRSaiyF4Oh3PQ5ggCnM8+5tApT7NWwqXbWXxcrAxvjvPdmrgAogtx9Af2bK5tDTbQUWfhDAH8eyGAiouMFYMOt95TTaesWL1b8dLlSu3DIsR6t9U+I+l840vwyajkBrc1a7wYAiQym6QII9KFC2+DQ2oUjOB31FzSK5eCmLw/l3fM7CsbXJl5sKaxZAfj1/MioToXattPxAgAA6z77rdtTKesbXp6dmJhe/ENJYML7+XUjC4C81Cacg07yEMb1z9ht2oq5H3P1z2dERyINhfDO7p3slQBC9gUEYQFIgnxBv5jrHP4mPzL63dYHEi1LQgAAwDSMNxkGP9nsOdtxa54IsFPe1V9KVXfRIS+1CefgWQDMDQ0TetZCIrdoxZfIwqF1Z/pHyEk12Aq46cV3CQIlAAEQR3NQju/pcAzAh1oeRBtYMgKw9jPfdEzDuIaouRtuYrKGFfDcCjANc9yt41BkjUKPa+BVAFS6dvBNI6qBPYv/ThXaCYlqKK+KYI/uZK+uOY5AUAC85IBsgni+pdX//fmR0VLLg2gDS0YAAGDj7fc+bJlG00IiQkhMLXQIKoCf9P4lqLcNoAm9VdqrAOh49QFAohsu1T4xUOCYZhdCwYBEYGGvdVF8ECJ1UTgvL9stWwDyRLqVyz//Kz8y+oWWBtBGlpQAAMDmO7/9PsPgh5o9NzVVXlxB6Jl+z0454aqax4HkihCu91rQyIYGAKjQtoa/l+jGFHtl4+i/AHEyu8N5cZ2THR1aWP3/CR1q+s+y5ARghtcTNZ4xSilMTi44UpMEw6MVoBTgOnW2AZpO6WZWgMqcN+/iTzMEejx59iV65vkDwkSaZ4VzUWiqNQFQk5bf4J+fAXhHJ4T7NmJJCsDWz3/n6VTK3NPMH1Cu2IsdgmPerQDHqf16FrQj0Fx4dNcYd9FRXxwwIIwQqg+3KADuU75Snh0HcG1+ZPRUS53HgCUpAACw6fb7vpzNpD7RbC6fGp+CmLsVUOTZFyCFgqwRE8CapSRf+J5mR4dMb5/uUoRx+BpIs/G2RBulAE2n61zEi12Q49pOUAFgT35k9EnfHceIJSsAALD+1ns+lMmkP9foGaUUTp2aX3SIdKwAe7EAcE1HYDMBII2YeoluSMSzyKe0tgf7wrLj2wGoXAZxyFc15N/Mj4zGqr5fKyxpAQCADbfec1MmnfpKo2dcV8w/GlQE48V+T+93XbnIGchOTWteMGpiAZD3jymuqz+AmS1AgFd3WzD/xaE+KP3y33+bHxn9M9+dxpAlLwAAsPH2e9+WSpkNVXt6uoJKZY7pfqQHhtPc9FYKcOzFE9io4yCsRXMLwPOr4NCg94ejhixIs/m1Y8+85G8LLsdTfsJ+vw2g6KvDGLMsBAAANt/x7StN0/heo2fGJ6bm3Rikn68G87D62vZiK8AYb35pZ5amAuChqCdQjfuP6ljPLzIoR+BUBZj0YQEowP2FXkwFqjX9rsmPjPp3OMSUZSMAAOA47i7DqF9dSCmFU+OTZ7zykoEf8rCiKsAuz5/EvDSpFftWXwRMzwJQvdYbbwKLPDzqb/V3n16hG/RzJ4C35kdGa4SPdj7LSgB2HHhIuq54hWka/1rvGdcVODU+deYHpzIwxpuvqo4j5ycLkRJc4zTQdWtPcmV4X61mw3tjDQXgA3AFcHxCu5l4sUs36OfPAOzNj4y2HmscU5aVAADAjgMPOWd97v6L0imrbsom23ZwavzMyQAdGgCTzT3xlQVWgPXSZJ0nF1PzmrImYV/sCYYAvnIvjXur0zYHeSqle+b/kfzI6AfyI6MxyAIbHstOAGbZdMd9b8hl03fV89ZXKg7G51gC/OfrmvoDhKvgzrkjwE5MwlAeQ4uFqBkQRO4xeL1IIyn8uP7WadECUACO6Zn/qmLAPTgAePssJID35UdGf9/H6DqOZSsAALD+1nvemcumP8hY7eDdcsXG+MSMCDgc/Kk1TW8MVqbFvMXJOjbueTy1twHC8339TrAAVKtbgBOTgK1hkQuC87MBr1d9HQA35UdGR3yOruNY1gIAAOs++60/zmSsXZzzmvZ6uWyfiRGYTIH/ck3DM36lgPL0GXOenZgC92gF1PUDeKxdEMXNvtZpQQCEBJ59SauJ8/N+r06/KVTDe2NZxjsslr0AAMD6z97zPdPg6w2D1wzvnJ6unLk4NJGGcWh1QxEQrpoXG5A66s0KqLcN8HJluGoldMLH2YI/beyY97v/CnCf7IcseXKMHgTw2vzI6Nf8D64z6YRvTCRsuuO+E64rtpuGcXet309Nl89YAqcyMMYGG+7MK+UzpwLs5BQsj4FBtawApZrfLVAIp0x20DD3GX8NT0x69/xLgnNwJcSRnJen/wLAr+RHRn/gb2CdDenkpFsu/PKm179dCHGnEHJRUL1lmejpzlYtgL5JuBuO1F2hGSNkcrwayccIU1tXQTYpY8AYQzY7f9VSPW+GYTae4AomJthQk79Z+0mXPgImntdr5ArgZ89U/7cZguA8PgB5sul26DkA78mPjHoqLrNUSSyAGmy589t/l7LMwVTK+v7C39m2g+MnJqoRgydyMJ6u7xiUUqE8NfOllQrp55umLISUEo4zf8VXovkWguB4DhhqG6oCJl7Qb3f4mKfJr1wG+6eDXib/lwCct9wnP5BYAE159j1XfKBctj/humLeEsyI0NOTg2kaoJSAOPtZiDo5SAyDkM5WnV/Omj5Uuhqv5kSEbDZ7xs9grAXvfU3TsU6yXbEOBWbOk0if+IReo9IEcOhI08eUzeE8tqqZw+8kqvn77tAbxNIlsQCasO4z3/rTrlxmZTplfXPuQi+VwomTEyiXbagKB/vpRhjl2g4n11Wng4TM50/AalRYBFWn3zwrwH0OUjU/4mPK+/2DdsArdQMwazNRrjr+mqCmTDg/Hmw2+b8N4Pxk8s8nEQAPDP7118c33XHfG1Ip67Wc83nL0fjE1GnnID25GuaxfE3noGNL2JWqCFi/PAqzQXERALBte55vQbrNtw8MMQ5XVxUY5Qe9Pz9RBn7xfNNyzOL5btg/Wg1VqRupWQbwXwAM5UdGD3sfwPIg2QJocnDPpWSaxkeFkP9VSnl6s2kYHN1dWRgGB3JliC0vQtbI42dZDFa6qrvlswbg8vpnCYZhIJ2e6cJYA957KRoVILdpMyq0w99fLGSM6XthTXhMnjsxDfzihYbJPpTN4f68v9F+3wHwNwA+1km1+qImEQCfHNxzqZlKWX/uOO57pDxzUSCXTSObnflSbn0RbnZy8VVhk5DOcICA8pbGIpDJZMBnyl+rFe+AwerfSHVpANMUUvrtllDIlH4XJJrv5TE+DTzVePLLY1k4T+WB2gk9BIA7APx+fmT0lz4HvGxIBKBFnnvPld2uELfZFectQkoGVK2Bnu5sdeL2lCE3HFnkIORGVQSIAHvTSthW7d0YESGTyYAxBmX0g/cON8gQzDDBXh9qqS8/GNP3wZrwEGDXbPILBvepFRBHa57vK1S9+/8jPzJ60P9olxeJAATEkVuuXl+u2H9RqTgFKSUnIuSyaWQyM867NSfg9h+HmmPCM0bIZDmIAe5ADyp96ZoGPmMMmUwGRATVfTUMq36AS4V2wqYAs+60CHOfRfrEx4FmwUwnJ4Gnj9Sd/PJ4Bu5TK+rt9f8B1bLc/9bqeJcbiQAEzOF9Qxkp5Z84jtgnpUybpoGurgwMzgFDQm06ApGZOj3RiYBUhsMwCDKXQnltX81gIc45MpkMAILK74VBtaPiJLowyS4N7y+og3KQPvFxMPfZ+s9IVY3vr3PDT55MQxzurZe991sAfic/Mtow01NCfRIBCImDey7llmXeopT6oOuKramUiVw2DcYYYLlQm49CpKZP+wdMs+ocJM5gb8zDNhdvCWadgop1g624Fgy1j/2m6RVw254dSMEav6Ox53+yUj3jryy2DuR4qjrxFzv5TqFq6n8mPzL6cIADXpYkAhABh/cObVBKfdIV4k2WaWSz2TSICJRyIDe8BJGZhlIKjBFSGQbOCbI7g8rqHogF1oBpmkilUlDGAFjvVTWP/hTSmGS72ugLkLDGb4NRfqT2r5UCXjwBvHBiUWIPNWnBPdy7sFqPBPBNALcD+PJSTc/VDhIBiJhnb77iZiHlBwyDb0tZVpYIAFdQ616C6JmAgoSVYrAsBhDgDPbC7k3Piwk4LQJ8FajvjeBYvB1waRDTdGGEf7MZlIPUqb8Ct+tsx49PAM8fX7Tqy1MpiOe7IV+aF0z1U1Qn/Z3JUV44JALQJp69+YoUgBvTaetCIroKwDkAgPwE1KqTkJYNK8VgmAQwgrNmBZycCTnzeXHOkU6nQSwL1XstDC6wMEagTC+DQ+sj+zuROIrU+GfAnF8s/uWJyerEL585xlRlA+JoDvJoDqp82rl3DMBdAG5brjf0oiQRgJhQKhbOAlAA8CYAr4MhUrTmJFRXGUaXADcVQIA7ULUIJNS8I0KZeRUoeyEMzE2YQSjTOXBoQ8ijFzCnvg5zanS+t18p4ORU1dSfreLrMoiXspBHcrOOPQHgXwF8B8C9AL6RHxnVq62W4JtEAGJIqVjIAbgCVTF4I7hYx3oqYL0VsBXToIwL2Z2Gu7IbrslhpSwYhgHFcpC5N8CwesDmbAts2ooKnR3KWLn9GMzJA2DuHAt9qgKUxoHjk4AroCoc6lQaopSBPJ6pQNL3UZ3w3wHwSH5k1HvetIRASQSgAygVC6sBXADgfAAXUNa5mPWVz2a9ZU7dNuRAGpRLg3VlgIwFRVmorivBra7TJwUOrUWFdgbjGFQVGOXvwpi+98zd/mkbODUFlMahTijIk2moUynI8dSUKhsP4syE/35+ZLS1kr4JgZEIQIdSKhYsAOcCOJ/S7msoZ7+K0u52yssutpaDVhhAJg3VdyFU5hyQ0QsGBzZthkPr4DXT8CwkT4I5B8Htx8HLj4KmTgLjZajjNtRR4aopdkJNmr+UJ9L/T02bPwbw1Mx/T+ZHRlvPeZ4QCokALDFKxUIewAAMuYqvnLqQsu4O6uNno5dvQP+aQZXf3oXMKlPwVSRTawg8O5Opd+Y/5YCJEsgtgdySoukXFTvxM4dOPFNW42oc4zgij+NHapw/Kk+lfgBJT+ZHRpvf2U2IJf8fyPQ3i4VjnZYAAAAASUVORK5CYII="; \ No newline at end of file diff --git a/sdk/tests/web-app/src/app/disclose/page.tsx b/sdk/tests/web-app/src/app/disclose/page.tsx deleted file mode 100644 index c4b777945..000000000 --- a/sdk/tests/web-app/src/app/disclose/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -'use client'; - -import SelfQRcodeWrapper, { SelfAppBuilder } from '@selfxyz/qrcode'; -import { v4 } from 'uuid'; -import {logo} from './logo'; - -export default function Prove() { - const userId = v4(); - - const selfApp = new SelfAppBuilder({ - appName: "Mock App2", - scope: "test-scope", - endpoint: "https://8ea8-157-131-196-195.ngrok-free.app/api/v1/verify-vc-and-disclose-proof", - logoBase64: logo, - userId, - disclosures: { - name: true, - nationality: true, - date_of_birth: true, - passport_number: true, - minimumAge: 20, - excludedCountries: [ - "AFG", "ALA", "ALB", "DZA", "ASM", "AND", "AGO", "AIA", "ATA", "ATG", "ARG", "ARM", "ABW", "AUS", "AZE", "BHS", - "BHR", "BGD", "BRB", "BLR", "BEL", "BMU", "BLZ", "BEN", "BMU", "BTN", "BOL", "BRN", "CPV", "KHM", "CAN", "CHN", - "EST", "DNK", "VUT", "ZWE", "ZMB", "YEM", "ESH", "USA" - ], - ofac: true, - } - }).build(); - - return ( -
- { - window.location.href = '/success'; - }} - onError={console.error} - /> -
- ); -} diff --git a/sdk/tests/web-app/src/app/favicon.ico b/sdk/tests/web-app/src/app/favicon.ico deleted file mode 100644 index 718d6fea4..000000000 Binary files a/sdk/tests/web-app/src/app/favicon.ico and /dev/null differ diff --git a/sdk/tests/web-app/src/app/fonts/GeistMonoVF.woff b/sdk/tests/web-app/src/app/fonts/GeistMonoVF.woff deleted file mode 100644 index f2ae185cb..000000000 Binary files a/sdk/tests/web-app/src/app/fonts/GeistMonoVF.woff and /dev/null differ diff --git a/sdk/tests/web-app/src/app/fonts/GeistVF.woff b/sdk/tests/web-app/src/app/fonts/GeistVF.woff deleted file mode 100644 index 1b62daacf..000000000 Binary files a/sdk/tests/web-app/src/app/fonts/GeistVF.woff and /dev/null differ diff --git a/sdk/tests/web-app/src/app/globals.css b/sdk/tests/web-app/src/app/globals.css deleted file mode 100644 index 13d40b892..000000000 --- a/sdk/tests/web-app/src/app/globals.css +++ /dev/null @@ -1,27 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; -} - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} diff --git a/sdk/tests/web-app/src/app/layout.tsx b/sdk/tests/web-app/src/app/layout.tsx deleted file mode 100644 index 2807dd219..000000000 --- a/sdk/tests/web-app/src/app/layout.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import type { Metadata } from 'next'; -import localFont from 'next/font/local'; -import './globals.css'; - -const geistSans = localFont({ - src: './fonts/GeistVF.woff', - variable: '--font-geist-sans', - weight: '100 900', -}); -const geistMono = localFont({ - src: './fonts/GeistMonoVF.woff', - variable: '--font-geist-mono', - weight: '100 900', -}); - -export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - {children} - - ); -} diff --git a/sdk/tests/web-app/src/app/page.tsx b/sdk/tests/web-app/src/app/page.tsx deleted file mode 100644 index 3e736c76d..000000000 --- a/sdk/tests/web-app/src/app/page.tsx +++ /dev/null @@ -1,41 +0,0 @@ -'use client'; - -import SelfQRcodeWrapper, { SelfAppBuilder, countries } from '@selfxyz/qrcode'; -import { v4 } from 'uuid'; - -export default function Home() { - const userId = v4(); - - const selfApp = new SelfAppBuilder({ - appName: "Self Workshop", - scope: "self-workshop", - endpoint: "https://1770-133-3-201-47.ngrok-free.app/api/verify", - logoBase64: "https://pluspng.com/img-png/images-owls-png-hd-owl-free-download-png-png-image-485.png", - userId, - disclosures: { - date_of_birth: true, - nationality: true, - excludedCountries: [ - countries.RUSSIA, - countries.CHINA, - countries.NORTH_KOREA, - countries.IRAN - ], - minimumAge: 18, - ofac: true, - } - }).build(); - - return ( -
- { - window.location.href = '/verified'; - }} - onError={console.error} - /> -
- ); -} diff --git a/sdk/tests/web-app/src/app/verified/page.module.css b/sdk/tests/web-app/src/app/verified/page.module.css deleted file mode 100644 index dd743a3a3..000000000 --- a/sdk/tests/web-app/src/app/verified/page.module.css +++ /dev/null @@ -1,51 +0,0 @@ -.rotatingTitle { - font-size: 4rem; - /* Increased from 3rem */ - font-weight: bold; - /* Gradient color for text only */ - background: linear-gradient(45deg, #1e40af, #7c3aed); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - /* Removed text-shadow to prevent blur */ - animation: rotate3D 3s infinite linear; - /* Faster: 5s → 3s */ - transform-style: preserve-3d; - perspective: 800px; - /* Increased from 500px for more dramatic effect */ - padding: 1.5rem; - /* Increased padding */ - position: relative; - display: inline-block; -} - -/* Remove the ::before element that created a background */ -.rotatingTitle::before { - display: none; -} - -@keyframes rotate3D { - 0% { - transform: rotateY(0deg) rotateX(0deg); - } - - 25% { - transform: rotateY(30deg) rotateX(15deg); - /* Increased angles for more dramatic rotation */ - } - - 50% { - transform: rotateY(0deg) rotateX(0deg); - } - - 75% { - transform: rotateY(-30deg) rotateX(-15deg); - /* Increased angles */ - } - - 100% { - transform: rotateY(0deg) rotateX(0deg); - } -} - -/* Remove the hover styles completely */ \ No newline at end of file diff --git a/sdk/tests/web-app/src/app/verified/page.tsx b/sdk/tests/web-app/src/app/verified/page.tsx deleted file mode 100644 index 77a96c5e8..000000000 --- a/sdk/tests/web-app/src/app/verified/page.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import Image from 'next/image'; -import styles from './page.module.css'; -import skeleton from './skeleton.gif'; - -export default function HomePage() { - return ( -
-
-

Identity Verified!

-
- -
- Loading animation -
-
- ); -} \ No newline at end of file diff --git a/sdk/tests/web-app/src/app/verified/skeleton.gif b/sdk/tests/web-app/src/app/verified/skeleton.gif deleted file mode 100644 index 0646ce778..000000000 Binary files a/sdk/tests/web-app/src/app/verified/skeleton.gif and /dev/null differ diff --git a/sdk/tests/web-app/tailwind.config.ts b/sdk/tests/web-app/tailwind.config.ts deleted file mode 100644 index 4dcc94ff8..000000000 --- a/sdk/tests/web-app/tailwind.config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Config } from 'tailwindcss'; - -const config: Config = { - content: [ - './src/pages/**/*.{js,ts,jsx,tsx,mdx}', - './src/components/**/*.{js,ts,jsx,tsx,mdx}', - './src/app/**/*.{js,ts,jsx,tsx,mdx}', - ], - theme: { - extend: { - colors: { - background: 'var(--background)', - foreground: 'var(--foreground)', - }, - }, - }, - plugins: [], -}; -export default config; diff --git a/sdk/tests/web-app/tsconfig.json b/sdk/tests/web-app/tsconfig.json deleted file mode 100644 index 3309399f7..000000000 --- a/sdk/tests/web-app/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["next-env.d.ts", "./src/**/*.ts", "./src/**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} diff --git a/yarn.lock b/yarn.lock index bde8831a6..c5ce9db42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,20 +12,6 @@ __metadata: languageName: node linkType: hard -"@adraffy/ens-normalize@npm:^1.10.1": - version: 1.11.0 - resolution: "@adraffy/ens-normalize@npm:1.11.0" - checksum: 10c0/5111d0f1a273468cb5661ed3cf46ee58de8f32f84e2ebc2365652e66c1ead82649df94c736804e2b9cfa831d30ef24e1cc3575d970dbda583416d3a98d8870a6 - languageName: node - linkType: hard - -"@alloc/quick-lru@npm:^5.2.0": - version: 5.2.0 - resolution: "@alloc/quick-lru@npm:5.2.0" - checksum: 10c0/7b878c48b9d25277d0e1a9b8b2f2312a314af806b4129dc902f2bc29ab09b58236e53964689feec187b28c80d2203aff03829754773a707a8a5987f1b7682d92 - languageName: node - linkType: hard - "@ampproject/remapping@npm:^2.2.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" @@ -197,7 +183,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.27.1": +"@babel/helper-module-imports@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: @@ -1070,13 +1056,6 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": - version: 7.27.3 - resolution: "@babel/runtime@npm:7.27.3" - checksum: 10c0/b860fe374a36fddbeeb238e52e59443abcacc046eebda1bf278bffbc67b5c8f713b939e09c126b086ca5f97cba1987ea17fd1737568bc50fedb1f6ef1cf46f69 - languageName: node - linkType: hard - "@babel/runtime@npm:^7.25.0": version: 7.26.9 resolution: "@babel/runtime@npm:7.26.9" @@ -1188,87 +1167,6 @@ __metadata: languageName: node linkType: hard -"@elysiajs/swagger@npm:^1.2.0": - version: 1.3.0 - resolution: "@elysiajs/swagger@npm:1.3.0" - dependencies: - "@scalar/themes": "npm:^0.9.52" - "@scalar/types": "npm:^0.0.12" - openapi-types: "npm:^12.1.3" - pathe: "npm:^1.1.2" - peerDependencies: - elysia: ">= 1.3.0" - checksum: 10c0/251b50d438175aadcaa19325ddfd30eb109cdc24fc7b9a4394d4da81dba02128248e30d8d1899e9fb4e023afcaf13a9edf1002285dfc540bd955f8cf9cf42733 - languageName: node - linkType: hard - -"@emnapi/core@npm:^1.4.3": - version: 1.4.3 - resolution: "@emnapi/core@npm:1.4.3" - dependencies: - "@emnapi/wasi-threads": "npm:1.0.2" - tslib: "npm:^2.4.0" - checksum: 10c0/e30101d16d37ef3283538a35cad60e22095aff2403fb9226a35330b932eb6740b81364d525537a94eb4fb51355e48ae9b10d779c0dd1cdcd55d71461fe4b45c7 - languageName: node - linkType: hard - -"@emnapi/runtime@npm:^1.4.3": - version: 1.4.3 - resolution: "@emnapi/runtime@npm:1.4.3" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/3b7ab72d21cb4e034f07df80165265f85f445ef3f581d1bc87b67e5239428baa00200b68a7d5e37a0425c3a78320b541b07f76c5530f6f6f95336a6294ebf30b - languageName: node - linkType: hard - -"@emnapi/wasi-threads@npm:1.0.2": - version: 1.0.2 - resolution: "@emnapi/wasi-threads@npm:1.0.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/f0621b1fc715221bd2d8332c0ca922617bcd77cdb3050eae50a124eb8923c54fa425d23982dc8f29d505c8798a62d1049bace8b0686098ff9dd82270e06d772e - languageName: node - linkType: hard - -"@emotion/babel-plugin@npm:^11.13.5": - version: 11.13.5 - resolution: "@emotion/babel-plugin@npm:11.13.5" - dependencies: - "@babel/helper-module-imports": "npm:^7.16.7" - "@babel/runtime": "npm:^7.18.3" - "@emotion/hash": "npm:^0.9.2" - "@emotion/memoize": "npm:^0.9.0" - "@emotion/serialize": "npm:^1.3.3" - babel-plugin-macros: "npm:^3.1.0" - convert-source-map: "npm:^1.5.0" - escape-string-regexp: "npm:^4.0.0" - find-root: "npm:^1.1.0" - source-map: "npm:^0.5.7" - stylis: "npm:4.2.0" - checksum: 10c0/8ccbfec7defd0e513cb8a1568fa179eac1e20c35fda18aed767f6c59ea7314363ebf2de3e9d2df66c8ad78928dc3dceeded84e6fa8059087cae5c280090aeeeb - languageName: node - linkType: hard - -"@emotion/cache@npm:^11.13.5, @emotion/cache@npm:^11.14.0": - version: 11.14.0 - resolution: "@emotion/cache@npm:11.14.0" - dependencies: - "@emotion/memoize": "npm:^0.9.0" - "@emotion/sheet": "npm:^1.4.0" - "@emotion/utils": "npm:^1.4.2" - "@emotion/weak-memoize": "npm:^0.4.0" - stylis: "npm:4.2.0" - checksum: 10c0/3fa3e7a431ab6f8a47c67132a00ac8358f428c1b6c8421d4b20de9df7c18e95eec04a5a6ff5a68908f98d3280044f247b4965ac63df8302d2c94dba718769724 - languageName: node - linkType: hard - -"@emotion/hash@npm:^0.9.2": - version: 0.9.2 - resolution: "@emotion/hash@npm:0.9.2" - checksum: 10c0/0dc254561a3cc0a06a10bbce7f6a997883fd240c8c1928b93713f803a2e9153a257a488537012efe89dbe1246f2abfe2add62cdb3471a13d67137fcb808e81c2 - languageName: node - linkType: hard - "@emotion/is-prop-valid@npm:^0.8.2": version: 0.8.8 resolution: "@emotion/is-prop-valid@npm:0.8.8" @@ -1278,15 +1176,6 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.3.0": - version: 1.3.1 - resolution: "@emotion/is-prop-valid@npm:1.3.1" - dependencies: - "@emotion/memoize": "npm:^0.9.0" - checksum: 10c0/123215540c816ff510737ec68dcc499c53ea4deb0bb6c2c27c03ed21046e2e69f6ad07a7a174d271c6cfcbcc9ea44e1763e0cf3875c92192f7689216174803cd - languageName: node - linkType: hard - "@emotion/memoize@npm:0.7.4": version: 0.7.4 resolution: "@emotion/memoize@npm:0.7.4" @@ -1294,104 +1183,6 @@ __metadata: languageName: node linkType: hard -"@emotion/memoize@npm:^0.9.0": - version: 0.9.0 - resolution: "@emotion/memoize@npm:0.9.0" - checksum: 10c0/13f474a9201c7f88b543e6ea42f55c04fb2fdc05e6c5a3108aced2f7e7aa7eda7794c56bba02985a46d8aaa914fcdde238727a98341a96e2aec750d372dadd15 - languageName: node - linkType: hard - -"@emotion/react@npm:^11.13.3": - version: 11.14.0 - resolution: "@emotion/react@npm:11.14.0" - dependencies: - "@babel/runtime": "npm:^7.18.3" - "@emotion/babel-plugin": "npm:^11.13.5" - "@emotion/cache": "npm:^11.14.0" - "@emotion/serialize": "npm:^1.3.3" - "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.2.0" - "@emotion/utils": "npm:^1.4.2" - "@emotion/weak-memoize": "npm:^0.4.0" - hoist-non-react-statics: "npm:^3.3.1" - peerDependencies: - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/d0864f571a9f99ec643420ef31fde09e2006d3943a6aba079980e4d5f6e9f9fecbcc54b8f617fe003c00092ff9d5241179149ffff2810cb05cf72b4620cfc031 - languageName: node - linkType: hard - -"@emotion/serialize@npm:^1.3.3": - version: 1.3.3 - resolution: "@emotion/serialize@npm:1.3.3" - dependencies: - "@emotion/hash": "npm:^0.9.2" - "@emotion/memoize": "npm:^0.9.0" - "@emotion/unitless": "npm:^0.10.0" - "@emotion/utils": "npm:^1.4.2" - csstype: "npm:^3.0.2" - checksum: 10c0/b28cb7de59de382021de2b26c0c94ebbfb16967a1b969a56fdb6408465a8993df243bfbd66430badaa6800e1834724e84895f5a6a9d97d0d224de3d77852acb4 - languageName: node - linkType: hard - -"@emotion/sheet@npm:^1.4.0": - version: 1.4.0 - resolution: "@emotion/sheet@npm:1.4.0" - checksum: 10c0/3ca72d1650a07d2fbb7e382761b130b4a887dcd04e6574b2d51ce578791240150d7072a9bcb4161933abbcd1e38b243a6fb4464a7fe991d700c17aa66bb5acc7 - languageName: node - linkType: hard - -"@emotion/styled@npm:^11.13.0": - version: 11.14.0 - resolution: "@emotion/styled@npm:11.14.0" - dependencies: - "@babel/runtime": "npm:^7.18.3" - "@emotion/babel-plugin": "npm:^11.13.5" - "@emotion/is-prop-valid": "npm:^1.3.0" - "@emotion/serialize": "npm:^1.3.3" - "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.2.0" - "@emotion/utils": "npm:^1.4.2" - peerDependencies: - "@emotion/react": ^11.0.0-rc.0 - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/20aa5c488e4edecf63659212fc5ba1ccff2d3a66593fc8461de7cd5fe9192a741db357ffcd270a455bd61898d7f37cd5c84b4fd2b7974dade712badf7860ca9c - languageName: node - linkType: hard - -"@emotion/unitless@npm:^0.10.0": - version: 0.10.0 - resolution: "@emotion/unitless@npm:0.10.0" - checksum: 10c0/150943192727b7650eb9a6851a98034ddb58a8b6958b37546080f794696141c3760966ac695ab9af97efe10178690987aee4791f9f0ad1ff76783cdca83c1d49 - languageName: node - linkType: hard - -"@emotion/use-insertion-effect-with-fallbacks@npm:^1.2.0": - version: 1.2.0 - resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.2.0" - peerDependencies: - react: ">=16.8.0" - checksum: 10c0/074dbc92b96bdc09209871070076e3b0351b6b47efefa849a7d9c37ab142130767609ca1831da0055988974e3b895c1de7606e4c421fecaa27c3e56a2afd3b08 - languageName: node - linkType: hard - -"@emotion/utils@npm:^1.4.2": - version: 1.4.2 - resolution: "@emotion/utils@npm:1.4.2" - checksum: 10c0/7d0010bf60a2a8c1a033b6431469de4c80e47aeb8fd856a17c1d1f76bbc3a03161a34aeaa78803566e29681ca551e7bf9994b68e9c5f5c796159923e44f78d9a - languageName: node - linkType: hard - -"@emotion/weak-memoize@npm:^0.4.0": - version: 0.4.0 - resolution: "@emotion/weak-memoize@npm:0.4.0" - checksum: 10c0/64376af11f1266042d03b3305c30b7502e6084868e33327e944b539091a472f089db307af69240f7188f8bc6b319276fd7b141a36613f1160d73d12a60f6ca1a - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/aix-ppc64@npm:0.25.5" @@ -1578,7 +1369,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 @@ -2535,7 +2326,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.8 resolution: "@jridgewell/gen-mapping@npm:0.3.8" dependencies: @@ -2662,309 +2453,6 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^6.4.11": - version: 6.4.11 - resolution: "@mui/core-downloads-tracker@npm:6.4.11" - checksum: 10c0/6875a06188119320083566bbe000369a838ea4badbae81fb36fcc750103f3c9ec15fac3407c1efd7f3596889f30732780c58842434d0d48f997219192f7fc3d1 - languageName: node - linkType: hard - -"@mui/material@npm:^6.0.2": - version: 6.4.11 - resolution: "@mui/material@npm:6.4.11" - dependencies: - "@babel/runtime": "npm:^7.26.0" - "@mui/core-downloads-tracker": "npm:^6.4.11" - "@mui/system": "npm:^6.4.11" - "@mui/types": "npm:~7.2.24" - "@mui/utils": "npm:^6.4.9" - "@popperjs/core": "npm:^2.11.8" - "@types/react-transition-group": "npm:^4.4.12" - clsx: "npm:^2.1.1" - csstype: "npm:^3.1.3" - prop-types: "npm:^15.8.1" - react-is: "npm:^19.0.0" - react-transition-group: "npm:^4.4.5" - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@mui/material-pigment-css": ^6.4.11 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@mui/material-pigment-css": - optional: true - "@types/react": - optional: true - checksum: 10c0/49640579e299ef650e6efe25ceb479fe2df8636ebebd00a9d1e7dd32d2cd3c81a99f093f4fb6de58a6463f2be4f5c93fb6331ded6085f0ebeea3a30629fe8ecb - languageName: node - linkType: hard - -"@mui/private-theming@npm:^6.4.9": - version: 6.4.9 - resolution: "@mui/private-theming@npm:6.4.9" - dependencies: - "@babel/runtime": "npm:^7.26.0" - "@mui/utils": "npm:^6.4.9" - prop-types: "npm:^15.8.1" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/3b198fad085b9ce5092cb2ad2aceee5f6a643f68f4fb1469d0748615490b8b9228179a6564be9c6784aa6f1f42a9afe61f1ad5ce0af56858e9bb58d36472e339 - languageName: node - linkType: hard - -"@mui/styled-engine@npm:^6.4.11": - version: 6.4.11 - resolution: "@mui/styled-engine@npm:6.4.11" - dependencies: - "@babel/runtime": "npm:^7.26.0" - "@emotion/cache": "npm:^11.13.5" - "@emotion/serialize": "npm:^1.3.3" - "@emotion/sheet": "npm:^1.4.0" - csstype: "npm:^3.1.3" - prop-types: "npm:^15.8.1" - peerDependencies: - "@emotion/react": ^11.4.1 - "@emotion/styled": ^11.3.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - checksum: 10c0/332ff6c32e7bfb34e9cd8a3d8d4abb13deaeea3216fb6d1441d8d154c615a76d594595cc34076bc0911f7f4784042a7fe0a83bf1924e78040935fa7242ee5a70 - languageName: node - linkType: hard - -"@mui/system@npm:^6.4.11": - version: 6.4.11 - resolution: "@mui/system@npm:6.4.11" - dependencies: - "@babel/runtime": "npm:^7.26.0" - "@mui/private-theming": "npm:^6.4.9" - "@mui/styled-engine": "npm:^6.4.11" - "@mui/types": "npm:~7.2.24" - "@mui/utils": "npm:^6.4.9" - clsx: "npm:^2.1.1" - csstype: "npm:^3.1.3" - prop-types: "npm:^15.8.1" - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: 10c0/6d1875232d8836c84b6f94bf32215f8b46370c98c4948a68ba934ef2baa652a5eb08e3048fa77ad16c464167a4d8d0548809d62d5f221829cfa744a5cdd90be5 - languageName: node - linkType: hard - -"@mui/types@npm:~7.2.24": - version: 7.2.24 - resolution: "@mui/types@npm:7.2.24" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/7756339cae70e9b684c4311924e4e3882f908552b69c434b4d13faf2f5908ce72fe889a31890257c5ad42a085207be7c1661981dfc683293e90ac6dfac3759d0 - languageName: node - linkType: hard - -"@mui/utils@npm:^6.4.9": - version: 6.4.9 - resolution: "@mui/utils@npm:6.4.9" - dependencies: - "@babel/runtime": "npm:^7.26.0" - "@mui/types": "npm:~7.2.24" - "@types/prop-types": "npm:^15.7.14" - clsx: "npm:^2.1.1" - prop-types: "npm:^15.8.1" - react-is: "npm:^19.0.0" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/27122262bc24d31e8906e3133f3f6e6c858733802019e0e9ec6dedf632ca46287ab3735c9da6be7a7e0b4f043ced9b8f36b5b21bfef1d96ecfa5d150ea458508 - languageName: node - linkType: hard - -"@napi-rs/wasm-runtime@npm:^0.2.10": - version: 0.2.10 - resolution: "@napi-rs/wasm-runtime@npm:0.2.10" - dependencies: - "@emnapi/core": "npm:^1.4.3" - "@emnapi/runtime": "npm:^1.4.3" - "@tybys/wasm-util": "npm:^0.9.0" - checksum: 10c0/4dce9bbb94a8969805574e1b55fdbeb7623348190265d77f6507ba32e535610deeb53a33ba0bb8b05a6520f379d418b92e8a01c5cd7b9486b136d2c0c26be0bd - languageName: node - linkType: hard - -"@next/env@npm:14.2.29": - version: 14.2.29 - resolution: "@next/env@npm:14.2.29" - checksum: 10c0/f4579139610a3a6eab5dfc92a982ed3530350e2b7d29993ca4b76aee3f23e9c4244fcee9f24e85bc7840e84a375fbfa819deced9f0c2aeb3bdd86b5d57abd23e - languageName: node - linkType: hard - -"@next/env@npm:14.2.8": - version: 14.2.8 - resolution: "@next/env@npm:14.2.8" - checksum: 10c0/8fd09c932ff472c9fd6c58c532f85972b7b0c72ef40bd937034ae34f3ff2692d6c829ef31b30eda761d467b1cd2c7ab7ad31aed829547546483e8beaf6d753f9 - languageName: node - linkType: hard - -"@next/eslint-plugin-next@npm:14.2.8": - version: 14.2.8 - resolution: "@next/eslint-plugin-next@npm:14.2.8" - dependencies: - glob: "npm:10.3.10" - checksum: 10c0/577b336feae3cd915af5befd6fd0e733e396b98dcdce792e406a7ebf020cc4a206e44f16d8cfb21416000086951c1f0eef37a6492551eae64c3e756c81356c95 - languageName: node - linkType: hard - -"@next/swc-darwin-arm64@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-darwin-arm64@npm:14.2.29" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-darwin-arm64@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-darwin-arm64@npm:14.2.8" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-darwin-x64@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-darwin-x64@npm:14.2.29" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@next/swc-darwin-x64@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-darwin-x64@npm:14.2.8" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@next/swc-linux-arm64-gnu@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-linux-arm64-gnu@npm:14.2.29" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-arm64-gnu@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-linux-arm64-gnu@npm:14.2.8" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-arm64-musl@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-linux-arm64-musl@npm:14.2.29" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-linux-arm64-musl@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-linux-arm64-musl@npm:14.2.8" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-linux-x64-gnu@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-linux-x64-gnu@npm:14.2.29" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-x64-gnu@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-linux-x64-gnu@npm:14.2.8" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-x64-musl@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-linux-x64-musl@npm:14.2.29" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-linux-x64-musl@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-linux-x64-musl@npm:14.2.8" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-win32-arm64-msvc@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-win32-arm64-msvc@npm:14.2.29" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-win32-arm64-msvc@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-win32-arm64-msvc@npm:14.2.8" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-win32-ia32-msvc@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-win32-ia32-msvc@npm:14.2.29" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@next/swc-win32-ia32-msvc@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-win32-ia32-msvc@npm:14.2.8" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@next/swc-win32-x64-msvc@npm:14.2.29": - version: 14.2.29 - resolution: "@next/swc-win32-x64-msvc@npm:14.2.29" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@next/swc-win32-x64-msvc@npm:14.2.8": - version: 14.2.8 - resolution: "@next/swc-win32-x64-msvc@npm:14.2.8" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": version: 5.1.1-v1 resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" @@ -2974,13 +2462,6 @@ __metadata: languageName: node linkType: hard -"@noble/ciphers@npm:^1.3.0": - version: 1.3.0 - resolution: "@noble/ciphers@npm:1.3.0" - checksum: 10c0/3ba6da645ce45e2f35e3b2e5c87ceba86b21dfa62b9466ede9edfb397f8116dae284f06652c0cd81d99445a2262b606632e868103d54ecc99fd946ae1af8cd37 - languageName: node - linkType: hard - "@noble/curves@npm:1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" @@ -2999,7 +2480,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.9.1, @noble/curves@npm:^1.4.2, @noble/curves@npm:^1.6.0, @noble/curves@npm:~1.9.0": +"@noble/curves@npm:^1.4.2": version: 1.9.1 resolution: "@noble/curves@npm:1.9.1" dependencies: @@ -3045,7 +2526,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.5, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.5.0, @noble/hashes@npm:~1.8.0": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.4.0": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: 10c0/06a0b52c81a6fa7f04d67762e08b2c476a00285858150caeaaff4037356dd5e119f45b2a530f638b77a5eeca013168ec1b655db41bae3236cb2e9d511484fc77 @@ -3093,13 +2574,6 @@ __metadata: languageName: node linkType: hard -"@nolyfill/is-core-module@npm:1.0.39": - version: 1.0.39 - resolution: "@nolyfill/is-core-module@npm:1.0.39" - checksum: 10c0/34ab85fdc2e0250879518841f74a30c276bca4f6c3e13526d2d1fe515e1adf6d46c25fcd5989d22ea056d76f7c39210945180b4859fc83b050e2da411aa86289 - languageName: node - linkType: hard - "@nomicfoundation/edr-darwin-arm64@npm:0.11.0": version: 0.11.0 resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.11.0" @@ -3502,15 +2976,6 @@ __metadata: languageName: node linkType: hard -"@paralleldrive/cuid2@npm:^2.2.2": - version: 2.2.2 - resolution: "@paralleldrive/cuid2@npm:2.2.2" - dependencies: - "@noble/hashes": "npm:^1.1.5" - checksum: 10c0/af5826df93de437121308f4f4ce0b2eeb89b60bb57a1a6592fb89c0d40d311ad1d9f3f6a4db2cce6f2bcf572de1aa3f85704254e89b18ce61c41ebb06564c4ee - languageName: node - linkType: hard - "@peculiar/asn1-cms@npm:^2.3.13, @peculiar/asn1-cms@npm:^2.3.15": version: 2.3.15 resolution: "@peculiar/asn1-cms@npm:2.3.15" @@ -3670,13 +3135,6 @@ __metadata: languageName: node linkType: hard -"@popperjs/core@npm:^2.11.8": - version: 2.11.8 - resolution: "@popperjs/core@npm:2.11.8" - checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63 - languageName: node - linkType: hard - "@puppeteer/browsers@npm:2.2.2": version: 2.2.2 resolution: "@puppeteer/browsers@npm:2.2.2" @@ -4547,68 +4005,6 @@ __metadata: languageName: node linkType: hard -"@rtsao/scc@npm:^1.1.0": - version: 1.1.0 - resolution: "@rtsao/scc@npm:1.1.0" - checksum: 10c0/b5bcfb0d87f7d1c1c7c0f7693f53b07866ed9fec4c34a97a8c948fb9a7c0082e416ce4d3b60beb4f5e167cbe04cdeefbf6771320f3ede059b9ce91188c409a5b - languageName: node - linkType: hard - -"@rushstack/eslint-patch@npm:^1.3.3": - version: 1.11.0 - resolution: "@rushstack/eslint-patch@npm:1.11.0" - checksum: 10c0/abea8d8cf2f4f50343f74abd6a8173c521ddd09b102021f5aa379ef373c40af5948b23db0e87eca1682e559e09d97d3f0c48ea71edad682c6bf72b840c8675b3 - languageName: node - linkType: hard - -"@scalar/openapi-types@npm:0.1.1": - version: 0.1.1 - resolution: "@scalar/openapi-types@npm:0.1.1" - checksum: 10c0/ef7108a7621b936694a153875ab85bf720fbf8369d4125778653dfb88a41da3308cdf55167da39052c382035766eae95c89fc2ab50f7346b87309f6fb65bd5bf - languageName: node - linkType: hard - -"@scalar/openapi-types@npm:0.2.0": - version: 0.2.0 - resolution: "@scalar/openapi-types@npm:0.2.0" - dependencies: - zod: "npm:^3.23.8" - checksum: 10c0/d96c826c4d595a712fa1e27739e635fe2cfa680183b97aec6e93b0cbdcd1ecf7ebb057506b3769b8e07eb569e1d73e01e66567e12d42cabd900486577355174a - languageName: node - linkType: hard - -"@scalar/themes@npm:^0.9.52": - version: 0.9.86 - resolution: "@scalar/themes@npm:0.9.86" - dependencies: - "@scalar/types": "npm:0.1.7" - checksum: 10c0/e9293c72cc3966919152c61d4904844c7428a33d123d06c324e363d22a0b9aaeaacd760c4c0d03f96234bab47f133f2b49ff9951aa102e1587a5160457506d77 - languageName: node - linkType: hard - -"@scalar/types@npm:0.1.7": - version: 0.1.7 - resolution: "@scalar/types@npm:0.1.7" - dependencies: - "@scalar/openapi-types": "npm:0.2.0" - "@unhead/schema": "npm:^1.11.11" - nanoid: "npm:^5.1.5" - type-fest: "npm:^4.20.0" - zod: "npm:^3.23.8" - checksum: 10c0/6d3ed7e358f9062901b3789da546a40feb8cecaaed40580e0d9e672ef4909781015eb9b8f3f905faeae0f73836989e23a97a6361010b32f47809574806183b27 - languageName: node - linkType: hard - -"@scalar/types@npm:^0.0.12": - version: 0.0.12 - resolution: "@scalar/types@npm:0.0.12" - dependencies: - "@scalar/openapi-types": "npm:0.1.1" - "@unhead/schema": "npm:^1.9.5" - checksum: 10c0/5776818cc732b4784b2406c1e81ce9916de6149c0f3452907372a6fd97fdcc2e7982acf7aee2832e1a7e08c47d3fff3e965009d612194870929747a0c21b4b5c - languageName: node - linkType: hard - "@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.6": version: 1.1.9 resolution: "@scure/base@npm:1.1.9" @@ -4645,17 +4041,6 @@ __metadata: languageName: node linkType: hard -"@scure/bip32@npm:1.7.0, @scure/bip32@npm:^1.5.0": - version: 1.7.0 - resolution: "@scure/bip32@npm:1.7.0" - dependencies: - "@noble/curves": "npm:~1.9.0" - "@noble/hashes": "npm:~1.8.0" - "@scure/base": "npm:~1.2.5" - checksum: 10c0/e3d4c1f207df16abcd79babcdb74d36f89bdafc90bf02218a5140cc5cba25821d80d42957c6705f35210cc5769714ea9501d4ae34732cdd1c26c9ff182a219f7 - languageName: node - linkType: hard - "@scure/bip39@npm:1.1.1": version: 1.1.1 resolution: "@scure/bip39@npm:1.1.1" @@ -4676,16 +4061,6 @@ __metadata: languageName: node linkType: hard -"@scure/bip39@npm:1.6.0, @scure/bip39@npm:^1.4.0": - version: 1.6.0 - resolution: "@scure/bip39@npm:1.6.0" - dependencies: - "@noble/hashes": "npm:~1.8.0" - "@scure/base": "npm:~1.2.5" - checksum: 10c0/73a54b5566a50a3f8348a5cfd74d2092efeefc485efbed83d7a7374ffd9a75defddf446e8e5ea0385e4adb49a94b8ae83c5bad3e16333af400e932f7da3aaff8 - languageName: node - linkType: hard - "@segment/analytics-react-native@npm:^2.21.0": version: 2.21.0 resolution: "@segment/analytics-react-native@npm:2.21.0" @@ -4884,23 +4259,6 @@ __metadata: languageName: unknown linkType: soft -"@selfxyz/core@npm:^0.0.3": - version: 0.0.3 - resolution: "@selfxyz/core@npm:0.0.3" - dependencies: - "@types/react": "npm:^18.3.4" - "@types/react-dom": "npm:^18.3.0" - "@types/uuid": "npm:^10.0.0" - ethers: "npm:^6.13.5" - next: "npm:^14.2.8" - snarkjs: "npm:^0.7.4" - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: 10c0/5d1e5b4a8627126f727dfad34078f747cbf08a629d74bc83a24dbceb13ca365e35d0ed82a09b1cafeba5e3c1cc0ea76c0a47d8afb4695b63c0941fb200902500 - languageName: node - linkType: hard - "@selfxyz/core@workspace:sdk/core": version: 0.0.0-use.local resolution: "@selfxyz/core@workspace:sdk/core" @@ -5033,7 +4391,7 @@ __metadata: languageName: unknown linkType: soft -"@selfxyz/qrcode@workspace:^, @selfxyz/qrcode@workspace:sdk/qrcode": +"@selfxyz/qrcode@workspace:sdk/qrcode": version: 0.0.0-use.local resolution: "@selfxyz/qrcode@workspace:sdk/qrcode" dependencies: @@ -5388,13 +4746,6 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.34.33": - version: 0.34.33 - resolution: "@sinclair/typebox@npm:0.34.33" - checksum: 10c0/88ab4f7afc7514d576602dce5c892462a89f9082d77dde0e8e21342b3a5c8891ddfc51a65e7dbd5b3f5cbd8f5cb76aded0c0edcfcfb5730f189c2819de9583a7 - languageName: node - linkType: hard - "@sindresorhus/is@npm:^4.0.0": version: 4.6.0 resolution: "@sindresorhus/is@npm:4.6.0" @@ -6908,23 +6259,6 @@ __metadata: languageName: node linkType: hard -"@swc/counter@npm:^0.1.3": - version: 0.1.3 - resolution: "@swc/counter@npm:0.1.3" - checksum: 10c0/8424f60f6bf8694cfd2a9bca45845bce29f26105cda8cf19cdb9fd3e78dc6338699e4db77a89ae449260bafa1cc6bec307e81e7fb96dbf7dcfce0eea55151356 - languageName: node - linkType: hard - -"@swc/helpers@npm:0.5.5": - version: 0.5.5 - resolution: "@swc/helpers@npm:0.5.5" - dependencies: - "@swc/counter": "npm:^0.1.3" - tslib: "npm:^2.4.0" - checksum: 10c0/21a9b9cfe7e00865f9c9f3eb4c1cc5b397143464f7abee76a2c5366e591e06b0155b5aac93fe8269ef8d548df253f6fd931e9ddfc0fd12efd405f90f45506e7d - languageName: node - linkType: hard - "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -8338,15 +7672,6 @@ __metadata: languageName: node linkType: hard -"@tybys/wasm-util@npm:^0.9.0": - version: 0.9.0 - resolution: "@tybys/wasm-util@npm:0.9.0" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/f9fde5c554455019f33af6c8215f1a1435028803dc2a2825b077d812bed4209a1a64444a4ca0ce2ea7e1175c8d88e2f9173a36a33c199e8a5c671aa31de8242d - languageName: node - linkType: hard - "@typechain/ethers-v6@npm:^0.4.3": version: 0.4.3 resolution: "@typechain/ethers-v6@npm:0.4.3" @@ -8628,7 +7953,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -8642,7 +7967,7 @@ __metadata: languageName: node linkType: hard -"@types/keyv@npm:^3.1.1, @types/keyv@npm:^3.1.4": +"@types/keyv@npm:^3.1.4": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" dependencies: @@ -8715,7 +8040,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20, @types/node@npm:^20.11.19": +"@types/node@npm:^20.11.19": version: 20.17.51 resolution: "@types/node@npm:20.17.51" dependencies: @@ -8738,13 +8063,6 @@ __metadata: languageName: node linkType: hard -"@types/parse-json@npm:^4.0.0": - version: 4.0.2 - resolution: "@types/parse-json@npm:4.0.2" - checksum: 10c0/b1b863ac34a2c2172fbe0807a1ec4d5cb684e48d422d15ec95980b81475fac4fdb3768a8b13eef39130203a7c04340fc167bae057c7ebcafd7dec9fe6c36aeb1 - languageName: node - linkType: hard - "@types/pbkdf2@npm:^3.0.0": version: 3.1.2 resolution: "@types/pbkdf2@npm:3.1.2" @@ -8754,17 +8072,6 @@ __metadata: languageName: node linkType: hard -"@types/pg@npm:^8.11.11": - version: 8.15.2 - resolution: "@types/pg@npm:8.15.2" - dependencies: - "@types/node": "npm:*" - pg-protocol: "npm:*" - pg-types: "npm:^4.0.1" - checksum: 10c0/e3bc75f02af897ed960e83d1af9bd0cba1ff41cd0cbae0eaee323eae84f55e6d433f620aa1c72f7bd5107c80b018185c0e47de553cfc5439514c3da98768ef6c - languageName: node - linkType: hard - "@types/prettier@npm:^2.1.1": version: 2.7.3 resolution: "@types/prettier@npm:2.7.3" @@ -8772,7 +8079,7 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.14": +"@types/prop-types@npm:*": version: 15.7.14 resolution: "@types/prop-types@npm:15.7.14" checksum: 10c0/1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1 @@ -8786,7 +8093,7 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18, @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: @@ -8827,15 +8134,6 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.4.12": - version: 4.4.12 - resolution: "@types/react-transition-group@npm:4.4.12" - peerDependencies: - "@types/react": "*" - checksum: 10c0/0441b8b47c69312c89ec0760ba477ba1a0808a10ceef8dc1c64b1013ed78517332c30f18681b0ec0b53542731f1ed015169fed1d127cc91222638ed955478ec7 - languageName: node - linkType: hard - "@types/react@npm:^18, @types/react@npm:^18.2.6, @types/react@npm:^18.3.4": version: 18.3.23 resolution: "@types/react@npm:18.3.23" @@ -8864,7 +8162,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.1.0, @types/semver@npm:^7.3.12, @types/semver@npm:^7.5.0": +"@types/semver@npm:^7.1.0, @types/semver@npm:^7.3.12": version: 7.7.0 resolution: "@types/semver@npm:7.7.0" checksum: 10c0/6b5f65f647474338abbd6ee91a6bbab434662ddb8fe39464edcbcfc96484d388baad9eb506dff217b6fc1727a88894930eb1f308617161ac0f376fe06be4e1ee @@ -8933,31 +8231,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.2.0" - dependencies: - "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/type-utils": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - debug: "npm:^4.3.4" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.4" - natural-compare: "npm:^1.4.0" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" - peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/8725c2193a16cc103a697d6e408c515a7618df3902dc504cf69999f60634dac79ce14a5bd942f0388ba7547caba44ac40e01097cda1106aa3912e2303dada8ab - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:^7.1.1": version: 7.18.0 resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" @@ -8981,24 +8254,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/parser@npm:7.2.0" - dependencies: - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/11ce36c68212fdbf98fc6fd32ba0977d46b645fd669a3f4fdb8be2036225f86ad005b31a66f97097e90517c44c92cf9cc5fb1d6e9647ee2fa125c4af21cdb477 - languageName: node - linkType: hard - "@typescript-eslint/parser@npm:^7.1.1": version: 7.18.0 resolution: "@typescript-eslint/parser@npm:7.18.0" @@ -9048,16 +8303,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/scope-manager@npm:7.2.0" - dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - checksum: 10c0/4d088c127e6ba1a7de8567f70684779083be24b48746c3b4a86a0ec7062bca58693ee08482349ad6572a17ada8aa6f26b74d1c7139c8fcf7101fa09a572e0ea6 - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:8.33.0": version: 8.33.0 resolution: "@typescript-eslint/scope-manager@npm:8.33.0" @@ -9094,23 +8339,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/type-utils@npm:7.2.0" - dependencies: - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.0.1" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/069b65ef327e1bfa1e59009504c8307f88f3673ebcc23d17ad370452ece107013c9dc321876092673d2c02ddd35104f67231b31b0e4f7d5ca6fbf95b43f828b2 - languageName: node - linkType: hard - "@typescript-eslint/types@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/types@npm:5.62.0" @@ -9125,13 +8353,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/types@npm:7.2.0" - checksum: 10c0/135aae061720185855bea61ea6cfd33f4801d2de57f65e50079bbdb505100f844632aa4e4bdeec9e9e79d29aaddad949178d0e918e41867da6ab4b1390820e33 - languageName: node - linkType: hard - "@typescript-eslint/types@npm:8.33.0, @typescript-eslint/types@npm:^8.33.0": version: 8.33.0 resolution: "@typescript-eslint/types@npm:8.33.0" @@ -9176,25 +8397,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.2.0" - dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/2730bb17730e6f3ca4061f00688a70386a808f5d174fdeb757c3cfa92c455373f69080df33237c1a8970e818af0cea0ae5a083970ed8ba493f3b04458c6f9271 - languageName: node - linkType: hard - "@typescript-eslint/typescript-estree@npm:8.33.0": version: 8.33.0 resolution: "@typescript-eslint/typescript-estree@npm:8.33.0" @@ -9229,23 +8431,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/utils@npm:7.2.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" - semver: "npm:^7.5.4" - peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/37944e1a4038820da82b51ac4756e09cff31851d9d957d3fd67a3b6fd2cf6c0e87767161eaeb8b6e63de418e513bb2570a6ee3fa986ba77f6d451d66a538f753 - languageName: node - linkType: hard - "@typescript-eslint/utils@npm:^5.10.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" @@ -9299,16 +8484,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.2.0" - dependencies: - "@typescript-eslint/types": "npm:7.2.0" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/2d7467495b2b76f3edb1b3047e97076c2242e7eca6d50bbbdd88219f9ff754dbcb9334a0568fe0ceb4c562823980938bd278aa2ba53da6343e7d99a167924f24 - languageName: node - linkType: hard - "@typescript-eslint/visitor-keys@npm:8.33.0": version: 8.33.0 resolution: "@typescript-eslint/visitor-keys@npm:8.33.0" @@ -9326,137 +8501,6 @@ __metadata: languageName: node linkType: hard -"@unhead/schema@npm:^1.11.11, @unhead/schema@npm:^1.9.5": - version: 1.11.20 - resolution: "@unhead/schema@npm:1.11.20" - dependencies: - hookable: "npm:^5.5.3" - zhead: "npm:^2.2.4" - checksum: 10c0/f2f968639bbd18f90ddfb83b77c9256bc4c0379ab75efa24dc759f3f597aae707d4dde97df690823f8902eab31d73a5faa8bdd8daf18c6ac8e4503a78b42be74 - languageName: node - linkType: hard - -"@unrs/resolver-binding-darwin-arm64@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.7.5" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-darwin-x64@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-darwin-x64@npm:1.7.5" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-freebsd-x64@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.7.5" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.7.5" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.7.5" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm64-gnu@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.7.5" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-arm64-musl@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.7.5" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.7.5" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.7.5" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-riscv64-musl@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.7.5" - conditions: os=linux & cpu=riscv64 & libc=musl - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-s390x-gnu@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.7.5" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-x64-gnu@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.7.5" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@unrs/resolver-binding-linux-x64-musl@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.7.5" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@unrs/resolver-binding-wasm32-wasi@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.7.5" - dependencies: - "@napi-rs/wasm-runtime": "npm:^0.2.10" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@unrs/resolver-binding-win32-arm64-msvc@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.7.5" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@unrs/resolver-binding-win32-ia32-msvc@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.7.5" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@unrs/resolver-binding-win32-x64-msvc@npm:1.7.5": - version: 1.7.5 - resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.7.5" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": version: 1.14.1 resolution: "@webassemblyjs/ast@npm:1.14.1" @@ -9848,13 +8892,6 @@ __metadata: languageName: node linkType: hard -"URIjs@npm:^1.16.0": - version: 1.16.1 - resolution: "URIjs@npm:1.16.1" - checksum: 10c0/4709474a384394d4b28987b845989ca56297f07afed3ad58204ba309727530a3aa0106cc5a90b0d784cda390b0ca500575981951f1fa065e8e766a4ffec26f08 - languageName: node - linkType: hard - "abbrev@npm:1": version: 1.1.1 resolution: "abbrev@npm:1.1.1" @@ -9876,21 +8913,6 @@ __metadata: languageName: node linkType: hard -"abitype@npm:1.0.8, abitype@npm:^1.0.6": - version: 1.0.8 - resolution: "abitype@npm:1.0.8" - peerDependencies: - typescript: ">=5.0.4" - zod: ^3 >=3.22.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - checksum: 10c0/d3393f32898c1f0f6da4eed2561da6830dcd0d5129a160fae9517214236ee6a6c8e5a0380b8b960c5bc1b949320bcbd015ec7f38b5d7444f8f2b854a1b5dd754 - languageName: node - linkType: hard - "abort-controller@npm:^3.0.0": version: 3.0.0 resolution: "abort-controller@npm:3.0.0" @@ -10061,15 +9083,6 @@ __metadata: languageName: node linkType: hard -"ansi-align@npm:^2.0.0": - version: 2.0.0 - resolution: "ansi-align@npm:2.0.0" - dependencies: - string-width: "npm:^2.0.0" - checksum: 10c0/a3e3e5e58146ca7da775b919a480b8588ea76d0c91aa03c055535de25f327a09b72f7c10be2de6c84a6e1d8387b89bd9b4c98321b1759fdf4c2767c6f10ecd29 - languageName: node - linkType: hard - "ansi-align@npm:^3.0.0": version: 3.0.1 resolution: "ansi-align@npm:3.0.1" @@ -10086,13 +9099,6 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^1.1.0": - version: 1.4.0 - resolution: "ansi-escapes@npm:1.4.0" - checksum: 10c0/11ee31a0827d2c95129ea7c3df13d4d9d15b487517209d1d16027a876e6029e1c464ba626771af525a5aee12b26a740fc0378142b3193f3a62aaa2f03b7a5e9c - languageName: node - linkType: hard - "ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -10120,13 +9126,6 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^2.0.0": - version: 2.1.1 - resolution: "ansi-regex@npm:2.1.1" - checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b - languageName: node - linkType: hard - "ansi-regex@npm:^3.0.0": version: 3.0.1 resolution: "ansi-regex@npm:3.0.1" @@ -10148,13 +9147,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: 10c0/7c68aed4f1857389e7a12f85537ea5b40d832656babbf511cc7ecd9efc52889b9c3e5653a71a6aade783c3c5e0aa223ad4ff8e83c27ac8a666514e6c79068cab - languageName: node - linkType: hard - "ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -10196,23 +9188,6 @@ __metadata: languageName: node linkType: hard -"any-promise@npm:^1.0.0": - version: 1.3.0 - resolution: "any-promise@npm:1.3.0" - checksum: 10c0/60f0298ed34c74fef50daab88e8dab786036ed5a7fad02e012ab57e376e0a0b4b29e83b95ea9b5e7d89df762f5f25119b83e00706ecaccb22cfbacee98d74889 - languageName: node - linkType: hard - -"anymatch@npm:^2.0.0": - version: 2.0.0 - resolution: "anymatch@npm:2.0.0" - dependencies: - micromatch: "npm:^3.1.4" - normalize-path: "npm:^2.1.1" - checksum: 10c0/a0d745e52f0233048724b9c9d7b1d8a650f7a50151a0f1d2cce1857b09fd096052d334f8c570cc88596edef8249ae778f767db94025cd00f81e154a37bb7e34e - languageName: node - linkType: hard - "anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" @@ -10230,13 +9205,6 @@ __metadata: languageName: node linkType: hard -"append-field@npm:^1.0.0": - version: 1.0.0 - resolution: "append-field@npm:1.0.0" - checksum: 10c0/1b5abcc227e5179936a9e4f7e2af4769fa1f00eda85bbaed907f7964b0fd1f7d61f0f332b35337f391389ff13dd5310c2546ba670f8e5a743b23ec85185c73ef - languageName: node - linkType: hard - "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -10244,13 +9212,6 @@ __metadata: languageName: node linkType: hard -"arg@npm:^5.0.2": - version: 5.0.2 - resolution: "arg@npm:5.0.2" - checksum: 10c0/ccaf86f4e05d342af6666c569f844bec426595c567d32a8289715087825c2ca7edd8a3d204e4d2fb2aa4602e09a57d0c13ea8c9eea75aac3dbb4af5514e6800e - languageName: node - linkType: hard - "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -10276,34 +9237,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.3.2": - version: 5.3.2 - resolution: "aria-query@npm:5.3.2" - checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e - languageName: node - linkType: hard - -"arr-diff@npm:^4.0.0": - version: 4.0.0 - resolution: "arr-diff@npm:4.0.0" - checksum: 10c0/67b80067137f70c89953b95f5c6279ad379c3ee39f7143578e13bd51580a40066ee2a55da066e22d498dce10f68c2d70056d7823f972fab99dfbf4c78d0bc0f7 - languageName: node - linkType: hard - -"arr-flatten@npm:^1.1.0": - version: 1.1.0 - resolution: "arr-flatten@npm:1.1.0" - checksum: 10c0/bef53be02ed3bc58f202b3861a5b1eb6e1ae4fecf39c3ad4d15b1e0433f941077d16e019a33312d820844b0661777322acbb7d0c447b04d9bdf7d6f9c532548a - languageName: node - linkType: hard - -"arr-union@npm:^3.1.0": - version: 3.1.0 - resolution: "arr-union@npm:3.1.0" - checksum: 10c0/7d5aa05894e54aa93c77c5726c1dd5d8e8d3afe4f77983c0aa8a14a8a5cbe8b18f0cf4ecaa4ac8c908ef5f744d2cbbdaa83fd6e96724d15fea56cfa7f5efdd51 - languageName: node - linkType: hard - "array-back@npm:^3.0.1, array-back@npm:^3.1.0": version: 3.1.0 resolution: "array-back@npm:3.1.0" @@ -10356,13 +9289,6 @@ __metadata: languageName: node linkType: hard -"array-unique@npm:^0.3.2": - version: 0.3.2 - resolution: "array-unique@npm:0.3.2" - checksum: 10c0/dbf4462cdba8a4b85577be07705210b3d35be4b765822a3f52962d907186617638ce15e0603a4fefdcf82f4cbbc9d433f8cbbd6855148a68872fa041b6474121 - languageName: node - linkType: hard - "array.prototype.findlast@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.findlast@npm:1.2.5" @@ -10377,22 +9303,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.5": - version: 1.2.6 - resolution: "array.prototype.findlastindex@npm:1.2.6" - dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.4" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.9" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.1.1" - es-shim-unscopables: "npm:^1.1.0" - checksum: 10c0/82559310d2e57ec5f8fc53d7df420e3abf0ba497935de0a5570586035478ba7d07618cb18e2d4ada2da514c8fb98a034aaf5c06caa0a57e2f7f4c4adedef5956 - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": +"array.prototype.flat@npm:^1.3.1": version: 1.3.3 resolution: "array.prototype.flat@npm:1.3.3" dependencies: @@ -10404,7 +9315,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.2, array.prototype.flatmap@npm:^1.3.3": +"array.prototype.flatmap@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flatmap@npm:1.3.3" dependencies: @@ -10467,7 +9378,7 @@ __metadata: languageName: node linkType: hard -"asap@npm:^2.0.0, asap@npm:~2.0.6": +"asap@npm:~2.0.6": version: 2.0.6 resolution: "asap@npm:2.0.6" checksum: 10c0/c6d5e39fe1f15e4b87677460bd66b66050cd14c772269cee6688824c1410a08ab20254bb6784f9afb75af9144a9f9a7692d49547f4d19d715aeb7c0318f3136d @@ -10520,20 +9431,6 @@ __metadata: languageName: node linkType: hard -"assign-symbols@npm:^1.0.0": - version: 1.0.0 - resolution: "assign-symbols@npm:1.0.0" - checksum: 10c0/29a654b8a6da6889a190d0d0efef4b1bfb5948fa06cbc245054aef05139f889f2f7c75b989917e3fde853fc4093b88048e4de8578a73a76f113d41bfd66e5775 - languageName: node - linkType: hard - -"ast-types-flow@npm:^0.0.8": - version: 0.0.8 - resolution: "ast-types-flow@npm:0.0.8" - checksum: 10c0/f2a0ba8055353b743c41431974521e5e852a9824870cd6fce2db0e538ac7bf4da406bbd018d109af29ff3f8f0993f6a730c9eddbd0abd031fbcb29ca75c1014e - languageName: node - linkType: hard - "ast-types@npm:0.15.2": version: 0.15.2 resolution: "ast-types@npm:0.15.2" @@ -10566,13 +9463,6 @@ __metadata: languageName: node linkType: hard -"async-each@npm:^1.0.1": - version: 1.0.6 - resolution: "async-each@npm:1.0.6" - checksum: 10c0/d4e45e8f077e20e015952c065ceae75f82b30ee2d4a8e56a5c454ae44331aaa009d8c94fe043ba254c177bffae9f6ebeefebb7daf9f7ce4d27fac0274dc328ae - languageName: node - linkType: hard - "async-function@npm:^1.0.0": version: 1.0.0 resolution: "async-function@npm:1.0.0" @@ -10587,7 +9477,7 @@ __metadata: languageName: node linkType: hard -"async@npm:1.x, async@npm:^1.2.1, async@npm:^1.3.0, async@npm:^1.4.0": +"async@npm:1.x": version: 1.5.2 resolution: "async@npm:1.5.2" checksum: 10c0/9ee84592c393aad1047d1223004317ecc65a9a3f76101e0f4614a0818eac962e666510353400a3c9ea158df540579a293f486f3578e918c5e90a0f5ed52e8aea @@ -10633,14 +9523,7 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.10.0": - version: 4.10.3 - resolution: "axe-core@npm:4.10.3" - checksum: 10c0/1b1c24f435b2ffe89d76eca0001cbfff42dbf012ad9bd37398b70b11f0d614281a38a28bc3069e8972e3c90ec929a8937994bd24b0ebcbaab87b8d1e241ab0c7 - languageName: node - linkType: hard - -"axios@npm:^1.5.1, axios@npm:^1.6.2, axios@npm:^1.7.2, axios@npm:^1.7.7": +"axios@npm:^1.5.1, axios@npm:^1.6.2, axios@npm:^1.7.2": version: 1.9.0 resolution: "axios@npm:1.9.0" dependencies: @@ -10651,13 +9534,6 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:^4.1.0": - version: 4.1.0 - resolution: "axobject-query@npm:4.1.0" - checksum: 10c0/c470e4f95008f232eadd755b018cb55f16c03ccf39c027b941cd8820ac6b68707ce5d7368a46756db4256fbc91bb4ead368f84f7fb034b2b7932f082f6dc0775 - languageName: node - linkType: hard - "b4a@npm:^1.0.1, b4a@npm:^1.6.4": version: 1.6.7 resolution: "b4a@npm:1.6.7" @@ -10716,17 +9592,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-macros@npm:^3.1.0": - version: 3.1.0 - resolution: "babel-plugin-macros@npm:3.1.0" - dependencies: - "@babel/runtime": "npm:^7.12.5" - cosmiconfig: "npm:^7.0.0" - resolve: "npm:^1.19.0" - checksum: 10c0/c6dfb15de96f67871d95bd2e8c58b0c81edc08b9b087dc16755e7157f357dc1090a8dc60ebab955e92587a9101f02eba07e730adc253a1e4cf593ca3ebd3839c - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.10": version: 0.4.13 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.13" @@ -10818,28 +9683,6 @@ __metadata: languageName: node linkType: hard -"backend-api@workspace:sdk/tests/api-server": - version: 0.0.0-use.local - resolution: "backend-api@workspace:sdk/tests/api-server" - dependencies: - "@elysiajs/swagger": "npm:^1.2.0" - "@openpassport/zk-kit-imt": "npm:^0.0.5" - "@openpassport/zk-kit-lean-imt": "npm:^0.0.6" - "@selfxyz/core": "npm:^0.0.3" - "@types/pg": "npm:^8.11.11" - bun-types: "npm:latest" - dotenv: "npm:^16.4.7" - elysia: "npm:latest" - logixlysia: "npm:^4.1.1" - pg: "npm:^8.13.1" - poseidon-lite: "npm:^0.3.0" - snarkjs: "npm:^0.7.5" - swagger: "npm:^0.7.5" - typescript: "npm:^5.8.3" - viem: "npm:^2.22.23" - languageName: unknown - linkType: soft - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -10946,21 +9789,6 @@ __metadata: languageName: node linkType: hard -"base@npm:^0.11.1": - version: 0.11.2 - resolution: "base@npm:0.11.2" - dependencies: - cache-base: "npm:^1.0.1" - class-utils: "npm:^0.3.5" - component-emitter: "npm:^1.2.1" - define-property: "npm:^1.0.0" - isobject: "npm:^3.0.1" - mixin-deep: "npm:^1.2.0" - pascalcase: "npm:^0.1.1" - checksum: 10c0/30a2c0675eb52136b05ef496feb41574d9f0bb2d6d677761da579c00a841523fccf07f1dbabec2337b5f5750f428683b8ca60d89e56a1052c4ae1c0cd05de64d - languageName: node - linkType: hard - "basic-ftp@npm:^5.0.2": version: 5.0.5 resolution: "basic-ftp@npm:5.0.5" @@ -10995,13 +9823,6 @@ __metadata: languageName: node linkType: hard -"binary-extensions@npm:^1.0.0": - version: 1.13.1 - resolution: "binary-extensions@npm:1.13.1" - checksum: 10c0/2d616938ac23d828ec3fbe0dea429b566fd2c137ddc38f166f16561ccd58029deac3fa9fddb489ab13d679c8fb5f1bd0e82824041299e5e39d8dd3cc68fbb9f9 - languageName: node - linkType: hard - "binary-extensions@npm:^2.0.0": version: 2.3.0 resolution: "binary-extensions@npm:2.3.0" @@ -11009,15 +9830,6 @@ __metadata: languageName: node linkType: hard -"bindings@npm:^1.5.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: "npm:1.0.0" - checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba - languageName: node - linkType: hard - "bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -11096,23 +9908,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.12.4": - version: 1.12.4 - resolution: "body-parser@npm:1.12.4" - dependencies: - bytes: "npm:1.0.0" - content-type: "npm:~1.0.1" - debug: "npm:~2.2.0" - depd: "npm:~1.0.1" - iconv-lite: "npm:0.4.8" - on-finished: "npm:~2.2.1" - qs: "npm:2.4.2" - raw-body: "npm:~2.0.1" - type-is: "npm:~1.6.2" - checksum: 10c0/5562e8d42531f1c0e49695541df4639a02b331a006ab9b4921035deb37606885ce56413f920e46a8d0beac74b659c041ce6588451fad5e9cbb91bbad60787f3f - languageName: node - linkType: hard - "boolbase@npm:^1.0.0": version: 1.0.0 resolution: "boolbase@npm:1.0.0" @@ -11120,21 +9915,6 @@ __metadata: languageName: node linkType: hard -"boxen@npm:^1.2.1": - version: 1.3.0 - resolution: "boxen@npm:1.3.0" - dependencies: - ansi-align: "npm:^2.0.0" - camelcase: "npm:^4.0.0" - chalk: "npm:^2.0.1" - cli-boxes: "npm:^1.0.0" - string-width: "npm:^2.0.0" - term-size: "npm:^1.2.0" - widest-line: "npm:^2.0.0" - checksum: 10c0/9df2e59dd6622cee184aaffc017b3b3d506f1f70cddb0a7c19d22c865db4222faa9940512a7a6e2065f48500f9310a04d27af2037b1afeb2143e79430c9af476 - languageName: node - linkType: hard - "boxen@npm:^5.1.2": version: 5.1.2 resolution: "boxen@npm:5.1.2" @@ -11170,24 +9950,6 @@ __metadata: languageName: node linkType: hard -"braces@npm:^2.3.1, braces@npm:^2.3.2": - version: 2.3.2 - resolution: "braces@npm:2.3.2" - dependencies: - arr-flatten: "npm:^1.1.0" - array-unique: "npm:^0.3.2" - extend-shallow: "npm:^2.0.1" - fill-range: "npm:^4.0.0" - isobject: "npm:^3.0.1" - repeat-element: "npm:^1.1.2" - snapdragon: "npm:^0.8.1" - snapdragon-node: "npm:^2.0.1" - split-string: "npm:^3.0.2" - to-regex: "npm:^3.0.1" - checksum: 10c0/72b27ea3ea2718f061c29e70fd6e17606e37c65f5801abddcf0b0052db1de7d60f3bf92cfc220ab57b44bd0083a5f69f9d03b3461d2816cfe9f9398207acc728 - languageName: node - linkType: hard - "braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -11318,34 +10080,6 @@ __metadata: languageName: node linkType: hard -"bun-types@npm:latest": - version: 1.2.14 - resolution: "bun-types@npm:1.2.14" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/d840798950293eb7023f8d715304eef388bbe7947e06df78afd25ed399d708e36f1164c8d32ed840f3d1f9f235bd72334503806bacf36a6be4c0e2da68f3c2ec - languageName: node - linkType: hard - -"busboy@npm:1.6.0": - version: 1.6.0 - resolution: "busboy@npm:1.6.0" - dependencies: - streamsearch: "npm:^1.1.0" - checksum: 10c0/fa7e836a2b82699b6e074393428b91ae579d4f9e21f5ac468e1b459a244341d722d2d22d10920cdd849743dbece6dca11d72de939fb75a7448825cf2babfba1f - languageName: node - linkType: hard - -"busboy@npm:^0.2.11": - version: 0.2.14 - resolution: "busboy@npm:0.2.14" - dependencies: - dicer: "npm:0.2.5" - readable-stream: "npm:1.1.x" - checksum: 10c0/660ce531347a03210f46080c2447030c41f60202be0d8dd1544482786341a497b1d4d8941e3c7c9b5e6ed4edc42003c28c9451e1fde87dd94010df69bb27cc38 - languageName: node - linkType: hard - "bytes-iec@npm:^3.1.1": version: 3.1.1 resolution: "bytes-iec@npm:3.1.1" @@ -11353,20 +10087,6 @@ __metadata: languageName: node linkType: hard -"bytes@npm:1.0.0": - version: 1.0.0 - resolution: "bytes@npm:1.0.0" - checksum: 10c0/46f38408f9bf41c7c82b4e8118ab22f3f83fcebeecc4b93a71867608a3f6f25ab446d72438054daf0059234f2522e3711a241a06a0836f9b5e3e025d2da8d9af - languageName: node - linkType: hard - -"bytes@npm:2.1.0": - version: 2.1.0 - resolution: "bytes@npm:2.1.0" - checksum: 10c0/09a120e49870543597d4e7b0dd32acdad4747a141719850c541d3d93c68193d31fe3f3d54bc1990edd3bf49fa9f95965cef0a13a36db97975ebb44c58b5db1f5 - languageName: node - linkType: hard - "bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" @@ -11401,23 +10121,6 @@ __metadata: languageName: node linkType: hard -"cache-base@npm:^1.0.1": - version: 1.0.1 - resolution: "cache-base@npm:1.0.1" - dependencies: - collection-visit: "npm:^1.0.0" - component-emitter: "npm:^1.2.1" - get-value: "npm:^2.0.6" - has-value: "npm:^1.0.0" - isobject: "npm:^3.0.1" - set-value: "npm:^2.0.0" - to-object-path: "npm:^0.3.0" - union-value: "npm:^1.0.0" - unset-value: "npm:^1.0.0" - checksum: 10c0/a7142e25c73f767fa520957dcd179b900b86eac63b8cfeaa3b2a35e18c9ca5968aa4e2d2bed7a3e7efd10f13be404344cfab3a4156217e71f9bdb95940bb9c8c - languageName: node - linkType: hard - "cacheable-lookup@npm:^5.0.3": version: 5.0.4 resolution: "cacheable-lookup@npm:5.0.4" @@ -11504,20 +10207,6 @@ __metadata: languageName: node linkType: hard -"camelcase-css@npm:^2.0.1": - version: 2.0.1 - resolution: "camelcase-css@npm:2.0.1" - checksum: 10c0/1a1a3137e8a781e6cbeaeab75634c60ffd8e27850de410c162cce222ea331cd1ba5364e8fb21c95e5ca76f52ac34b81a090925ca00a87221355746d049c6e273 - languageName: node - linkType: hard - -"camelcase@npm:^4.0.0": - version: 4.1.0 - resolution: "camelcase@npm:4.1.0" - checksum: 10c0/54c0b6a85b54fb4e96a9d834a9d0d8f760fd608ab6752a6789042b5e1c38d3dd60f878d2c590d005046445d32d77f6e05e568a91fe8db3e282da0a1560d83058 - languageName: node - linkType: hard - "camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" @@ -11532,20 +10221,13 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001716": +"caniuse-lite@npm:^1.0.30001716": version: 1.0.30001718 resolution: "caniuse-lite@npm:1.0.30001718" checksum: 10c0/67f9ad09bc16443e28d14f265d6e468480cd8dc1900d0d8b982222de80c699c4f2306599c3da8a3fa7139f110d4b30d49dbac78f215470f479abb6ffe141d5d3 languageName: node linkType: hard -"capture-stack-trace@npm:^1.0.0": - version: 1.0.2 - resolution: "capture-stack-trace@npm:1.0.2" - checksum: 10c0/9f910506dcbe82dbfadf81a9e8c7cff478dd64ea2de319d01762de32940cdb082217686215a8ed389a540e683779fe56ac4b9a2957d1bfdd8c730d08e5f12ca5 - languageName: node - linkType: hard - "caseless@npm:^0.12.0, caseless@npm:~0.12.0": version: 0.12.0 resolution: "caseless@npm:0.12.0" @@ -11625,20 +10307,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.0.0": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: "npm:^2.2.1" - escape-string-regexp: "npm:^1.0.2" - has-ansi: "npm:^2.0.0" - strip-ansi: "npm:^3.0.0" - supports-color: "npm:^2.0.0" - checksum: 10c0/28c3e399ec286bb3a7111fd4225ebedb0d7b813aef38a37bca7c498d032459c265ef43404201d5fbb8d888d29090899c95335b4c0cda13e8b126ff15c541cef8 - languageName: node - linkType: hard - -"chalk@npm:^2.0.1, chalk@npm:^2.4.2": +"chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -11669,13 +10338,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.3.0": - version: 5.4.1 - resolution: "chalk@npm:5.4.1" - checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef - languageName: node - linkType: hard - "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -11683,7 +10345,7 @@ __metadata: languageName: node linkType: hard -"charenc@npm:>= 0.0.1, charenc@npm:~0.0.1": +"charenc@npm:>= 0.0.1": version: 0.0.2 resolution: "charenc@npm:0.0.2" checksum: 10c0/a45ec39363a16799d0f9365c8dd0c78e711415113c6f14787a22462ef451f5013efae8a28f1c058f81fc01f2a6a16955f7a5fd0cd56247ce94a45349c89877d8 @@ -11713,30 +10375,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^2.1.8": - version: 2.1.8 - resolution: "chokidar@npm:2.1.8" - dependencies: - anymatch: "npm:^2.0.0" - async-each: "npm:^1.0.1" - braces: "npm:^2.3.2" - fsevents: "npm:^1.2.7" - glob-parent: "npm:^3.1.0" - inherits: "npm:^2.0.3" - is-binary-path: "npm:^1.0.0" - is-glob: "npm:^4.0.0" - normalize-path: "npm:^3.0.0" - path-is-absolute: "npm:^1.0.0" - readdirp: "npm:^2.2.1" - upath: "npm:^1.1.1" - dependenciesMeta: - fsevents: - optional: true - checksum: 10c0/5631cc00080224f9482cf5418dcbea111aec02fa8d81a8cfe37e47b9cf36089e071de52d503647e3a821a01426a40adc926ba899f657af86a51b8f8d4eef12a7 - languageName: node - linkType: hard - -"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": +"chokidar@npm:^3.5.3": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -11826,13 +10465,6 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^1.5.0": - version: 1.6.0 - resolution: "ci-info@npm:1.6.0" - checksum: 10c0/5a74921e50e0be504ef811f00cb8dd6a547e1f4f2e709b7364b2de72a6fbc0215d86c88cd62c485a129090365d2a6367ca00344ced04e714860b22fbe10180c8 - languageName: node - linkType: hard - "ci-info@npm:^2.0.0": version: 2.0.0 resolution: "ci-info@npm:2.0.0" @@ -11978,18 +10610,6 @@ __metadata: languageName: node linkType: hard -"class-utils@npm:^0.3.5": - version: 0.3.6 - resolution: "class-utils@npm:0.3.6" - dependencies: - arr-union: "npm:^3.1.0" - define-property: "npm:^0.2.5" - isobject: "npm:^3.0.0" - static-extend: "npm:^0.1.1" - checksum: 10c0/d44f4afc7a3e48dba4c2d3fada5f781a1adeeff371b875c3b578bc33815c6c29d5d06483c2abfd43a32d35b104b27b67bfa39c2e8a422fa858068bd756cfbd42 - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -11997,13 +10617,6 @@ __metadata: languageName: node linkType: hard -"cli-boxes@npm:^1.0.0": - version: 1.0.0 - resolution: "cli-boxes@npm:1.0.0" - checksum: 10c0/1f79cd17e39cc00710d85c2a2d33ead781d1215b72546b31cfb4da5b2edc1f12ef8f99af67afb8a79fa1f92ad6b54505cc245afb16eee5fa01772f87353ba6e4 - languageName: node - linkType: hard - "cli-boxes@npm:^2.2.1": version: 2.2.1 resolution: "cli-boxes@npm:2.2.1" @@ -12011,15 +10624,6 @@ __metadata: languageName: node linkType: hard -"cli-cursor@npm:^1.0.1": - version: 1.0.2 - resolution: "cli-cursor@npm:1.0.2" - dependencies: - restore-cursor: "npm:^1.0.1" - checksum: 10c0/a621ddfae6dde44c699c520ef416745d096b7d58255f3a2a2727b19db4a308085f33ca86e19f1bf3e4dc4d500c347c5c9ed62c4cfe1a23c2fd4b0419e1ff4e8b - languageName: node - linkType: hard - "cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -12063,20 +10667,6 @@ __metadata: languageName: node linkType: hard -"cli-width@npm:^1.0.1": - version: 1.1.1 - resolution: "cli-width@npm:1.1.1" - checksum: 10c0/257dd5c16b1c79ca571515dc5ff7872cbb8f0a7c98c4d2cc9a9498b2b1e9aec3794c2aa881ccf3dcc8fc0a5f2b4e4309d1a17758db36476ef13b4e5adb344fa8 - languageName: node - linkType: hard - -"client-only@npm:0.0.1": - version: 0.0.1 - resolution: "client-only@npm:0.0.1" - checksum: 10c0/9d6cfd0c19e1c96a434605added99dff48482152af791ec4172fb912a71cff9027ff174efd8cdb2160cc7f377543e0537ffc462d4f279bc4701de3f2a3c4b358 - languageName: node - linkType: hard - "clipanion@npm:^4.0.0-rc.2": version: 4.0.0-rc.4 resolution: "clipanion@npm:4.0.0-rc.4" @@ -12160,20 +10750,6 @@ __metadata: languageName: node linkType: hard -"clone@npm:^2.1.2": - version: 2.1.2 - resolution: "clone@npm:2.1.2" - checksum: 10c0/ed0601cd0b1606bc7d82ee7175b97e68d1dd9b91fd1250a3617b38d34a095f8ee0431d40a1a611122dcccb4f93295b4fdb94942aa763392b5fe44effa50c2d5e - languageName: node - linkType: hard - -"clsx@npm:^2.1.1": - version: 2.1.1 - resolution: "clsx@npm:2.1.1" - checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 - languageName: node - linkType: hard - "co@npm:^4.6.0": version: 4.6.0 resolution: "co@npm:4.6.0" @@ -12181,13 +10757,6 @@ __metadata: languageName: node linkType: hard -"code-point-at@npm:^1.0.0": - version: 1.1.0 - resolution: "code-point-at@npm:1.1.0" - checksum: 10c0/33f6b234084e46e6e369b6f0b07949392651b4dde70fc6a592a8d3dafa08d5bb32e3981a02f31f6fc323a26bc03a4c063a9d56834848695bda7611c2417ea2e6 - languageName: node - linkType: hard - "collect-v8-coverage@npm:^1.0.0": version: 1.0.2 resolution: "collect-v8-coverage@npm:1.0.2" @@ -12195,16 +10764,6 @@ __metadata: languageName: node linkType: hard -"collection-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "collection-visit@npm:1.0.0" - dependencies: - map-visit: "npm:^1.0.0" - object-visit: "npm:^1.0.0" - checksum: 10c0/add72a8d1c37cb90e53b1aaa2c31bf1989bfb733f0b02ce82c9fa6828c7a14358dba2e4f8e698c02f69e424aeccae1ffb39acdeaf872ade2f41369e84a2fcf8a - languageName: node - linkType: hard - "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -12278,7 +10837,7 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.5, combined-stream@npm:^1.0.8": +"combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -12318,20 +10877,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:0.6.1": - version: 0.6.1 - resolution: "commander@npm:0.6.1" - checksum: 10c0/01dd500bbc8df9d523eaa01c022ec47055c1a308e5c275d3bed986366bd3acaf59a1750319877f15c3cf1a982240098d9469c003dad425a3a20d5db6054a378a - languageName: node - linkType: hard - -"commander@npm:2.3.0": - version: 2.3.0 - resolution: "commander@npm:2.3.0" - checksum: 10c0/cb41bc7f92b4af7c35c7084637e5a0e71d8774eac1088d2371e4be30dc310f8619d26389e71681af9fb3f8e0d291bf0723aba30eb84ebb6391963b8263c57c18 - languageName: node - linkType: hard - "commander@npm:^11.0.0": version: 11.1.0 resolution: "commander@npm:11.1.0" @@ -12346,20 +10891,13 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.20.0, commander@npm:^2.7.1, commander@npm:^2.8.1, commander@npm:^2.9.0": +"commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: 10c0/74c781a5248c2402a0a3e966a0a2bba3c054aad144f5c023364be83265e796b20565aa9feff624132ff629aa64e16999fa40a743c10c12f7c61e96a794b99288 languageName: node linkType: hard -"commander@npm:^4.0.0": - version: 4.1.1 - resolution: "commander@npm:4.1.1" - checksum: 10c0/84a76c08fe6cc08c9c93f62ac573d2907d8e79138999312c92d4155bc2325d487d64d13f669b2000c9f8caf70493c1be2dac74fec3c51d5a04f8bc3ae1830bab - languageName: node - linkType: hard - "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -12400,20 +10938,6 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.2.1, component-emitter@npm:^1.3.0": - version: 1.3.1 - resolution: "component-emitter@npm:1.3.1" - checksum: 10c0/e4900b1b790b5e76b8d71b328da41482118c0f3523a516a41be598dc2785a07fd721098d9bf6e22d89b19f4fa4e1025160dc00317ea111633a3e4f75c2b86032 - languageName: node - linkType: hard - -"component-emitter@npm:~1.2.0": - version: 1.2.1 - resolution: "component-emitter@npm:1.2.1" - checksum: 10c0/6c27bd7bba028776464cee6c1686c8e02cb9a576a11df93f1fc211ae3eb2de234ae90952d0b7fb3acc9c92c8baa389fa7389681b2e8689d2ca463e94f3ad30b2 - languageName: node - linkType: hard - "compressible@npm:~2.0.18": version: 2.0.18 resolution: "compressible@npm:2.0.18" @@ -12445,7 +10969,7 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.5.2, concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.2": +"concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.2": version: 1.6.2 resolution: "concat-stream@npm:1.6.2" dependencies: @@ -12457,21 +10981,7 @@ __metadata: languageName: node linkType: hard -"configstore@npm:^3.0.0": - version: 3.1.5 - resolution: "configstore@npm:3.1.5" - dependencies: - dot-prop: "npm:^4.2.1" - graceful-fs: "npm:^4.1.2" - make-dir: "npm:^1.0.0" - unique-string: "npm:^1.0.0" - write-file-atomic: "npm:^2.0.0" - xdg-basedir: "npm:^3.0.0" - checksum: 10c0/a68edffee893b1803a108c4083dee481967f7eec232f83499bc86973d93d1e2728c1ea98cb1a4c7c583bc172abbdf197888ba0b0c12640631792186aa233918b - languageName: node - linkType: hard - -"connect@npm:^3.3.5, connect@npm:^3.6.5": +"connect@npm:^3.6.5": version: 3.7.0 resolution: "connect@npm:3.7.0" dependencies: @@ -12483,14 +10993,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.1": - version: 1.0.5 - resolution: "content-type@npm:1.0.5" - checksum: 10c0/b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af - languageName: node - linkType: hard - -"convert-source-map@npm:^1.5.0, convert-source-map@npm:^1.7.0": +"convert-source-map@npm:^1.7.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b @@ -12511,54 +11014,19 @@ __metadata: languageName: node linkType: hard -"cookie@npm:^1.0.2": - version: 1.0.2 - resolution: "cookie@npm:1.0.2" - checksum: 10c0/fd25fe79e8fbcfcaf6aa61cd081c55d144eeeba755206c058682257cb38c4bd6795c6620de3f064c740695bb65b7949ebb1db7a95e4636efb8357a335ad3f54b +"core-js-compat@npm:^3.40.0": + version: 3.42.0 + resolution: "core-js-compat@npm:3.42.0" + dependencies: + browserslist: "npm:^4.24.4" + checksum: 10c0/0138ce005c13ce642fc38e18e54a52a1c78ca8315ee6e4faad748d2a1b0ad2462ea615285ad4e6cf77afe48e47a868d898e64c70606c1eb1c9e6a9f19ee2b186 languageName: node linkType: hard -"cookiejar@npm:2.0.6": - version: 2.0.6 - resolution: "cookiejar@npm:2.0.6" - checksum: 10c0/e62e345b74f29c396720e0592c9f6b7de6b29250867cf5abf6a7e798e4ea2efcb811210439ab6243b5dc2cde9d992133214039b08f7e474142eef441b102a58d - languageName: node - linkType: hard - -"cookiejar@npm:^2.1.3": - version: 2.1.4 - resolution: "cookiejar@npm:2.1.4" - checksum: 10c0/2dae55611c6e1678f34d93984cbd4bda58f4fe3e5247cc4993f4a305cd19c913bbaf325086ed952e892108115073a747596453d3dc1c34947f47f731818b8ad1 - languageName: node - linkType: hard - -"copy-descriptor@npm:^0.1.0": - version: 0.1.1 - resolution: "copy-descriptor@npm:0.1.1" - checksum: 10c0/161f6760b7348c941007a83df180588fe2f1283e0867cc027182734e0f26134e6cc02de09aa24a95dc267b2e2025b55659eef76c8019df27bc2d883033690181 - languageName: node - linkType: hard - -"core-js-compat@npm:^3.40.0": - version: 3.42.0 - resolution: "core-js-compat@npm:3.42.0" - dependencies: - browserslist: "npm:^4.24.4" - checksum: 10c0/0138ce005c13ce642fc38e18e54a52a1c78ca8315ee6e4faad748d2a1b0ad2462ea615285ad4e6cf77afe48e47a868d898e64c70606c1eb1c9e6a9f19ee2b186 - languageName: node - linkType: hard - -"core-js@npm:^2.5.7": - version: 2.6.12 - resolution: "core-js@npm:2.6.12" - checksum: 10c0/00128efe427789120a06b819adc94cc72b96955acb331cb71d09287baf9bd37bebd191d91f1ee4939c893a050307ead4faea08876f09115112612b6a05684b63 - languageName: node - linkType: hard - -"core-util-is@npm:^1.0.2, core-util-is@npm:~1.0.0": - version: 1.0.3 - resolution: "core-util-is@npm:1.0.3" - checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 +"core-util-is@npm:^1.0.2, core-util-is@npm:~1.0.0": + version: 1.0.3 + resolution: "core-util-is@npm:1.0.3" + checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 languageName: node linkType: hard @@ -12574,19 +11042,6 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7.0.0": - version: 7.1.0 - resolution: "cosmiconfig@npm:7.1.0" - dependencies: - "@types/parse-json": "npm:^4.0.0" - import-fresh: "npm:^3.2.1" - parse-json: "npm:^5.0.0" - path-type: "npm:^4.0.0" - yaml: "npm:^1.10.0" - checksum: 10c0/b923ff6af581638128e5f074a5450ba12c0300b71302398ea38dbeabd33bbcaa0245ca9adbedfcf284a07da50f99ede5658c80bb3e39e2ce770a99d28a21ef03 - languageName: node - linkType: hard - "cosmiconfig@npm:^8.1.3": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" @@ -12635,15 +11090,6 @@ __metadata: languageName: node linkType: hard -"create-error-class@npm:^3.0.0": - version: 3.0.2 - resolution: "create-error-class@npm:3.0.2" - dependencies: - capture-stack-trace: "npm:^1.0.0" - checksum: 10c0/e7978884999f7195b20a56c327acf1d742b45c721098691863bd2a933180aa411d5dbe790d3565f3eca6105b829a647497d52e3e00edf1d5c19c1d116def69b6 - languageName: node - linkType: hard - "create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": version: 1.2.0 resolution: "create-hash@npm:1.2.0" @@ -12695,17 +11141,6 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^5.0.1": - version: 5.1.0 - resolution: "cross-spawn@npm:5.1.0" - dependencies: - lru-cache: "npm:^4.0.1" - shebang-command: "npm:^1.2.0" - which: "npm:^1.2.9" - checksum: 10c0/1918621fddb9f8c61e02118b2dbf81f611ccd1544ceaca0d026525341832b8511ce2504c60f935dbc06b35e5ef156fe8c1e72708c27dd486f034e9c0e1e07201 - languageName: node - linkType: hard - "cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" @@ -12717,20 +11152,13 @@ __metadata: languageName: node linkType: hard -"crypt@npm:>= 0.0.1, crypt@npm:~0.0.1": +"crypt@npm:>= 0.0.1": version: 0.0.2 resolution: "crypt@npm:0.0.2" checksum: 10c0/adbf263441dd801665d5425f044647533f39f4612544071b1471962209d235042fb703c27eea2795c7c53e1dfc242405173003f83cf4f4761a633d11f9653f18 languageName: node linkType: hard -"crypto-random-string@npm:^1.0.0": - version: 1.0.0 - resolution: "crypto-random-string@npm:1.0.0" - checksum: 10c0/0cb4dbbb895656919d1de11ba43829a3527edddb85a9c49c9d4c4eb783d3b03fc9f371cefee62c87082fd8758db2798a52a9cad48a7381826190d3c2cf858e4a - languageName: node - linkType: hard - "crypto@npm:^1.0.1": version: 1.0.1 resolution: "crypto@npm:1.0.1" @@ -12788,15 +11216,6 @@ __metadata: languageName: node linkType: hard -"cssesc@npm:^3.0.0": - version: 3.0.0 - resolution: "cssesc@npm:3.0.0" - bin: - cssesc: bin/cssesc - checksum: 10c0/6bcfd898662671be15ae7827120472c5667afb3d7429f1f917737f3bf84c4176003228131b643ae74543f17a394446247df090c597bb9a728cce298606ed0aa7 - languageName: node - linkType: hard - "csso@npm:^5.0.5": version: 5.0.5 resolution: "csso@npm:5.0.5" @@ -12806,27 +11225,13 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.3": +"csstype@npm:^3.0.2": version: 3.1.3 resolution: "csstype@npm:3.1.3" checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248 languageName: node linkType: hard -"dag-map@npm:~1.0.0": - version: 1.0.2 - resolution: "dag-map@npm:1.0.2" - checksum: 10c0/1b5ee77cbc9caf61178db592ecc8fa8f6905fd4b0571176af74d2fece2332b68c0e9e8275f1c2c76bc1f0c84a9dc973f87233db7a06375bd13254fae9866867f - languageName: node - linkType: hard - -"damerau-levenshtein@npm:^1.0.8": - version: 1.0.8 - resolution: "damerau-levenshtein@npm:1.0.8" - checksum: 10c0/4c2647e0f42acaee7d068756c1d396e296c3556f9c8314bac1ac63ffb236217ef0e7e58602b18bb2173deec7ec8e0cac8e27cccf8f5526666b4ff11a13ad54a3 - languageName: node - linkType: hard - "data-uri-to-buffer@npm:^6.0.2": version: 6.0.2 resolution: "data-uri-to-buffer@npm:6.0.2" @@ -12888,7 +11293,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2, debug@npm:2.6.9, debug@npm:^2.1.3, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.9": +"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -12897,15 +11302,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.2.0, debug@npm:~2.2.0": - version: 2.2.0 - resolution: "debug@npm:2.2.0" - dependencies: - ms: "npm:0.7.1" - checksum: 10c0/d24d6200c9d9bef20e1dcb823a9895193a45c39505606468735f387bdd850a21baf4c7841df1787f9a02596cbf0f111d60726ba3fa7511e22198b91b33440fe9 - languageName: node - linkType: hard - "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0, debug@npm:^4.4.1": version: 4.4.1 resolution: "debug@npm:4.4.1" @@ -12930,15 +11326,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.2.6, debug@npm:^3.2.7": - version: 3.2.7 - resolution: "debug@npm:3.2.7" - dependencies: - ms: "npm:^2.1.1" - checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a - languageName: node - linkType: hard - "debug@npm:~4.3.1, debug@npm:~4.3.2": version: 4.3.7 resolution: "debug@npm:4.3.7" @@ -12965,7 +11352,7 @@ __metadata: languageName: node linkType: hard -"decode-uri-component@npm:^0.2.0, decode-uri-component@npm:^0.2.2": +"decode-uri-component@npm:^0.2.2": version: 0.2.2 resolution: "decode-uri-component@npm:0.2.2" checksum: 10c0/1f4fa54eb740414a816b3f6c24818fbfcabd74ac478391e9f4e2282c994127db02010ce804f3d08e38255493cfe68608b3f5c8e09fd6efc4ae46c807691f7a31 @@ -13009,7 +11396,7 @@ __metadata: languageName: node linkType: hard -"deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": +"deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 @@ -13075,34 +11462,6 @@ __metadata: languageName: node linkType: hard -"define-property@npm:^0.2.5": - version: 0.2.5 - resolution: "define-property@npm:0.2.5" - dependencies: - is-descriptor: "npm:^0.1.0" - checksum: 10c0/9986915c0893818dedc9ca23eaf41370667762fd83ad8aa4bf026a28563120dbaacebdfbfbf2b18d3b929026b9c6ee972df1dbf22de8fafb5fe6ef18361e4750 - languageName: node - linkType: hard - -"define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "define-property@npm:1.0.0" - dependencies: - is-descriptor: "npm:^1.0.0" - checksum: 10c0/d7cf09db10d55df305f541694ed51dafc776ad9bb8a24428899c9f2d36b11ab38dce5527a81458d1b5e7c389f8cbe803b4abad6e91a0037a329d153b84fc975e - languageName: node - linkType: hard - -"define-property@npm:^2.0.2": - version: 2.0.2 - resolution: "define-property@npm:2.0.2" - dependencies: - is-descriptor: "npm:^1.0.2" - isobject: "npm:^3.0.1" - checksum: 10c0/f91a08ad008fa764172a2c072adc7312f10217ade89ddaea23018321c6d71b2b68b8c229141ed2064179404e345c537f1a2457c379824813695b51a6ad3e4969 - languageName: node - linkType: hard - "degenerator@npm:^5.0.0": version: 5.0.1 resolution: "degenerator@npm:5.0.1" @@ -13135,13 +11494,6 @@ __metadata: languageName: node linkType: hard -"depd@npm:~1.0.1": - version: 1.0.1 - resolution: "depd@npm:1.0.1" - checksum: 10c0/c8453ebf9cf819e6847693278d34d21dc42a16c5f30099673339e809212d291d884837572478008a910b877eb69058be19f1aeb06c4c73ad574963fc98abd078 - languageName: node - linkType: hard - "destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" @@ -13170,16 +11522,6 @@ __metadata: languageName: node linkType: hard -"dezalgo@npm:^1.0.4": - version: 1.0.4 - resolution: "dezalgo@npm:1.0.4" - dependencies: - asap: "npm:^2.0.0" - wrappy: "npm:1" - checksum: 10c0/8a870ed42eade9a397e6141fe5c025148a59ed52f1f28b1db5de216b4d57f0af7a257070c3af7ce3d5508c1ce9dd5009028a76f4b2cc9370dc56551d2355fad8 - languageName: node - linkType: hard - "diacritics@npm:1.3.0": version: 1.3.0 resolution: "diacritics@npm:1.3.0" @@ -13187,23 +11529,6 @@ __metadata: languageName: node linkType: hard -"dicer@npm:0.2.5": - version: 0.2.5 - resolution: "dicer@npm:0.2.5" - dependencies: - readable-stream: "npm:1.1.x" - streamsearch: "npm:0.1.2" - checksum: 10c0/c0520cee8c4d8c7e2db4f8fe30c0fdbf96d9623d53a65b54f4e0d9a89b76c3e0c397de54a1530c1d4b1788d1e87ff3ca5800e3ba93c748e0cd24827b505fb5e7 - languageName: node - linkType: hard - -"didyoumean@npm:^1.2.2": - version: 1.2.2 - resolution: "didyoumean@npm:1.2.2" - checksum: 10c0/95d0b53d23b851aacff56dfadb7ecfedce49da4232233baecfeecb7710248c4aa03f0aa8995062f0acafaf925adf8536bd7044a2e68316fd7d411477599bc27b - languageName: node - linkType: hard - "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -13211,13 +11536,6 @@ __metadata: languageName: node linkType: hard -"diff@npm:1.4.0": - version: 1.4.0 - resolution: "diff@npm:1.4.0" - checksum: 10c0/516ce8f6a85e2025ea039cd7ce5491b0f8cda1a9d8a9c7998aa4a8a49ba94d24ff1c7e91e5b23e04ae78e1f788a19c03b24709bb619fa15d9627d657b5aa86f3 - languageName: node - linkType: hard - "diff@npm:^3.1.0": version: 3.5.0 resolution: "diff@npm:3.5.0" @@ -13282,16 +11600,6 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^5.0.1": - version: 5.2.1 - resolution: "dom-helpers@npm:5.2.1" - dependencies: - "@babel/runtime": "npm:^7.8.7" - csstype: "npm:^3.0.2" - checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c - languageName: node - linkType: hard - "dom-serializer@npm:^2.0.0": version: 2.0.0 resolution: "dom-serializer@npm:2.0.0" @@ -13340,15 +11648,6 @@ __metadata: languageName: node linkType: hard -"dot-prop@npm:^4.2.1": - version: 4.2.1 - resolution: "dot-prop@npm:4.2.1" - dependencies: - is-obj: "npm:^1.0.0" - checksum: 10c0/ea0a98871ef4de0cce05325979517a43b70eb3a3671254fce78f2629c125d5ddb69cfdd5570ace4e41d9f02ced06374ea0444d1aeae70290a19f73e02093318e - languageName: node - linkType: hard - "dotenv-cli@npm:^7.4.2": version: 7.4.4 resolution: "dotenv-cli@npm:7.4.4" @@ -13395,13 +11694,6 @@ __metadata: languageName: node linkType: hard -"duplexer3@npm:^0.1.4": - version: 0.1.5 - resolution: "duplexer3@npm:0.1.5" - checksum: 10c0/02195030d61c4d6a2a34eca71639f2ea5e05cb963490e5bd9527623c2ac7f50c33842a34d14777ea9cbfd9bc2be5a84065560b897d9fabb99346058a5b86ca98 - languageName: node - linkType: hard - "duplexer@npm:^0.1.2": version: 0.1.2 resolution: "duplexer@npm:0.1.2" @@ -13416,13 +11708,6 @@ __metadata: languageName: node linkType: hard -"ee-first@npm:1.1.0": - version: 1.1.0 - resolution: "ee-first@npm:1.1.0" - checksum: 10c0/a2c35602b8ea8bc65a56c2fecad8dfc0a1e6cfe242cda0b35bc21c8b99dfb2d0b29d72183f7133c92b43526603b022f52dcb1c971c54022fa7d8152e5e73cbc6 - languageName: node - linkType: hard - "ee-first@npm:1.1.1": version: 1.1.1 resolution: "ee-first@npm:1.1.1" @@ -13463,30 +11748,6 @@ __metadata: languageName: node linkType: hard -"elysia@npm:^1.1.23, elysia@npm:latest": - version: 1.3.3 - resolution: "elysia@npm:1.3.3" - dependencies: - "@sinclair/typebox": "npm:^0.34.33" - cookie: "npm:^1.0.2" - exact-mirror: "npm:0.1.2" - fast-decode-uri-component: "npm:^1.0.1" - openapi-types: "npm:^12.1.3" - peerDependencies: - "@sinclair/typebox": ">= 0.34.0" - exact-mirror: ">= 0.0.9" - file-type: ">= 20.0.0" - openapi-types: ">= 12.0.0" - typescript: ">= 5.0.0" - dependenciesMeta: - "@sinclair/typebox": - optional: true - openapi-types: - optional: true - checksum: 10c0/61a339f6655acea2664e83fc11d860dac8b1b73161d723bce07d0e0599136e1bddd6e2a627846d5cade7408c090dbae98a4c34fdabe60618449887ccce720d54 - languageName: node - linkType: hard - "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -13777,7 +12038,7 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": +"es-shim-unscopables@npm:^1.0.2": version: 1.1.0 resolution: "es-shim-unscopables@npm:1.1.0" dependencies: @@ -13914,14 +12175,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:1.0.2": - version: 1.0.2 - resolution: "escape-string-regexp@npm:1.0.2" - checksum: 10c0/df696f5330ee177510299abfaa2ead4be9aae024a22fd388acfb0b49fdfe8d45d15cbc6c960934fb073efd2fd68c80a9dee5d3a3ac30097baec08fd8de4b5cd5 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 @@ -13998,30 +12252,6 @@ __metadata: languageName: node linkType: hard -"eslint-config-next@npm:14.2.8": - version: 14.2.8 - resolution: "eslint-config-next@npm:14.2.8" - dependencies: - "@next/eslint-plugin-next": "npm:14.2.8" - "@rushstack/eslint-patch": "npm:^1.3.3" - "@typescript-eslint/eslint-plugin": "npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0" - "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0" - eslint-import-resolver-node: "npm:^0.3.6" - eslint-import-resolver-typescript: "npm:^3.5.2" - eslint-plugin-import: "npm:^2.28.1" - eslint-plugin-jsx-a11y: "npm:^6.7.1" - eslint-plugin-react: "npm:^7.33.2" - eslint-plugin-react-hooks: "npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - peerDependencies: - eslint: ^7.23.0 || ^8.0.0 - typescript: ">=3.3.1" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/932538864965157d94e6ad32f674afee40fb72d81070550e29bce1b5c8c52f5221f9ddbf483622a29507c760b6317ee7c660590ad8454d23e232a31e6371cc0b - languageName: node - linkType: hard - "eslint-config-prettier@npm:^10.1.2": version: 10.1.2 resolution: "eslint-config-prettier@npm:10.1.2" @@ -14044,53 +12274,6 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-node@npm:^0.3.6, eslint-import-resolver-node@npm:^0.3.9": - version: 0.3.9 - resolution: "eslint-import-resolver-node@npm:0.3.9" - dependencies: - debug: "npm:^3.2.7" - is-core-module: "npm:^2.13.0" - resolve: "npm:^1.22.4" - checksum: 10c0/0ea8a24a72328a51fd95aa8f660dcca74c1429806737cf10261ab90cfcaaf62fd1eff664b76a44270868e0a932711a81b250053942595bcd00a93b1c1575dd61 - languageName: node - linkType: hard - -"eslint-import-resolver-typescript@npm:^3.5.2": - version: 3.10.1 - resolution: "eslint-import-resolver-typescript@npm:3.10.1" - dependencies: - "@nolyfill/is-core-module": "npm:1.0.39" - debug: "npm:^4.4.0" - get-tsconfig: "npm:^4.10.0" - is-bun-module: "npm:^2.0.0" - stable-hash: "npm:^0.0.5" - tinyglobby: "npm:^0.2.13" - unrs-resolver: "npm:^1.6.2" - peerDependencies: - eslint: "*" - eslint-plugin-import: "*" - eslint-plugin-import-x: "*" - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - checksum: 10c0/02ba72cf757753ab9250806c066d09082e00807b7b6525d7687e1c0710bc3f6947e39120227fe1f93dabea3510776d86fb3fd769466ba3c46ce67e9f874cb702 - languageName: node - linkType: hard - -"eslint-module-utils@npm:^2.12.0": - version: 2.12.0 - resolution: "eslint-module-utils@npm:2.12.0" - dependencies: - debug: "npm:^3.2.7" - peerDependenciesMeta: - eslint: - optional: true - checksum: 10c0/4d8b46dcd525d71276f9be9ffac1d2be61c9d54cc53c992e6333cf957840dee09381842b1acbbb15fc6b255ebab99cd481c5007ab438e5455a14abe1a0468558 - languageName: node - linkType: hard - "eslint-plugin-eslint-comments@npm:^3.2.0": version: 3.2.0 resolution: "eslint-plugin-eslint-comments@npm:3.2.0" @@ -14116,35 +12299,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.28.1": - version: 2.31.0 - resolution: "eslint-plugin-import@npm:2.31.0" - dependencies: - "@rtsao/scc": "npm:^1.1.0" - array-includes: "npm:^3.1.8" - array.prototype.findlastindex: "npm:^1.2.5" - array.prototype.flat: "npm:^1.3.2" - array.prototype.flatmap: "npm:^1.3.2" - debug: "npm:^3.2.7" - doctrine: "npm:^2.1.0" - eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.12.0" - hasown: "npm:^2.0.2" - is-core-module: "npm:^2.15.1" - is-glob: "npm:^4.0.3" - minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.8" - object.groupby: "npm:^1.0.3" - object.values: "npm:^1.2.0" - semver: "npm:^6.3.1" - string.prototype.trimend: "npm:^1.0.8" - tsconfig-paths: "npm:^3.15.0" - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - checksum: 10c0/e21d116ddd1900e091ad120b3eb68c5dd5437fe2c930f1211781cd38b246f090a6b74d5f3800b8255a0ed29782591521ad44eb21c5534960a8f1fb4040fd913a - languageName: node - linkType: hard - "eslint-plugin-jest@npm:^27.9.0": version: 27.9.0 resolution: "eslint-plugin-jest@npm:27.9.0" @@ -14181,31 +12335,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.7.1": - version: 6.10.2 - resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" - dependencies: - aria-query: "npm:^5.3.2" - array-includes: "npm:^3.1.8" - array.prototype.flatmap: "npm:^1.3.2" - ast-types-flow: "npm:^0.0.8" - axe-core: "npm:^4.10.0" - axobject-query: "npm:^4.1.0" - damerau-levenshtein: "npm:^1.0.8" - emoji-regex: "npm:^9.2.2" - hasown: "npm:^2.0.2" - jsx-ast-utils: "npm:^3.3.5" - language-tags: "npm:^1.0.9" - minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.8" - safe-regex-test: "npm:^1.0.3" - string.prototype.includes: "npm:^2.0.1" - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - checksum: 10c0/d93354e03b0cf66f018d5c50964e074dffe4ddf1f9b535fa020d19c4ae45f89c1a16e9391ca61ac3b19f7042c751ac0d361a056a65cbd1de24718a53ff8daa6e - languageName: node - linkType: hard - "eslint-plugin-prettier@npm:^5.2.6": version: 5.2.6 resolution: "eslint-plugin-prettier@npm:5.2.6" @@ -14226,15 +12355,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version: 5.0.0-canary-7118f5dd7-20230705 - resolution: "eslint-plugin-react-hooks@npm:5.0.0-canary-7118f5dd7-20230705" - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10c0/554c4e426bfeb126155510dcba8345391426af147ee629f1c56c9ef6af08340d11008213e4e15b0138830af2c4439d7158da2091987f7efb01aeab662c44b274 - languageName: node - linkType: hard - "eslint-plugin-react-hooks@npm:^4.6.0": version: 4.6.2 resolution: "eslint-plugin-react-hooks@npm:4.6.2" @@ -14262,7 +12382,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.30.1, eslint-plugin-react@npm:^7.33.2": +"eslint-plugin-react@npm:^7.30.1": version: 7.37.5 resolution: "eslint-plugin-react@npm:7.37.5" dependencies: @@ -14340,7 +12460,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8, eslint@npm:^8.19.0": +"eslint@npm:^8.19.0": version: 8.57.1 resolution: "eslint@npm:8.57.1" dependencies: @@ -14669,13 +12789,6 @@ __metadata: languageName: node linkType: hard -"eventemitter3@npm:5.0.1": - version: 5.0.1 - resolution: "eventemitter3@npm:5.0.1" - checksum: 10c0/4ba5c00c506e6c786b4d6262cfbce90ddc14c10d4667e5c83ae993c9de88aa856033994dd2b35b83e8dc1170e224e66a319fa80adc4c32adcd2379bbc75da814 - languageName: node - linkType: hard - "events@npm:^3.2.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" @@ -14694,33 +12807,6 @@ __metadata: languageName: node linkType: hard -"exact-mirror@npm:0.1.2": - version: 0.1.2 - resolution: "exact-mirror@npm:0.1.2" - peerDependencies: - "@sinclair/typebox": ^0.34.15 - peerDependenciesMeta: - "@sinclair/typebox": - optional: true - checksum: 10c0/26e8924494b6a1e3db4bca9376a33da0b50821f486158fd6bda46f82af863ff856117b4ca5b864004400668550bf219879c117e8179683c418f8847bd0507b96 - languageName: node - linkType: hard - -"execa@npm:^0.7.0": - version: 0.7.0 - resolution: "execa@npm:0.7.0" - dependencies: - cross-spawn: "npm:^5.0.1" - get-stream: "npm:^3.0.0" - is-stream: "npm:^1.1.0" - npm-run-path: "npm:^2.0.0" - p-finally: "npm:^1.0.0" - signal-exit: "npm:^3.0.0" - strip-eof: "npm:^1.0.0" - checksum: 10c0/812f1776e2a6b2226532e43c1af87d8a12e26de03a06e7e043f653acf5565e0656f5f6c64d66726fefa17178ac129caaa419a50905934e7c4a846417abb25d4a - languageName: node - linkType: hard - "execa@npm:^5.0.0, execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -14738,13 +12824,6 @@ __metadata: languageName: node linkType: hard -"exit-hook@npm:^1.0.0": - version: 1.1.1 - resolution: "exit-hook@npm:1.1.1" - checksum: 10c0/6485772b1f5fdc5c8bf0cf9e9ba430f5b1e1ced2976be0bc6474b695358be32374a59370f5a3cec452c1b786b5f181035f3a10c58f9c639d7a7218e1b49e1a3a - languageName: node - linkType: hard - "exit@npm:^0.1.2": version: 0.1.2 resolution: "exit@npm:0.1.2" @@ -14752,21 +12831,6 @@ __metadata: languageName: node linkType: hard -"expand-brackets@npm:^2.1.4": - version: 2.1.4 - resolution: "expand-brackets@npm:2.1.4" - dependencies: - debug: "npm:^2.3.3" - define-property: "npm:^0.2.5" - extend-shallow: "npm:^2.0.1" - posix-character-classes: "npm:^0.1.0" - regex-not: "npm:^1.0.0" - snapdragon: "npm:^0.8.1" - to-regex: "npm:^3.0.1" - checksum: 10c0/3e2fb95d2d7d7231486493fd65db913927b656b6fcdfcce41e139c0991a72204af619ad4acb1be75ed994ca49edb7995ef241dbf8cf44dc3c03d211328428a87 - languageName: node - linkType: hard - "expect@npm:*, expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" @@ -14796,48 +12860,6 @@ __metadata: languageName: node linkType: hard -"extend-shallow@npm:^2.0.1": - version: 2.0.1 - resolution: "extend-shallow@npm:2.0.1" - dependencies: - is-extendable: "npm:^0.1.0" - checksum: 10c0/ee1cb0a18c9faddb42d791b2d64867bd6cfd0f3affb711782eb6e894dd193e2934a7f529426aac7c8ddb31ac5d38000a00aa2caf08aa3dfc3e1c8ff6ba340bd9 - languageName: node - linkType: hard - -"extend-shallow@npm:^3.0.0, extend-shallow@npm:^3.0.2": - version: 3.0.2 - resolution: "extend-shallow@npm:3.0.2" - dependencies: - assign-symbols: "npm:^1.0.0" - is-extendable: "npm:^1.0.1" - checksum: 10c0/f39581b8f98e3ad94995e33214fff725b0297cf09f2725b6f624551cfb71e0764accfd0af80becc0182af5014d2a57b31b85ec999f9eb8a6c45af81752feac9a - languageName: node - linkType: hard - -"extend@npm:3.0.0": - version: 3.0.0 - resolution: "extend@npm:3.0.0" - checksum: 10c0/67a867fd39abcd36f3d11e99c6e2808d0237214239ca7a194278b1a91790945a3755e22fd4e16521a247e511f9bce866142b483e1ca61d33d7c2317aa98ecf5a - languageName: node - linkType: hard - -"extglob@npm:^2.0.4": - version: 2.0.4 - resolution: "extglob@npm:2.0.4" - dependencies: - array-unique: "npm:^0.3.2" - define-property: "npm:^1.0.0" - expand-brackets: "npm:^2.1.4" - extend-shallow: "npm:^2.0.1" - fragment-cache: "npm:^0.2.1" - regex-not: "npm:^1.0.0" - snapdragon: "npm:^0.8.1" - to-regex: "npm:^3.0.1" - checksum: 10c0/e1a891342e2010d046143016c6c03d58455c2c96c30bf5570ea07929984ee7d48fad86b363aee08f7a8a638f5c3a66906429b21ecb19bc8e90df56a001cd282c - languageName: node - linkType: hard - "extract-zip@npm:2.0.1, extract-zip@npm:^2.0.1": version: 2.0.1 resolution: "extract-zip@npm:2.0.1" @@ -14862,13 +12884,6 @@ __metadata: languageName: node linkType: hard -"fast-decode-uri-component@npm:^1.0.1": - version: 1.0.1 - resolution: "fast-decode-uri-component@npm:1.0.1" - checksum: 10c0/039d50c2e99d64f999c3f2126c23fbf75a04a4117e218a149ca0b1d2aeb8c834b7b19d643b9d35d4eabce357189a6a94085f78cf48869e6e26cc59b036284bc3 - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -14917,13 +12932,6 @@ __metadata: languageName: node linkType: hard -"fast-safe-stringify@npm:^2.1.1": - version: 2.1.1 - resolution: "fast-safe-stringify@npm:2.1.1" - checksum: 10c0/d90ec1c963394919828872f21edaa3ad6f1dddd288d2bd4e977027afff09f5db40f94e39536d4646f7e01761d704d72d51dce5af1b93717f3489ef808f5f4e4d - languageName: node - linkType: hard - "fast-uri@npm:^3.0.1": version: 3.0.6 resolution: "fast-uri@npm:3.0.6" @@ -15055,16 +13063,6 @@ __metadata: languageName: node linkType: hard -"figures@npm:^1.3.5": - version: 1.7.0 - resolution: "figures@npm:1.7.0" - dependencies: - escape-string-regexp: "npm:^1.0.5" - object-assign: "npm:^4.1.0" - checksum: 10c0/a10942b0eec3372bf61822ab130d2bbecdf527d551b0b013fbe7175b7a0238ead644ee8930a1a3cb872fb9ab2ec27df30e303765a3b70b97852e2e9ee43bdff3 - languageName: node - linkType: hard - "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -15074,13 +13072,6 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 - languageName: node - linkType: hard - "filelist@npm:^1.0.4": version: 1.0.4 resolution: "filelist@npm:1.0.4" @@ -15090,21 +13081,9 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^4.0.0": - version: 4.0.0 - resolution: "fill-range@npm:4.0.0" - dependencies: - extend-shallow: "npm:^2.0.1" - is-number: "npm:^3.0.0" - repeat-string: "npm:^1.6.1" - to-regex-range: "npm:^2.1.0" - checksum: 10c0/ccd57b7c43d7e28a1f8a60adfa3c401629c08e2f121565eece95e2386ebc64dedc7128d8c3448342aabf19db0c55a34f425f148400c7a7be9a606ba48749e089 - languageName: node - linkType: hard - -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" dependencies: to-regex-range: "npm:^5.0.1" checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 @@ -15162,13 +13141,6 @@ __metadata: languageName: node linkType: hard -"find-root@npm:^1.1.0": - version: 1.1.0 - resolution: "find-root@npm:1.1.0" - checksum: 10c0/1abc7f3bf2f8d78ff26d9e00ce9d0f7b32e5ff6d1da2857bcdf4746134c422282b091c672cde0572cac3840713487e0a7a636af9aa1b74cb11894b447a521efa - languageName: node - linkType: hard - "find-up@npm:^3.0.0": version: 3.0.0 resolution: "find-up@npm:3.0.0" @@ -15281,7 +13253,7 @@ __metadata: languageName: node linkType: hard -"for-in@npm:^1.0.1, for-in@npm:^1.0.2": +"for-in@npm:^1.0.1": version: 1.0.2 resolution: "for-in@npm:1.0.2" checksum: 10c0/42bb609d564b1dc340e1996868b67961257fd03a48d7fdafd4f5119530b87f962be6b4d5b7e3a3fc84c9854d149494b1d358e0b0ce9837e64c4c6603a49451d6 @@ -15307,17 +13279,6 @@ __metadata: languageName: node linkType: hard -"form-data@npm:1.0.0-rc3": - version: 1.0.0-rc3 - resolution: "form-data@npm:1.0.0-rc3" - dependencies: - async: "npm:^1.4.0" - combined-stream: "npm:^1.0.5" - mime-types: "npm:^2.1.3" - checksum: 10c0/d67674a76f46253f69aebdc5c1c86aa123385940d147346b2f801681656ab5df6b82bd9568483e1579fd53bf277795f2da7592c6a842893465ef69e9073c342f - languageName: node - linkType: hard - "form-data@npm:^2.2.0": version: 2.5.3 resolution: "form-data@npm:2.5.3" @@ -15343,25 +13304,6 @@ __metadata: languageName: node linkType: hard -"formidable@npm:^2.0.1": - version: 2.1.5 - resolution: "formidable@npm:2.1.5" - dependencies: - "@paralleldrive/cuid2": "npm:^2.2.2" - dezalgo: "npm:^1.0.4" - once: "npm:^1.4.0" - qs: "npm:^6.11.0" - checksum: 10c0/2c68ca6cccc1ac3de497c50236631fafea8e1a09396d88b4dd2dc9db6029b5abaeb6747b8b97ebc1143cd40cf62c27ba485b8c6317088c066fc999af3ac621d4 - languageName: node - linkType: hard - -"formidable@npm:~1.0.14": - version: 1.0.17 - resolution: "formidable@npm:1.0.17" - checksum: 10c0/651c7394574ab6b451467200495bcb5064776419d883e6f82512f31019a0528de90c729d28d89d519eb00cb456302206aa389a4d63d2aba69eef5653ba863714 - languageName: node - linkType: hard - "fp-ts@npm:1.19.3": version: 1.19.3 resolution: "fp-ts@npm:1.19.3" @@ -15376,15 +13318,6 @@ __metadata: languageName: node linkType: hard -"fragment-cache@npm:^0.2.1": - version: 0.2.1 - resolution: "fragment-cache@npm:0.2.1" - dependencies: - map-cache: "npm:^0.2.2" - checksum: 10c0/5891d1c1d1d5e1a7fb3ccf28515c06731476fa88f7a50f4ede8a0d8d239a338448e7f7cc8b73db48da19c229fa30066104fe6489862065a4f1ed591c42fbeabf - languageName: node - linkType: hard - "framer-motion@npm:^6.5.1": version: 6.5.1 resolution: "framer-motion@npm:6.5.1" @@ -15422,18 +13355,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^0.24.0": - version: 0.24.0 - resolution: "fs-extra@npm:0.24.0" - dependencies: - graceful-fs: "npm:^4.1.2" - jsonfile: "npm:^2.1.0" - path-is-absolute: "npm:^1.0.0" - rimraf: "npm:^2.2.8" - checksum: 10c0/bd60b201302789155de4f5c4c2bfcc389a077cf4aaea47fe8f23c5c209cd2dc00cdaa1181978572e38404ed47ccfda2f0e68bfd2616af4d554318a4ecb925233 - languageName: node - linkType: hard - "fs-extra@npm:^10.0.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" @@ -15518,17 +13439,6 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^1.2.7": - version: 1.2.13 - resolution: "fsevents@npm:1.2.13" - dependencies: - bindings: "npm:^1.5.0" - nan: "npm:^2.12.1" - checksum: 10c0/4427ff08db9ee7327f2c3ad58ec56f9096a917eed861bfffaa2e2be419479cdf37d00750869ab9ecbf5f59f32ad999bd59577d73fc639193e6c0ce52bb253e02 - conditions: os=darwin - languageName: node - linkType: hard - "fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -15539,16 +13449,6 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A^1.2.7#optional!builtin": - version: 1.2.13 - resolution: "fsevents@patch:fsevents@npm%3A1.2.13#optional!builtin::version=1.2.13&hash=d11327" - dependencies: - bindings: "npm:^1.5.0" - nan: "npm:^2.12.1" - conditions: os=darwin - languageName: node - linkType: hard - "fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -15663,13 +13563,6 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^3.0.0": - version: 3.0.0 - resolution: "get-stream@npm:3.0.0" - checksum: 10c0/003f5f3b8870da59c6aafdf6ed7e7b07b48c2f8629cd461bd3900726548b6b8cfa2e14d6b7814fbb08f07a42f4f738407fa70b989928b2783a76b278505bba22 - languageName: node - linkType: hard - "get-stream@npm:^5.1.0": version: 5.2.0 resolution: "get-stream@npm:5.2.0" @@ -15697,7 +13590,7 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.10.0, get-tsconfig@npm:^4.7.5": +"get-tsconfig@npm:^4.7.5": version: 4.10.1 resolution: "get-tsconfig@npm:4.10.1" dependencies: @@ -15717,13 +13610,6 @@ __metadata: languageName: node linkType: hard -"get-value@npm:^2.0.3, get-value@npm:^2.0.6": - version: 2.0.6 - resolution: "get-value@npm:2.0.6" - checksum: 10c0/f069c132791b357c8fc4adfe9e2929b0a2c6e95f98ca7bc6fcbc27f8a302e552f86b4ae61ec56d9e9ac2544b93b6a39743d479866a37b43fcc104088ba74f0d9 - languageName: node - linkType: hard - "ghost-testrpc@npm:^0.0.2": version: 0.0.2 resolution: "ghost-testrpc@npm:0.0.2" @@ -15736,16 +13622,6 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^3.1.0": - version: 3.1.0 - resolution: "glob-parent@npm:3.1.0" - dependencies: - is-glob: "npm:^3.1.0" - path-dirname: "npm:^1.0.0" - checksum: 10c0/bfa89ce5ae1dfea4c2ece7b61d2ea230d87fcbec7472915cfdb3f4caf688a91ecb0dc86ae39b1e17505adce7e64cae3b971d64dc66091f3a0131169fd631b00d - languageName: node - linkType: hard - "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -15771,31 +13647,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" - minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" - bin: - glob: dist/esm/bin.mjs - checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d - languageName: node - linkType: hard - -"glob@npm:3.2.11": - version: 3.2.11 - resolution: "glob@npm:3.2.11" - dependencies: - inherits: "npm:2" - minimatch: "npm:0.3" - checksum: 10c0/d3ca265ee7a3cec543f49d93ac20925c8b2fa66a0f87ffaf3004ef9cef62414a55cb0b0f22a1e8e3f7b77154e6b9afdfaf589099276b3c6402e8a23849c5cc25 - languageName: node - linkType: hard - "glob@npm:7.1.7": version: 7.1.7 resolution: "glob@npm:7.1.7" @@ -15810,7 +13661,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10": +"glob@npm:^10.2.2": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -15866,15 +13717,6 @@ __metadata: languageName: node linkType: hard -"global-dirs@npm:^0.1.0": - version: 0.1.1 - resolution: "global-dirs@npm:0.1.1" - dependencies: - ini: "npm:^1.3.4" - checksum: 10c0/3608072e58962396c124ad5a1cfb3f99ee76c998654a3432d82977b3c3eeb09dc8a5a2a9849b2b8113906c8d0aad89ce362c22e97cec5fe34405bbf4f3cdbe7a - languageName: node - linkType: hard - "global-modules@npm:^2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" @@ -15977,25 +13819,6 @@ __metadata: languageName: node linkType: hard -"got@npm:^6.7.1": - version: 6.7.1 - resolution: "got@npm:6.7.1" - dependencies: - create-error-class: "npm:^3.0.0" - duplexer3: "npm:^0.1.4" - get-stream: "npm:^3.0.0" - is-redirect: "npm:^1.0.0" - is-retry-allowed: "npm:^1.0.0" - is-stream: "npm:^1.0.0" - lowercase-keys: "npm:^1.0.0" - safe-buffer: "npm:^5.0.1" - timed-out: "npm:^4.0.0" - unzip-response: "npm:^2.0.1" - url-parse-lax: "npm:^1.0.0" - checksum: 10c0/10a3b2254b3c1dd61a93f7c3dd3061bfc13c4c7c1fc9a7cfa348e5d4f619c20dcf8f8638da4a46372ea9a646fd56fe4cf291174c8a50ab4c8f1f70809c767a15 - languageName: node - linkType: hard - "graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.3, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -16017,22 +13840,6 @@ __metadata: languageName: node linkType: hard -"graphlib@npm:^2.1.1": - version: 2.1.8 - resolution: "graphlib@npm:2.1.8" - dependencies: - lodash: "npm:^4.17.15" - checksum: 10c0/41c525e4d91a6d8b4e8da1883bf4e85689a547e908557ccc53f64db9141bdfb351b9162a79f13cae81c5b3a410027f59e4fc1edc1ea442234ec08e629859b188 - languageName: node - linkType: hard - -"growl@npm:1.9.2": - version: 1.9.2 - resolution: "growl@npm:1.9.2" - checksum: 10c0/e3191e0fafb218c0d0d404198a94c32a53b21504cde9f01781907897504b7f1a63fe4038a4e197af8b0f375a64f98019213eb294be99d7fc7cf281f3ce5f6e75 - languageName: node - linkType: hard - "gzip-size@npm:^6.0.0": version: 6.0.0 resolution: "gzip-size@npm:6.0.0" @@ -16042,7 +13849,7 @@ __metadata: languageName: node linkType: hard -"handlebars@npm:^4.0.1, handlebars@npm:^4.0.5": +"handlebars@npm:^4.0.1": version: 4.7.8 resolution: "handlebars@npm:4.7.8" dependencies: @@ -16145,15 +13952,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: "npm:^2.0.0" - checksum: 10c0/f54e4887b9f8f3c4bfefd649c48825b3c093987c92c27880ee9898539e6f01aed261e82e73153c3f920fde0db5bf6ebd58deb498ed1debabcb4bc40113ccdf05 - languageName: node - linkType: hard - "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" @@ -16223,45 +14021,6 @@ __metadata: languageName: node linkType: hard -"has-value@npm:^0.3.1": - version: 0.3.1 - resolution: "has-value@npm:0.3.1" - dependencies: - get-value: "npm:^2.0.3" - has-values: "npm:^0.1.4" - isobject: "npm:^2.0.0" - checksum: 10c0/7a7c2e9d07bc9742c81806150adb154d149bc6155267248c459cd1ce2a64b0759980d26213260e4b7599c8a3754551179f155ded88d0533a0d2bc7bc29028432 - languageName: node - linkType: hard - -"has-value@npm:^1.0.0": - version: 1.0.0 - resolution: "has-value@npm:1.0.0" - dependencies: - get-value: "npm:^2.0.6" - has-values: "npm:^1.0.0" - isobject: "npm:^3.0.0" - checksum: 10c0/17cdccaf50f8aac80a109dba2e2ee5e800aec9a9d382ef9deab66c56b34269e4c9ac720276d5ffa722764304a1180ae436df077da0dd05548cfae0209708ba4d - languageName: node - linkType: hard - -"has-values@npm:^0.1.4": - version: 0.1.4 - resolution: "has-values@npm:0.1.4" - checksum: 10c0/a8f00ad862c20289798c35243d5bd0b0a97dd44b668c2204afe082e0265f2d0bf3b89fc8cc0ef01a52b49f10aa35cf85c336ee3a5f1cac96ed490f5e901cdbf2 - languageName: node - linkType: hard - -"has-values@npm:^1.0.0": - version: 1.0.0 - resolution: "has-values@npm:1.0.0" - dependencies: - is-number: "npm:^3.0.0" - kind-of: "npm:^4.0.0" - checksum: 10c0/a6f2a1cc6b2e43eacc68e62e71ad6890def7f4b13d2ef06b4ad3ee156c23e470e6df144b9b467701908e17633411f1075fdff0cab45fb66c5e0584d89b25f35e - languageName: node - linkType: hard - "hash-base@npm:^3.0.0": version: 3.1.0 resolution: "hash-base@npm:3.1.0" @@ -16283,7 +14042,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -16390,7 +14149,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -16399,13 +14158,6 @@ __metadata: languageName: node linkType: hard -"hookable@npm:^5.5.3": - version: 5.5.3 - resolution: "hookable@npm:5.5.3" - checksum: 10c0/275f4cc84d27f8d48c5a5cd5685b6c0fea9291be9deea5bff0cfa72856ed566abde1dcd8cb1da0f9a70b4da3d7ec0d60dc3554c4edbba647058cc38816eced3d - languageName: node - linkType: hard - "hoopy@npm:^0.1.4": version: 0.1.4 resolution: "hoopy@npm:0.1.4" @@ -16526,13 +14278,6 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.4.8": - version: 0.4.8 - resolution: "iconv-lite@npm:0.4.8" - checksum: 10c0/43c3a63b10f9a86a38fb72ec4b325e870a2af577b31cc1a9f8cc3f35787a84a1cc7e101b9add3ee19d1c77c03873e2b8827aa2dfefcaa13923c67194dcd3e54a - languageName: node - linkType: hard - "iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -16549,14 +14294,7 @@ __metadata: languageName: node linkType: hard -"ignore-by-default@npm:^1.0.1": - version: 1.0.1 - resolution: "ignore-by-default@npm:1.0.1" - checksum: 10c0/9ab6e70e80f7cc12735def7ecb5527cfa56ab4e1152cd64d294522827f2dcf1f6d85531241537dc3713544e88dd888f65cb3c49c7b2cddb9009087c75274e533 - languageName: node - linkType: hard - -"ignore@npm:^5.0.5, ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": +"ignore@npm:^5.0.5, ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -16615,13 +14353,6 @@ __metadata: languageName: node linkType: hard -"import-lazy@npm:^2.1.0": - version: 2.1.0 - resolution: "import-lazy@npm:2.1.0" - checksum: 10c0/c5e5f507d26ee23c5b2ed64577155810361ac37863b322cae0c17f16b6a8cdd15adf370288384ddd95ef9de05602fb8d87bf76ff835190eb037333c84db8062c - languageName: node - linkType: hard - "import-local@npm:^3.0.2": version: 3.2.0 resolution: "import-local@npm:3.2.0" @@ -16658,7 +14389,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -16672,33 +14403,13 @@ __metadata: languageName: node linkType: hard -"ini@npm:^1.3.4, ini@npm:^1.3.5, ini@npm:~1.3.0": +"ini@npm:^1.3.5": version: 1.3.8 resolution: "ini@npm:1.3.8" checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a languageName: node linkType: hard -"inquirer@npm:^0.10.0": - version: 0.10.1 - resolution: "inquirer@npm:0.10.1" - dependencies: - ansi-escapes: "npm:^1.1.0" - ansi-regex: "npm:^2.0.0" - chalk: "npm:^1.0.0" - cli-cursor: "npm:^1.0.1" - cli-width: "npm:^1.0.1" - figures: "npm:^1.3.5" - lodash: "npm:^3.3.1" - readline2: "npm:^1.0.1" - run-async: "npm:^0.1.0" - rx-lite: "npm:^3.1.2" - strip-ansi: "npm:^3.0.0" - through: "npm:^2.3.6" - checksum: 10c0/9a46497073342e8ab778e86958b55c2c2763335157a05686eaa1f7121242eef66a33f963e611117f06a628f4fb05d7f376b51efea6e19cda5e5edbf7d3b0a711 - languageName: node - linkType: hard - "int64-buffer@npm:^0.1.9": version: 0.1.10 resolution: "int64-buffer@npm:0.1.10" @@ -16752,15 +14463,6 @@ __metadata: languageName: node linkType: hard -"is-accessor-descriptor@npm:^1.0.1": - version: 1.0.1 - resolution: "is-accessor-descriptor@npm:1.0.1" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10c0/d034034074c5ffeb6c868e091083182279db1a956f49f8d1494cecaa0f8b99d706556ded2a9b20d9aa290549106eef8204d67d8572902e06dcb1add6db6b524d - languageName: node - linkType: hard - "is-arguments@npm:^1.0.4": version: 1.2.0 resolution: "is-arguments@npm:1.2.0" @@ -16818,15 +14520,6 @@ __metadata: languageName: node linkType: hard -"is-binary-path@npm:^1.0.0": - version: 1.0.1 - resolution: "is-binary-path@npm:1.0.1" - dependencies: - binary-extensions: "npm:^1.0.0" - checksum: 10c0/16e456fa3782eaf3d8e28d382b750507e3d54ff6694df8a1b2c6498da321e2ead311de9c42e653d8fb3213de72bac204b5f97e4a110cda8a72f17b1c1b4eb643 - languageName: node - linkType: hard - "is-binary-path@npm:~2.1.0": version: 2.1.0 resolution: "is-binary-path@npm:2.1.0" @@ -16846,22 +14539,6 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^1.1.5, is-buffer@npm:~1.1.1": - version: 1.1.6 - resolution: "is-buffer@npm:1.1.6" - checksum: 10c0/ae18aa0b6e113d6c490ad1db5e8df9bdb57758382b313f5a22c9c61084875c6396d50bbf49315f5b1926d142d74dfb8d31b40d993a383e0a158b15fea7a82234 - languageName: node - linkType: hard - -"is-bun-module@npm:^2.0.0": - version: 2.0.0 - resolution: "is-bun-module@npm:2.0.0" - dependencies: - semver: "npm:^7.7.1" - checksum: 10c0/7d27a0679cfa5be1f5052650391f9b11040cd70c48d45112e312c56bc6b6ca9c9aea70dcce6cc40b1e8947bfff8567a5c5715d3b066fb478522dab46ea379240 - languageName: node - linkType: hard - "is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -16869,18 +14546,7 @@ __metadata: languageName: node linkType: hard -"is-ci@npm:^1.0.10": - version: 1.2.1 - resolution: "is-ci@npm:1.2.1" - dependencies: - ci-info: "npm:^1.5.0" - bin: - is-ci: bin.js - checksum: 10c0/56d8e0e404c5ee9eb4cc846b9fbed043bac587633a8b10caad35b1e4b11edccae742037c4bc2196203e5929643bd257a4caac23b65e99b372a54e68d187bacc9 - languageName: node - linkType: hard - -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1, is-core-module@npm:^2.16.0": +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -16889,15 +14555,6 @@ __metadata: languageName: node linkType: hard -"is-data-descriptor@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-descriptor@npm:1.0.1" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10c0/ad3acc372e3227f87eb8cdba112c343ca2a67f1885aecf64f02f901cb0858a1fc9488ad42135ab102e9d9e71a62b3594740790bb103a9ba5da830a131a89e3e8 - languageName: node - linkType: hard - "is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": version: 1.0.2 resolution: "is-data-view@npm:1.0.2" @@ -16919,26 +14576,6 @@ __metadata: languageName: node linkType: hard -"is-descriptor@npm:^0.1.0": - version: 0.1.7 - resolution: "is-descriptor@npm:0.1.7" - dependencies: - is-accessor-descriptor: "npm:^1.0.1" - is-data-descriptor: "npm:^1.0.1" - checksum: 10c0/f5960b9783f508aec570465288cb673d4b3cc4aae4e6de970c3afd9a8fc1351edcb85d78b2cce2ec5251893a423f73263cab3bb94cf365a8d71b5d510a116392 - languageName: node - linkType: hard - -"is-descriptor@npm:^1.0.0, is-descriptor@npm:^1.0.2": - version: 1.0.3 - resolution: "is-descriptor@npm:1.0.3" - dependencies: - is-accessor-descriptor: "npm:^1.0.1" - is-data-descriptor: "npm:^1.0.1" - checksum: 10c0/b4ee667ea787d3a0be4e58536087fd0587de2b0b6672fbfe288f5b8d831ac4b79fd987f31d6c2d4e5543a42c97a87428bc5215ce292a1a47070147793878226f - languageName: node - linkType: hard - "is-directory@npm:^0.3.1": version: 0.3.1 resolution: "is-directory@npm:0.3.1" @@ -16955,30 +14592,14 @@ __metadata: languageName: node linkType: hard -"is-extendable@npm:^0.1.0, is-extendable@npm:^0.1.1": +"is-extendable@npm:^0.1.1": version: 0.1.1 resolution: "is-extendable@npm:0.1.1" checksum: 10c0/dd5ca3994a28e1740d1e25192e66eed128e0b2ff161a7ea348e87ae4f616554b486854de423877a2a2c171d5f7cd6e8093b91f54533bc88a59ee1c9838c43879 languageName: node linkType: hard -"is-extendable@npm:^1.0.1": - version: 1.0.1 - resolution: "is-extendable@npm:1.0.1" - dependencies: - is-plain-object: "npm:^2.0.4" - checksum: 10c0/1d6678a5be1563db6ecb121331c819c38059703f0179f52aa80c242c223ee9c6b66470286636c0e63d7163e4d905c0a7d82a096e0b5eaeabb51b9f8d0af0d73f - languageName: node - linkType: hard - -"is-extglob@npm:^1.0.0": - version: 1.0.0 - resolution: "is-extglob@npm:1.0.0" - checksum: 10c0/1ce5366d19958f36069a45ca996c1e51ab607f42a01eb0505f0ccffe8f9c91f5bcba6e971605efd8b4d4dfd0111afa3c8df3e1746db5b85b9a8f933f5e7286b7 - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": +"is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 @@ -16994,15 +14615,6 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^1.0.0": - version: 1.0.0 - resolution: "is-fullwidth-code-point@npm:1.0.0" - dependencies: - number-is-nan: "npm:^1.0.0" - checksum: 10c0/12acfcf16142f2d431bf6af25d68569d3198e81b9799b4ae41058247aafcc666b0127d64384ea28e67a746372611fcbe9b802f69175287aba466da3eddd5ba0f - languageName: node - linkType: hard - "is-fullwidth-code-point@npm:^2.0.0": version: 2.0.0 resolution: "is-fullwidth-code-point@npm:2.0.0" @@ -17036,24 +14648,6 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^2.0.0": - version: 2.0.1 - resolution: "is-glob@npm:2.0.1" - dependencies: - is-extglob: "npm:^1.0.0" - checksum: 10c0/ef156806af0924983325c9218a8b8a838fa50e1a104ed2a11fe94829a5b27c1b05a4c8cf98d96cb3a7fea539c21f14ae2081e1a248f3d5a9eea62f2d4e9f8b0c - languageName: node - linkType: hard - -"is-glob@npm:^3.1.0": - version: 3.1.0 - resolution: "is-glob@npm:3.1.0" - dependencies: - is-extglob: "npm:^2.1.0" - checksum: 10c0/ba816a35dcf5285de924a8a4654df7b183a86381d73ea3bbf3df3cc61b3ba61fdddf90ee205709a2235b210ee600ee86e5e8600093cf291a662607fd032e2ff4 - languageName: node - linkType: hard - "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" @@ -17070,16 +14664,6 @@ __metadata: languageName: node linkType: hard -"is-installed-globally@npm:^0.1.0": - version: 0.1.0 - resolution: "is-installed-globally@npm:0.1.0" - dependencies: - global-dirs: "npm:^0.1.0" - is-path-inside: "npm:^1.0.0" - checksum: 10c0/e5664812205367240bf7229e56410a4d33a83843e32642938dc5d0ba6d53e5125b24ea9aefcf5d35bc3ab8a868469d631624ce59dead1d6ceadf88b19cca6ab7 - languageName: node - linkType: hard - "is-interactive@npm:^1.0.0": version: 1.0.0 resolution: "is-interactive@npm:1.0.0" @@ -17087,15 +14671,6 @@ __metadata: languageName: node linkType: hard -"is-invalid-path@npm:^0.1.0": - version: 0.1.0 - resolution: "is-invalid-path@npm:0.1.0" - dependencies: - is-glob: "npm:^2.0.0" - checksum: 10c0/9f7f74825ddcbd70ceb0aca1155d2961f3767a7a0f1351c255d25047cc7dece161b755d0698aaf8f201693d96ea12e04b4afa00ee9b4f8f47ab5ec2adbe96df8 - languageName: node - linkType: hard - "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -17103,13 +14678,6 @@ __metadata: languageName: node linkType: hard -"is-npm@npm:^1.0.0": - version: 1.0.0 - resolution: "is-npm@npm:1.0.0" - checksum: 10c0/6d9a9cfbb849ad631e3050d1dad140ded91a10f374b57ff6ccb688b4ee8d5fd139e6aa2c5ab4342b8119242c9c4cba041876fb4046fcae52e76eb073db71dfe7 - languageName: node - linkType: hard - "is-number-object@npm:^1.1.1": version: 1.1.1 resolution: "is-number-object@npm:1.1.1" @@ -17120,15 +14688,6 @@ __metadata: languageName: node linkType: hard -"is-number@npm:^3.0.0": - version: 3.0.0 - resolution: "is-number@npm:3.0.0" - dependencies: - kind-of: "npm:^3.0.2" - checksum: 10c0/e639c54640b7f029623df24d3d103901e322c0c25ea5bde97cd723c2d0d4c05857a8364ab5c58d963089dbed6bf1d0ffe975cb6aef917e2ad0ccbca653d31b4f - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -17136,22 +14695,6 @@ __metadata: languageName: node linkType: hard -"is-obj@npm:^1.0.0": - version: 1.0.1 - resolution: "is-obj@npm:1.0.1" - checksum: 10c0/5003acba0af7aa47dfe0760e545a89bbac89af37c12092c3efadc755372cdaec034f130e7a3653a59eb3c1843cfc72ca71eaf1a6c3bafe5a0bab3611a47f9945 - languageName: node - linkType: hard - -"is-path-inside@npm:^1.0.0": - version: 1.0.1 - resolution: "is-path-inside@npm:1.0.1" - dependencies: - path-is-inside: "npm:^1.0.1" - checksum: 10c0/093ab1324e33a95c2d057e1450e1936ee7a3ed25b78c8dc42f576f3dc3489dd8788d431ea2969bb0e081f005de1571792ea99cf7b1b69ab2dd4ca477ae7a8e51 - languageName: node - linkType: hard - "is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" @@ -17166,7 +14709,7 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": +"is-plain-object@npm:^2.0.4": version: 2.0.4 resolution: "is-plain-object@npm:2.0.4" dependencies: @@ -17175,13 +14718,6 @@ __metadata: languageName: node linkType: hard -"is-redirect@npm:^1.0.0": - version: 1.0.0 - resolution: "is-redirect@npm:1.0.0" - checksum: 10c0/4fb24eaa61548d276499ec5e2f7efbc4ed823b68c7ee3bdfbf29d0f6c45d19c07f417bf3dd86110285c28a35481b46a9996921739b7b84bb8ba5216f250d40de - languageName: node - linkType: hard - "is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" @@ -17194,13 +14730,6 @@ __metadata: languageName: node linkType: hard -"is-retry-allowed@npm:^1.0.0": - version: 1.2.0 - resolution: "is-retry-allowed@npm:1.2.0" - checksum: 10c0/a80f14e1e11c27a58f268f2927b883b635703e23a853cb7b8436e3456bf2ea3efd5082a4e920093eec7bd372c1ce6ea7cea78a9376929c211039d0cc4a393a44 - languageName: node - linkType: hard - "is-set@npm:^2.0.3": version: 2.0.3 resolution: "is-set@npm:2.0.3" @@ -17217,13 +14746,6 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^1.0.0, is-stream@npm:^1.1.0": - version: 1.1.0 - resolution: "is-stream@npm:1.1.0" - checksum: 10c0/b8ae7971e78d2e8488d15f804229c6eed7ed36a28f8807a1815938771f4adff0e705218b7dab968270433f67103e4fef98062a0beea55d64835f705ee72c7002 - languageName: node - linkType: hard - "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -17268,15 +14790,6 @@ __metadata: languageName: node linkType: hard -"is-valid-path@npm:^0.1.1": - version: 0.1.1 - resolution: "is-valid-path@npm:0.1.1" - dependencies: - is-invalid-path: "npm:^0.1.0" - checksum: 10c0/05c3533b8d98ac469bec9849e6ee73a07e1f9857e2043c75a9a45d21bae5e11fafb625808d7bd1aaf5cc63e842876c636f9888388a959ee9c33975c7b603c6ba - languageName: node - linkType: hard - "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -17303,13 +14816,6 @@ __metadata: languageName: node linkType: hard -"is-windows@npm:^1.0.2": - version: 1.0.2 - resolution: "is-windows@npm:1.0.2" - checksum: 10c0/b32f418ab3385604a66f1b7a3ce39d25e8881dee0bd30816dc8344ef6ff9df473a732bcc1ec4e84fe99b2f229ae474f7133e8e93f9241686cfcf7eebe53ba7a5 - languageName: node - linkType: hard - "is-wsl@npm:^1.1.0": version: 1.1.0 resolution: "is-wsl@npm:1.1.0" @@ -17326,14 +14832,7 @@ __metadata: languageName: node linkType: hard -"isarray@npm:0.0.1": - version: 0.0.1 - resolution: "isarray@npm:0.0.1" - checksum: 10c0/ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311 - languageName: node - linkType: hard - -"isarray@npm:1.0.0, isarray@npm:^1.0.0, isarray@npm:~1.0.0": +"isarray@npm:^1.0.0, isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d @@ -17361,31 +14860,13 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^2.0.0": - version: 2.1.0 - resolution: "isobject@npm:2.1.0" - dependencies: - isarray: "npm:1.0.0" - checksum: 10c0/c4cafec73b3b2ee11be75dff8dafd283b5728235ac099b07d7873d5182553a707768e208327bbc12931b9422d8822280bf88d894a0024ff5857b3efefb480e7b - languageName: node - linkType: hard - -"isobject@npm:^3.0.0, isobject@npm:^3.0.1": +"isobject@npm:^3.0.1": version: 3.0.1 resolution: "isobject@npm:3.0.1" checksum: 10c0/03344f5064a82f099a0cd1a8a407f4c0d20b7b8485e8e816c39f249e9416b06c322e8dec5b842b6bb8a06de0af9cb48e7bc1b5352f0fadc2f0abac033db3d4db languageName: node linkType: hard -"isows@npm:1.0.7": - version: 1.0.7 - resolution: "isows@npm:1.0.7" - peerDependencies: - ws: "*" - checksum: 10c0/43c41fe89c7c07258d0be3825f87e12da8ac9023c5b5ae6741ec00b2b8169675c04331ea73ef8c172d37a6747066f4dc93947b17cd369f92828a3b3e741afbda - languageName: node - linkType: hard - "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" @@ -17465,19 +14946,6 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 - languageName: node - linkType: hard - "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -17491,18 +14959,6 @@ __metadata: languageName: node linkType: hard -"jade@npm:0.26.3": - version: 0.26.3 - resolution: "jade@npm:0.26.3" - dependencies: - commander: "npm:0.6.1" - mkdirp: "npm:0.3.0" - bin: - jade: ./bin/jade - checksum: 10c0/5fac05818e7203de6e2ba1afa06f522070054166dba95621ec57be891011f6767cdbc30d56e4987b94da89ad84ff28fcf06c6d91b7779c21a3dd0800d67dd6bc - languageName: node - linkType: hard - "jake@npm:^10.8.5": version: 10.9.2 resolution: "jake@npm:10.9.2" @@ -17967,15 +15423,6 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.21.6": - version: 1.21.7 - resolution: "jiti@npm:1.21.7" - bin: - jiti: bin/jiti.js - checksum: 10c0/77b61989c758ff32407cdae8ddc77f85e18e1a13fc4977110dbd2e05fc761842f5f71bce684d9a01316e1c4263971315a111385759951080bbfe17cbb5de8f7a - languageName: node - linkType: hard - "jiti@npm:^2.4.2": version: 2.4.2 resolution: "jiti@npm:2.4.2" @@ -18040,13 +15487,6 @@ __metadata: languageName: node linkType: hard -"js-string-escape@npm:^1.0.1": - version: 1.0.1 - resolution: "js-string-escape@npm:1.0.1" - checksum: 10c0/2c33b9ff1ba6b84681c51ca0997e7d5a1639813c95d5b61cb7ad47e55cc28fa4a0b1935c3d218710d8e6bcee5d0cd8c44755231e3a4e45fc604534d9595a3628 - languageName: node - linkType: hard - "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -18054,7 +15494,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:3.x, js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.3.0, js-yaml@npm:^3.3.1, js-yaml@npm:^3.8.3": +"js-yaml@npm:3.x, js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" dependencies: @@ -18175,40 +15615,6 @@ __metadata: languageName: node linkType: hard -"json-refs@npm:^2.1.5": - version: 2.1.7 - resolution: "json-refs@npm:2.1.7" - dependencies: - commander: "npm:^2.9.0" - graphlib: "npm:^2.1.1" - js-yaml: "npm:^3.8.3" - native-promise-only: "npm:^0.8.1" - path-loader: "npm:^1.0.2" - slash: "npm:^1.0.0" - uri-js: "npm:^3.0.2" - bin: - json-refs: ./bin/json-refs - checksum: 10c0/c67aab9e874cf2dbcd6d06df2ada034410c9af053c3c14d1d3c60c64e8903773555c3f1dcd4ddfaf0532b8804ee19b0f5eddc21cecbec67e081d491e719bd41c - languageName: node - linkType: hard - -"json-schema-deref-sync@npm:^0.6.0": - version: 0.6.0 - resolution: "json-schema-deref-sync@npm:0.6.0" - dependencies: - clone: "npm:^2.1.2" - dag-map: "npm:~1.0.0" - is-valid-path: "npm:^0.1.1" - lodash: "npm:^4.17.11" - md5: "npm:~2.2.0" - memory-cache: "npm:~0.2.0" - mpath: "npm:~0.5.0" - traverse: "npm:~0.6.6" - valid-url: "npm:~1.0.9" - checksum: 10c0/aed431cb0a3a4dbaebce4fcf571a40df9e9f3978ef555367e1ac4a707613cc4eba0f9b2b3bffb4d4da701fe5dd35e22b75d9bfb3760c4c43220e30e2ca053b7f - languageName: node - linkType: hard - "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -18288,18 +15694,6 @@ __metadata: languageName: node linkType: hard -"jsonfile@npm:^2.1.0": - version: 2.4.0 - resolution: "jsonfile@npm:2.4.0" - dependencies: - graceful-fs: "npm:^4.1.6" - dependenciesMeta: - graceful-fs: - optional: true - checksum: 10c0/02ad746d9490686519b3369bc9572694076eb982e1b4982c5ad9b91bc3c0ad30d10c866bb26b7a87f0c4025a80222cd2962cb57083b5a6a475a9031eab8c8962 - languageName: node - linkType: hard - "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -18357,7 +15751,7 @@ __metadata: languageName: node linkType: hard -"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" dependencies: @@ -18390,24 +15784,6 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": - version: 3.2.2 - resolution: "kind-of@npm:3.2.2" - dependencies: - is-buffer: "npm:^1.1.5" - checksum: 10c0/7e34bc29d4b02c997f92f080de34ebb92033a96736bbb0bb2410e033a7e5ae6571f1fa37b2d7710018f95361473b816c604234197f4f203f9cf149d8ef1574d9 - languageName: node - linkType: hard - -"kind-of@npm:^4.0.0": - version: 4.0.0 - resolution: "kind-of@npm:4.0.0" - dependencies: - is-buffer: "npm:^1.1.5" - checksum: 10c0/d6c44c75ee36898142dfc7106afbd50593216c37f96acb81a7ab33ca1a6938ce97d5692b8fc8fccd035f83811a9d97749d68771116441a48eedd0b68e2973165 - languageName: node - linkType: hard - "kind-of@npm:^5.0.0": version: 5.1.0 resolution: "kind-of@npm:5.1.0" @@ -18438,31 +15814,6 @@ __metadata: languageName: node linkType: hard -"language-subtag-registry@npm:^0.3.20": - version: 0.3.23 - resolution: "language-subtag-registry@npm:0.3.23" - checksum: 10c0/e9b05190421d2cd36dd6c95c28673019c927947cb6d94f40ba7e77a838629ee9675c94accf897fbebb07923187deb843b8fbb8935762df6edafe6c28dcb0b86c - languageName: node - linkType: hard - -"language-tags@npm:^1.0.9": - version: 1.0.9 - resolution: "language-tags@npm:1.0.9" - dependencies: - language-subtag-registry: "npm:^0.3.20" - checksum: 10c0/9ab911213c4bd8bd583c850201c17794e52cb0660d1ab6e32558aadc8324abebf6844e46f92b80a5d600d0fbba7eface2c207bfaf270a1c7fd539e4c3a880bff - languageName: node - linkType: hard - -"latest-version@npm:^3.0.0": - version: 3.1.0 - resolution: "latest-version@npm:3.1.0" - dependencies: - package-json: "npm:^4.0.0" - checksum: 10c0/a850d49d5008e9370e5afc5b2a6bc610c34499b5d9aeaa1cb41e80bfa64a3f666438c65c7d2db6ad3bd62f727d4b805c63e1444bc9c3ad6d51d1c1ebce66758c - languageName: node - linkType: hard - "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -18535,7 +15886,7 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:^3.0.0, lilconfig@npm:^3.1.3": +"lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" checksum: 10c0/f5604e7240c5c275743561442fbc5abf2a84ad94da0f5adc71d25e31fa8483048de3dcedcb7a44112a942fed305fd75841cdf6c9681c7f640c63f1049e9a5dcc @@ -18593,13 +15944,6 @@ __metadata: languageName: node linkType: hard -"lodash-compat@npm:^3.10.0": - version: 3.10.2 - resolution: "lodash-compat@npm:3.10.2" - checksum: 10c0/9546d151acfc3487f825aaa5cf94ac6c32936bee4719ef17ddd3b51a00b589eaef6c06ac68635312887d9d421eed4fd7f8969b25bd883739a92c902b5c2d8086 - languageName: node - linkType: hard - "lodash-es@npm:^4.17.10": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" @@ -18607,175 +15951,6 @@ __metadata: languageName: node linkType: hard -"lodash._arraypool@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._arraypool@npm:2.4.1" - checksum: 10c0/caf2f7b20b288385699df05a29f24d7958c9e47199e15d70c4f5018983a011adabdd7158d635eb91ebc1bdc84c2791dece3f1c8850322c063eeaadeb317f9862 - languageName: node - linkType: hard - -"lodash._basebind@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._basebind@npm:2.4.1" - dependencies: - lodash._basecreate: "npm:~2.4.1" - lodash._setbinddata: "npm:~2.4.1" - lodash._slice: "npm:~2.4.1" - lodash.isobject: "npm:~2.4.1" - checksum: 10c0/b6c0a3ac71ceb39f7b9f636efcfe0a74ddcf24f9e96429ff3e9025db3382e3240bc3c254b0a0f5b7680565c0c5b99ac37b2a69d0370a36c363c19e09e5967857 - languageName: node - linkType: hard - -"lodash._baseclone@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._baseclone@npm:2.4.1" - dependencies: - lodash._getarray: "npm:~2.4.1" - lodash._releasearray: "npm:~2.4.1" - lodash._slice: "npm:~2.4.1" - lodash.assign: "npm:~2.4.1" - lodash.foreach: "npm:~2.4.1" - lodash.forown: "npm:~2.4.1" - lodash.isarray: "npm:~2.4.1" - lodash.isobject: "npm:~2.4.1" - checksum: 10c0/c237e2515f3c39b951be5193c0b7e5ec6421d425d3386818464623fc07c0edb970012e7cd4d103dd69f1838bcb5d89477aad27af95885b2ae2de1d4e0eb2a725 - languageName: node - linkType: hard - -"lodash._basecreate@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._basecreate@npm:2.4.1" - dependencies: - lodash._isnative: "npm:~2.4.1" - lodash.isobject: "npm:~2.4.1" - lodash.noop: "npm:~2.4.1" - checksum: 10c0/b2edb54d55e49ab955294df1c2ea4ffc0c298a4ff7e738dd04e6b2a256272ac052abf4018ee926536ee862290a9694b9e882044085388c3a5acae7228011767d - languageName: node - linkType: hard - -"lodash._basecreatecallback@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._basecreatecallback@npm:2.4.1" - dependencies: - lodash._setbinddata: "npm:~2.4.1" - lodash.bind: "npm:~2.4.1" - lodash.identity: "npm:~2.4.1" - lodash.support: "npm:~2.4.1" - checksum: 10c0/294f15e00ea4fd894fa75e01b0ad9a0829f0f2d2e0623e35ead7848154712df91b48de6cfcf8d4bd54f1cb7d10625b39747782d996667c1b74dd7236adac69b8 - languageName: node - linkType: hard - -"lodash._basecreatewrapper@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._basecreatewrapper@npm:2.4.1" - dependencies: - lodash._basecreate: "npm:~2.4.1" - lodash._setbinddata: "npm:~2.4.1" - lodash._slice: "npm:~2.4.1" - lodash.isobject: "npm:~2.4.1" - checksum: 10c0/ef12e3c74b7cf0b47d4fbd0f58f09053a08553e93decc6c8b6896349a91d56bc05f95b50b18cf303ff07182ddbb05a6d58f536eb8418bfcc37a7c63d29c847e5 - languageName: node - linkType: hard - -"lodash._createwrapper@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._createwrapper@npm:2.4.1" - dependencies: - lodash._basebind: "npm:~2.4.1" - lodash._basecreatewrapper: "npm:~2.4.1" - lodash._slice: "npm:~2.4.1" - lodash.isfunction: "npm:~2.4.1" - checksum: 10c0/79af16e1a987fc74e0b4acc4e4a16cd6ce4c435876c3535eea99bc3cbaefcd5c240c3d0f5777010c4d6918cdf2ca0ba1874bf62c62442c3ba1e815a045421442 - languageName: node - linkType: hard - -"lodash._getarray@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._getarray@npm:2.4.1" - dependencies: - lodash._arraypool: "npm:~2.4.1" - checksum: 10c0/3246969b623b87bd73762bcf19b68e68efaddbb966c9832b9a25932150ee1fa80effa79a93ab90f5ab89b65cbcae22a209a830433a270f7e3595da54228cf33d - languageName: node - linkType: hard - -"lodash._isnative@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._isnative@npm:2.4.1" - checksum: 10c0/4e09ed09e1e52ae81a14b19e1da1a2c98f2dc189feb2ed8d91fd193283a5208099d2840ffdc1aa8d51b0fe766fd4ac828a29724382bc3268fb91735e6345d4b7 - languageName: node - linkType: hard - -"lodash._maxpoolsize@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._maxpoolsize@npm:2.4.1" - checksum: 10c0/6d490a1504fdad9f963c0a67266871355a79101e089a66ea0f6f7a16cf5b14a610068f8a82d636fd6a9f4a7b8fe93965ab8e114c88a116a964a2589a2227c5b3 - languageName: node - linkType: hard - -"lodash._objecttypes@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._objecttypes@npm:2.4.1" - checksum: 10c0/edb72879107c6072d67aa733eebf534c67a1963118f961e18d46834ed33e1d58f11b491b1709f1217cc1b8d4ca5336618ed3994f4f7d89dbd4cef5cc11d7bf73 - languageName: node - linkType: hard - -"lodash._releasearray@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._releasearray@npm:2.4.1" - dependencies: - lodash._arraypool: "npm:~2.4.1" - lodash._maxpoolsize: "npm:~2.4.1" - checksum: 10c0/8d2a97143a733f01dc9928fb79f95847bd879448fd049f9a6d9068cd70921c06a3b2e013e9bb9bbceee1729cef3cd3b2486b72fe8e52a3e3a942d1785552d720 - languageName: node - linkType: hard - -"lodash._setbinddata@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._setbinddata@npm:2.4.1" - dependencies: - lodash._isnative: "npm:~2.4.1" - lodash.noop: "npm:~2.4.1" - checksum: 10c0/3e9a60768b138994c03526357f70a37fa89296aff7ff748f28909fb093b42729b3f8fe5da58d38024a94b982fe14c2f4b55bd337f13ba97803d0e02dd1bcaa22 - languageName: node - linkType: hard - -"lodash._shimkeys@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._shimkeys@npm:2.4.1" - dependencies: - lodash._objecttypes: "npm:~2.4.1" - checksum: 10c0/bd9aa121195bdc515d7af4e282c85d72a764d8107ab83be2f90f8541276bf5f3c8b13e8d31b85ebccb49f52ca688a07cf26139a7f3435011cfa989ab7a368db1 - languageName: node - linkType: hard - -"lodash._slice@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash._slice@npm:2.4.1" - checksum: 10c0/cfc3214cf71f9fd96eb9e61ad71504b4982143fe1f9e9c41122af65fefd4c566d0f6014b8fadaa04d1c56fd8bf8930cc21387663f5432eb2d3e6e84cd7dbacba - languageName: node - linkType: hard - -"lodash.assign@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.assign@npm:2.4.1" - dependencies: - lodash._basecreatecallback: "npm:~2.4.1" - lodash._objecttypes: "npm:~2.4.1" - lodash.keys: "npm:~2.4.1" - checksum: 10c0/ce96af4545ea1e98282faf8f446ff533014b7a142a54a606ea2c3c3369377b8de199365aa2e9098f325a567132db3529894bb220874fd9a25fa049b1bf851c88 - languageName: node - linkType: hard - -"lodash.bind@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.bind@npm:2.4.1" - dependencies: - lodash._createwrapper: "npm:~2.4.1" - lodash._slice: "npm:~2.4.1" - checksum: 10c0/b0b8c7656417e44c257efb0b06c57b1cdd8542682074e6522b99fe67fabfc2fed59c849d6e4746093d9de344adc32f4367edd7806b466ff486350760c26885d9 - languageName: node - linkType: hard - "lodash.camelcase@npm:^4.3.0": version: 4.3.0 resolution: "lodash.camelcase@npm:4.3.0" @@ -18783,16 +15958,6 @@ __metadata: languageName: node linkType: hard -"lodash.clonedeep@npm:^2.4.1": - version: 2.4.1 - resolution: "lodash.clonedeep@npm:2.4.1" - dependencies: - lodash._baseclone: "npm:~2.4.1" - lodash._basecreatecallback: "npm:~2.4.1" - checksum: 10c0/99d416a6a62a284be48f4aa3d6beaec5a22f7e350d23d1708977a22305b8a1b3af07cccadb8dd5a31341c859c4e047490c2d2f942aee40085faff63c15fc0df5 - languageName: node - linkType: hard - "lodash.clonedeep@npm:^4.5.0": version: 4.5.0 resolution: "lodash.clonedeep@npm:4.5.0" @@ -18807,50 +15972,6 @@ __metadata: languageName: node linkType: hard -"lodash.foreach@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.foreach@npm:2.4.1" - dependencies: - lodash._basecreatecallback: "npm:~2.4.1" - lodash.forown: "npm:~2.4.1" - checksum: 10c0/794df75c9d5c44d474359ae19ab472f45890ff1fda8a07c0aaf7e7141417855d671f0f30ce374ae553e13fd708ac38ccad7ac23723108d837280f0dc0887eb05 - languageName: node - linkType: hard - -"lodash.forown@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.forown@npm:2.4.1" - dependencies: - lodash._basecreatecallback: "npm:~2.4.1" - lodash._objecttypes: "npm:~2.4.1" - lodash.keys: "npm:~2.4.1" - checksum: 10c0/a324e538e6ff40dc575e37122eab8b04bdd89919c806ff07af6db40ed8e657efb595cd154e646d7b7f4fec69e2c8587a100f1203516f76dbf7738ee93fad70bb - languageName: node - linkType: hard - -"lodash.get@npm:^4.0.0": - version: 4.4.2 - resolution: "lodash.get@npm:4.4.2" - checksum: 10c0/48f40d471a1654397ed41685495acb31498d5ed696185ac8973daef424a749ca0c7871bf7b665d5c14f5cc479394479e0307e781f61d5573831769593411be6e - languageName: node - linkType: hard - -"lodash.identity@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.identity@npm:2.4.1" - checksum: 10c0/b58784222f0b011e71aa45a7d2ad2f46e6d03f3e2ae96803e0feabd2d8a71e8e76f4686130dc598dc3d4dcbb565d5caef6dfffabfe32e142e624d78f8fa228e4 - languageName: node - linkType: hard - -"lodash.isarray@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.isarray@npm:2.4.1" - dependencies: - lodash._isnative: "npm:~2.4.1" - checksum: 10c0/2b869606580d8fa0e03f47565ed40e1dad4f0fad45c954552444b840de833ec4299e646413f8e83092a6c2aa4cead1c6b29fb3f03aa349861064ce28f7763472 - languageName: node - linkType: hard - "lodash.isempty@npm:^4.4.0": version: 4.4.0 resolution: "lodash.isempty@npm:4.4.0" @@ -18858,7 +15979,7 @@ __metadata: languageName: node linkType: hard -"lodash.isequal@npm:^4.0.0, lodash.isequal@npm:^4.5.0": +"lodash.isequal@npm:^4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" checksum: 10c0/dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f @@ -18872,13 +15993,6 @@ __metadata: languageName: node linkType: hard -"lodash.isfunction@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.isfunction@npm:2.4.1" - checksum: 10c0/727cc623cbcc6dde02e1ea3bd5b08f8a536ba55104d37ba911c90bdbea0f57ca9da673b3ab64869d8b851e800fdc59d78e21262446384147355c47a15e09a72f - languageName: node - linkType: hard - "lodash.isobject@npm:^3.0.2": version: 3.0.2 resolution: "lodash.isobject@npm:3.0.2" @@ -18886,15 +16000,6 @@ __metadata: languageName: node linkType: hard -"lodash.isobject@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.isobject@npm:2.4.1" - dependencies: - lodash._objecttypes: "npm:~2.4.1" - checksum: 10c0/836a7567947bb01c054bdf4f1c8cc533d5dd053362368f16e5e5cdd1c5cfcf0ff219929e911b671cd9ae536f48318e41abb13a3557e5ec33fd400e262cf58792 - languageName: node - linkType: hard - "lodash.isstring@npm:^4.0.1": version: 4.0.1 resolution: "lodash.isstring@npm:4.0.1" @@ -18902,17 +16007,6 @@ __metadata: languageName: node linkType: hard -"lodash.keys@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.keys@npm:2.4.1" - dependencies: - lodash._isnative: "npm:~2.4.1" - lodash._shimkeys: "npm:~2.4.1" - lodash.isobject: "npm:~2.4.1" - checksum: 10c0/73d0e3e29415a4a636d09ca6e5f58d1cf545ea67ade2627c8a86c42fea4744dda9031af25bbd90c32006765a3b9847fb58655f30e046a08553b038f552f6dbff - languageName: node - linkType: hard - "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -18920,22 +16014,6 @@ __metadata: languageName: node linkType: hard -"lodash.noop@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.noop@npm:2.4.1" - checksum: 10c0/d30f7d2cc3d8a162a5c621b1687d3b0428c9a10fe1ce71aa7fae9620d1219de12bff2a3db8c269bf8d22937392541675a307a3012e8b00f992fae6e2eada7c94 - languageName: node - linkType: hard - -"lodash.support@npm:~2.4.1": - version: 2.4.1 - resolution: "lodash.support@npm:2.4.1" - dependencies: - lodash._isnative: "npm:~2.4.1" - checksum: 10c0/6d46ff622c1e01326fa2823d51394b2a221f2fbf463c6b89a28eeb912bd8d3f339b2d307bf58472c4049abfa4e8d1d466df96f8590755113fb1ede3410728f1a - languageName: node - linkType: hard - "lodash.throttle@npm:^4.1.1": version: 4.1.1 resolution: "lodash.throttle@npm:4.1.1" @@ -18950,20 +16028,13 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.12, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": +"lodash@npm:4.17.21, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c languageName: node linkType: hard -"lodash@npm:^3.10.0, lodash@npm:^3.3.1": - version: 3.10.1 - resolution: "lodash@npm:3.10.1" - checksum: 10c0/f5f6d3d87503c3f1db27d49b30a00bb38dc1bd9de716c5febe8970259cc7b447149a0e320452ccaf5996a7a4abd63d94df341bb91bd8d336584ad518d8eab144 - languageName: node - linkType: hard - "log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" @@ -18974,18 +16045,6 @@ __metadata: languageName: node linkType: hard -"logixlysia@npm:^4.1.1": - version: 4.2.7 - resolution: "logixlysia@npm:4.2.7" - dependencies: - chalk: "npm:^5.3.0" - elysia: "npm:^1.1.23" - peerDependencies: - typescript: ^5.2.2 - conditions: (os=darwin | os=linux | os=win32) - languageName: node - linkType: hard - "logkitty@npm:^0.7.1": version: 0.7.1 resolution: "logkitty@npm:0.7.1" @@ -19078,13 +16137,6 @@ __metadata: languageName: node linkType: hard -"lowercase-keys@npm:^1.0.0": - version: 1.0.1 - resolution: "lowercase-keys@npm:1.0.1" - checksum: 10c0/56776a8e1ef1aca98ecf6c19b30352ae1cf257b65b8ac858b7d8a0e8b348774d12a9b41aa7f59bfea51bff44bc7a198ab63ba4406bfba60dba008799618bef66 - languageName: node - linkType: hard - "lowercase-keys@npm:^2.0.0": version: 2.0.0 resolution: "lowercase-keys@npm:2.0.0" @@ -19092,13 +16144,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:2": - version: 2.7.3 - resolution: "lru-cache@npm:2.7.3" - checksum: 10c0/699702a9e374fd48cb507c55ecf655409337b3f6356a78e620e64e34c675bd988377fd4e3bb1db6e05a03b10e1758ba55877ca90a01c8d7ab2bea05cc49190d8 - languageName: node - linkType: hard - "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -19106,16 +16151,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^4.0.1": - version: 4.1.5 - resolution: "lru-cache@npm:4.1.5" - dependencies: - pseudomap: "npm:^1.0.2" - yallist: "npm:^2.1.2" - checksum: 10c0/1ca5306814e5add9ec63556d6fd9b24a4ecdeaef8e9cea52cbf30301e6b88c8d8ddc7cab45b59b56eb763e6c45af911585dc89925a074ab65e1502e3fe8103cf - languageName: node - linkType: hard - "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -19148,15 +16183,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^1.0.0": - version: 1.3.0 - resolution: "make-dir@npm:1.3.0" - dependencies: - pify: "npm:^3.0.0" - checksum: 10c0/5eb94f47d7ef41d89d1b8eef6539b8950d5bd99eeba093a942bfd327faa37d2d62227526b88b73633243a2ec7972d21eb0f4e5d62ae4e02a79e389f4a7bb3022 - languageName: node - linkType: hard - "make-dir@npm:^2.0.0, make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" @@ -19211,22 +16237,6 @@ __metadata: languageName: node linkType: hard -"map-cache@npm:^0.2.2": - version: 0.2.2 - resolution: "map-cache@npm:0.2.2" - checksum: 10c0/05e3eb005c1b80b9f949ca007687640e8c5d0fc88dc45c3c3ab4902a3bec79d66a58f3e3b04d6985d90cd267c629c7b46c977e9c34433e8c11ecfcbb9f0fa290 - languageName: node - linkType: hard - -"map-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "map-visit@npm:1.0.0" - dependencies: - object-visit: "npm:^1.0.0" - checksum: 10c0/fb3475e5311939a6147e339999113db607adc11c7c3cd3103e5e9dbf502898416ecba6b1c7c649c6d4d12941de00cee58b939756bdf20a9efe7d4fa5a5738b73 - languageName: node - linkType: hard - "markdown-table@npm:^1.1.3": version: 1.1.3 resolution: "markdown-table@npm:1.1.3" @@ -19259,17 +16269,6 @@ __metadata: languageName: node linkType: hard -"md5@npm:~2.2.0": - version: 2.2.1 - resolution: "md5@npm:2.2.1" - dependencies: - charenc: "npm:~0.0.1" - crypt: "npm:~0.0.1" - is-buffer: "npm:~1.1.1" - checksum: 10c0/e9e7de197a100169f27b956af63ece22348b2d06d40162c8d380d13dcbb7a307c95956857d0cb5ed92059f6448bbdce2d54bc6b922f8e6a36284c303ecc1612d - languageName: node - linkType: hard - "mdn-data@npm:2.0.14": version: 2.0.14 resolution: "mdn-data@npm:2.0.14" @@ -19291,13 +16290,6 @@ __metadata: languageName: node linkType: hard -"media-typer@npm:0.3.0": - version: 0.3.0 - resolution: "media-typer@npm:0.3.0" - checksum: 10c0/d160f31246907e79fed398470285f21bafb45a62869dc469b1c8877f3f064f5eabc4bcc122f9479b8b605bc5c76187d7871cf84c4ee3ecd3e487da1993279928 - languageName: node - linkType: hard - "memoize-one@npm:^5.0.0": version: 5.2.1 resolution: "memoize-one@npm:5.2.1" @@ -19305,13 +16297,6 @@ __metadata: languageName: node linkType: hard -"memory-cache@npm:~0.2.0": - version: 0.2.0 - resolution: "memory-cache@npm:0.2.0" - checksum: 10c0/d4fe58865dfdc252db18ae152ab6c9d62868cfc42d5e7f6cf30732fcf27f5f1f8d7b179c3b6f26f31a28ab1cc5c3937215c60aa9e8ad7ea8ff35e79f69ef14da - languageName: node - linkType: hard - "memorystream@npm:^0.3.1": version: 0.3.1 resolution: "memorystream@npm:0.3.1" @@ -19342,13 +16327,6 @@ __metadata: languageName: node linkType: hard -"methods@npm:^1.1.2, methods@npm:~1.1.1": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 10c0/bdf7cc72ff0a33e3eede03708c08983c4d7a173f91348b4b1e4f47d4cdbf734433ad971e7d1e8c77247d9e5cd8adb81ea4c67b0a2db526b758b2233d7814b8b2 - languageName: node - linkType: hard - "metro-babel-transformer@npm:0.80.12": version: 0.80.12 resolution: "metro-babel-transformer@npm:0.80.12" @@ -19833,27 +16811,6 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^3.1.10, micromatch@npm:^3.1.4": - version: 3.1.10 - resolution: "micromatch@npm:3.1.10" - dependencies: - arr-diff: "npm:^4.0.0" - array-unique: "npm:^0.3.2" - braces: "npm:^2.3.1" - define-property: "npm:^2.0.2" - extend-shallow: "npm:^3.0.2" - extglob: "npm:^2.0.4" - fragment-cache: "npm:^0.2.1" - kind-of: "npm:^6.0.2" - nanomatch: "npm:^1.2.9" - object.pick: "npm:^1.3.0" - regex-not: "npm:^1.0.0" - snapdragon: "npm:^0.8.1" - to-regex: "npm:^3.0.2" - checksum: 10c0/531a32e7ac92bef60657820202be71b63d0f945c08a69cc4c239c0b19372b751483d464a850a2e3a5ff6cc9060641e43d44c303af104c1a27493d137d8af017f - languageName: node - linkType: hard - "micromatch@npm:^4.0.0, micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" @@ -19878,7 +16835,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.3, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.35, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -19887,15 +16844,6 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.3.4": - version: 1.3.4 - resolution: "mime@npm:1.3.4" - bin: - mime: cli.js - checksum: 10c0/06ca13fe3be58eedfadc4351ca735c19ad25f2f8f0ecc746c1b2e780934829cc0e4b303269f0abfc919ecb6f149f1b648700f996d2b7935fb23208f7357438d4 - languageName: node - linkType: hard - "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -19905,7 +16853,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:2.6.0, mime@npm:^2.4.1": +"mime@npm:^2.4.1": version: 2.6.0 resolution: "mime@npm:2.6.0" bin: @@ -19956,16 +16904,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:0.3": - version: 0.3.0 - resolution: "minimatch@npm:0.3.0" - dependencies: - lru-cache: "npm:2" - sigmund: "npm:~1.0.0" - checksum: 10c0/c9809c0f0bb04b9af8f3bdf3d0c285e94c3b08a961d4916e22bc89d1f94771a98af7e22accc9622fb4cd543c6028882ab38fdaa22f4d8ee7026b7aa6670425e4 - languageName: node - linkType: hard - "minimatch@npm:2 || 3, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -19975,15 +16913,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - "minimatch@npm:^5.0.1, minimatch@npm:^5.1.6": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -19993,7 +16922,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -20002,13 +16931,6 @@ __metadata: languageName: node linkType: hard -"minimist@npm:0.0.8": - version: 0.0.8 - resolution: "minimist@npm:0.0.8" - checksum: 10c0/d0a998c3042922dbcd5f23566b52811d6977649ad089fd75dd89e8a9bff27634194900818b2dfb1b873f204edb902d0c8cdea9cb8dca8488b301f69bd522d5dc - languageName: node - linkType: hard - "minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -20116,16 +17038,6 @@ __metadata: languageName: node linkType: hard -"mixin-deep@npm:^1.2.0": - version: 1.3.2 - resolution: "mixin-deep@npm:1.3.2" - dependencies: - for-in: "npm:^1.0.2" - is-extendable: "npm:^1.0.1" - checksum: 10c0/cb39ffb73c377222391af788b4c83d1a6cecb2d9fceb7015384f8deb46e151a9b030c21ef59a79cb524d4557e3f74c7248ab948a62a6e7e296b42644863d183b - languageName: node - linkType: hard - "mixin-object@npm:^2.0.1": version: 2.0.1 resolution: "mixin-object@npm:2.0.1" @@ -20136,25 +17048,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:0.3.0": - version: 0.3.0 - resolution: "mkdirp@npm:0.3.0" - checksum: 10c0/cd9e54878490571df79770de1cdceba48ab6682c004616666d23a38315feaf5822d443aeb500ac298a12d7f6f5e11dc05cea3207d500e547d938218bf22d8629 - languageName: node - linkType: hard - -"mkdirp@npm:0.5.1": - version: 0.5.1 - resolution: "mkdirp@npm:0.5.1" - dependencies: - minimist: "npm:0.0.8" - bin: - mkdirp: bin/cmd.js - checksum: 10c0/e5ff572d761240a06dbfc69e1ea303d5482815a1f66033b999bd9d78583fcdc9ef63e99e61d396bbd57eca45b388af80a7f7f35f63510619c991c9d44c75341c - languageName: node - linkType: hard - -"mkdirp@npm:0.5.x, mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.4": +"mkdirp@npm:0.5.x, mkdirp@npm:^0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -20223,27 +17117,6 @@ __metadata: languageName: node linkType: hard -"mocha@npm:^2.2.1": - version: 2.5.3 - resolution: "mocha@npm:2.5.3" - dependencies: - commander: "npm:2.3.0" - debug: "npm:2.2.0" - diff: "npm:1.4.0" - escape-string-regexp: "npm:1.0.2" - glob: "npm:3.2.11" - growl: "npm:1.9.2" - jade: "npm:0.26.3" - mkdirp: "npm:0.5.1" - supports-color: "npm:1.2.0" - to-iso-string: "npm:0.0.2" - bin: - _mocha: ./bin/_mocha - mocha: ./bin/mocha - checksum: 10c0/9d9b4097b592f7409973d347ecb6cbd82475135cb81e3198be94703353cc9c6bae9d4116db621fb084d7dcc0858db477b46dd54b4a56b2f696296afe5a56a559 - languageName: node - linkType: hard - "mochawesome-report-generator@npm:^6.2.0": version: 6.2.0 resolution: "mochawesome-report-generator@npm:6.2.0" @@ -20306,20 +17179,6 @@ __metadata: languageName: node linkType: hard -"mpath@npm:~0.5.0": - version: 0.5.2 - resolution: "mpath@npm:0.5.2" - checksum: 10c0/ff624fc83925e0661b70d49902903e1e859b08faaef22ce7bdb6497f8cf2665a56c2877c72be7079aa253f37055058610520b35245c0d545185ffcdc2b85603e - languageName: node - linkType: hard - -"ms@npm:0.7.1": - version: 0.7.1 - resolution: "ms@npm:0.7.1" - checksum: 10c0/caeb29c1eef02d38f03781d1937a59ddef897be8686c146507a9d33cda7fa4de678d0c6091f8ce7e45bf35585e655d398d9d5103e5197fd919643c46356887cc - languageName: node - linkType: hard - "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -20334,7 +17193,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": +"ms@npm:2.1.3, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -20355,49 +17214,6 @@ __metadata: languageName: node linkType: hard -"multer@npm:^1.1.0": - version: 1.4.4 - resolution: "multer@npm:1.4.4" - dependencies: - append-field: "npm:^1.0.0" - busboy: "npm:^0.2.11" - concat-stream: "npm:^1.5.2" - mkdirp: "npm:^0.5.4" - object-assign: "npm:^4.1.1" - on-finished: "npm:^2.3.0" - type-is: "npm:^1.6.4" - xtend: "npm:^4.0.0" - checksum: 10c0/ae7505b440b833bffe4d4b712659fc880b3a3735db1190745e738138b069b2344d0d17e3985c93f0aee287d795572dbb7a90af31ec33bd1293cbf90366934b7b - languageName: node - linkType: hard - -"mute-stream@npm:0.0.5": - version: 0.0.5 - resolution: "mute-stream@npm:0.0.5" - checksum: 10c0/562d334db46e4334f473e9e9c4993df7227fa1ba0c3f7eb453e1db666b0f0e3be45315b4d01bfa722784752e51acf72e37bb982d0bd2768fe6a431eb4dbb17ab - languageName: node - linkType: hard - -"mz@npm:^2.7.0": - version: 2.7.0 - resolution: "mz@npm:2.7.0" - dependencies: - any-promise: "npm:^1.0.0" - object-assign: "npm:^4.0.1" - thenify-all: "npm:^1.0.0" - checksum: 10c0/103114e93f87362f0b56ab5b2e7245051ad0276b646e3902c98397d18bb8f4a77f2ea4a2c9d3ad516034ea3a56553b60d3f5f78220001ca4c404bd711bd0af39 - languageName: node - linkType: hard - -"nan@npm:^2.12.1": - version: 2.22.2 - resolution: "nan@npm:2.22.2" - dependencies: - node-gyp: "npm:latest" - checksum: 10c0/971f963b8120631880fa47a389c71b00cadc1c1b00ef8f147782a3f4387d4fc8195d0695911272d57438c11562fb27b24c4ae5f8c05d5e4eeb4478ba51bb73c5 - languageName: node - linkType: hard - "nanoassert@npm:^2.0.0": version: 2.0.0 resolution: "nanoassert@npm:2.0.0" @@ -20414,7 +17230,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.11, nanoid@npm:^3.3.6, nanoid@npm:^3.3.8": +"nanoid@npm:^3.3.11": version: 3.3.11 resolution: "nanoid@npm:3.3.11" bin: @@ -20423,7 +17239,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^5.1.0, nanoid@npm:^5.1.5": +"nanoid@npm:^5.1.0": version: 5.1.5 resolution: "nanoid@npm:5.1.5" bin: @@ -20432,25 +17248,6 @@ __metadata: languageName: node linkType: hard -"nanomatch@npm:^1.2.9": - version: 1.2.13 - resolution: "nanomatch@npm:1.2.13" - dependencies: - arr-diff: "npm:^4.0.0" - array-unique: "npm:^0.3.2" - define-property: "npm:^2.0.2" - extend-shallow: "npm:^3.0.2" - fragment-cache: "npm:^0.2.1" - is-windows: "npm:^1.0.2" - kind-of: "npm:^6.0.2" - object.pick: "npm:^1.3.0" - regex-not: "npm:^1.0.0" - snapdragon: "npm:^0.8.1" - to-regex: "npm:^3.0.1" - checksum: 10c0/0f5cefa755ca2e20c86332821995effb24acb79551ddaf51c1b9112628cad234a0d8fd9ac6aa56ad1f8bfad6ff6ae86e851acb960943249d9fa44b091479953a - languageName: node - linkType: hard - "nanospinner@npm:^1.2.2": version: 1.2.2 resolution: "nanospinner@npm:1.2.2" @@ -20460,22 +17257,6 @@ __metadata: languageName: node linkType: hard -"napi-postinstall@npm:^0.2.2": - version: 0.2.4 - resolution: "napi-postinstall@npm:0.2.4" - bin: - napi-postinstall: lib/cli.js - checksum: 10c0/e8c357d7e27848c4af7becf2796afff245a2fc8ba176e1b133410bb1c9934a66d4bc542d0c9f04c73b0ba34ee0486b30b6cd1c62ed3aa36797d394200c9a2a8b - languageName: node - linkType: hard - -"native-promise-only@npm:^0.8.1": - version: 0.8.1 - resolution: "native-promise-only@npm:0.8.1" - checksum: 10c0/c1b41128ca9806818e12d0b84f7c71e88b1fa00f0f4857767d96206dbdd0af6755305103f55c583b045533185ffca863b0c34116ade507ff7ba2e417e076a5ac - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -20533,122 +17314,6 @@ __metadata: languageName: node linkType: hard -"next@npm:14.2.8": - version: 14.2.8 - resolution: "next@npm:14.2.8" - dependencies: - "@next/env": "npm:14.2.8" - "@next/swc-darwin-arm64": "npm:14.2.8" - "@next/swc-darwin-x64": "npm:14.2.8" - "@next/swc-linux-arm64-gnu": "npm:14.2.8" - "@next/swc-linux-arm64-musl": "npm:14.2.8" - "@next/swc-linux-x64-gnu": "npm:14.2.8" - "@next/swc-linux-x64-musl": "npm:14.2.8" - "@next/swc-win32-arm64-msvc": "npm:14.2.8" - "@next/swc-win32-ia32-msvc": "npm:14.2.8" - "@next/swc-win32-x64-msvc": "npm:14.2.8" - "@swc/helpers": "npm:0.5.5" - busboy: "npm:1.6.0" - caniuse-lite: "npm:^1.0.30001579" - graceful-fs: "npm:^4.2.11" - postcss: "npm:8.4.31" - styled-jsx: "npm:5.1.1" - peerDependencies: - "@opentelemetry/api": ^1.1.0 - "@playwright/test": ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - dependenciesMeta: - "@next/swc-darwin-arm64": - optional: true - "@next/swc-darwin-x64": - optional: true - "@next/swc-linux-arm64-gnu": - optional: true - "@next/swc-linux-arm64-musl": - optional: true - "@next/swc-linux-x64-gnu": - optional: true - "@next/swc-linux-x64-musl": - optional: true - "@next/swc-win32-arm64-msvc": - optional: true - "@next/swc-win32-ia32-msvc": - optional: true - "@next/swc-win32-x64-msvc": - optional: true - peerDependenciesMeta: - "@opentelemetry/api": - optional: true - "@playwright/test": - optional: true - sass: - optional: true - bin: - next: dist/bin/next - checksum: 10c0/ceead5258f80dc2a4e911cb3e8c224ce5487c726587a79ea0a510192305f2e66a17a002841c3c0b195fd568c9a35160f563042417d3807eb5f6538c7630615de - languageName: node - linkType: hard - -"next@npm:^14.2.8": - version: 14.2.29 - resolution: "next@npm:14.2.29" - dependencies: - "@next/env": "npm:14.2.29" - "@next/swc-darwin-arm64": "npm:14.2.29" - "@next/swc-darwin-x64": "npm:14.2.29" - "@next/swc-linux-arm64-gnu": "npm:14.2.29" - "@next/swc-linux-arm64-musl": "npm:14.2.29" - "@next/swc-linux-x64-gnu": "npm:14.2.29" - "@next/swc-linux-x64-musl": "npm:14.2.29" - "@next/swc-win32-arm64-msvc": "npm:14.2.29" - "@next/swc-win32-ia32-msvc": "npm:14.2.29" - "@next/swc-win32-x64-msvc": "npm:14.2.29" - "@swc/helpers": "npm:0.5.5" - busboy: "npm:1.6.0" - caniuse-lite: "npm:^1.0.30001579" - graceful-fs: "npm:^4.2.11" - postcss: "npm:8.4.31" - styled-jsx: "npm:5.1.1" - peerDependencies: - "@opentelemetry/api": ^1.1.0 - "@playwright/test": ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - dependenciesMeta: - "@next/swc-darwin-arm64": - optional: true - "@next/swc-darwin-x64": - optional: true - "@next/swc-linux-arm64-gnu": - optional: true - "@next/swc-linux-arm64-musl": - optional: true - "@next/swc-linux-x64-gnu": - optional: true - "@next/swc-linux-x64-musl": - optional: true - "@next/swc-win32-arm64-msvc": - optional: true - "@next/swc-win32-ia32-msvc": - optional: true - "@next/swc-win32-x64-msvc": - optional: true - peerDependenciesMeta: - "@opentelemetry/api": - optional: true - "@playwright/test": - optional: true - sass: - optional: true - bin: - next: dist/bin/next - checksum: 10c0/369a56f09f337804325c4049fac7ae1609717b8e3317c5f4fb9f59b29a682bcf37aaaa7e50ad5251f9ffef60a4450b976644d053a951548b15f428d861514d49 - languageName: node - linkType: hard - "no-case@npm:^3.0.4": version: 3.0.4 resolution: "no-case@npm:3.0.4" @@ -20798,26 +17463,6 @@ __metadata: languageName: node linkType: hard -"nodemon@npm:^1.3.7": - version: 1.19.4 - resolution: "nodemon@npm:1.19.4" - dependencies: - chokidar: "npm:^2.1.8" - debug: "npm:^3.2.6" - ignore-by-default: "npm:^1.0.1" - minimatch: "npm:^3.0.4" - pstree.remy: "npm:^1.1.7" - semver: "npm:^5.7.1" - supports-color: "npm:^5.5.0" - touch: "npm:^3.1.0" - undefsafe: "npm:^2.0.2" - update-notifier: "npm:^2.5.0" - bin: - nodemon: ./bin/nodemon.js - checksum: 10c0/4337afa4848c4809de89d6b4f14b9c3ee2374d4b7cd9ae6e2efaf08cc0245fdd69937874a66d54ee642f9ce9a413a14f49b496fd768036ce64939b924f1dcaf7 - languageName: node - linkType: hard - "nofilter@npm:^3.1.0": version: 3.1.0 resolution: "nofilter@npm:3.1.0" @@ -20847,15 +17492,6 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^2.1.1": - version: 2.1.1 - resolution: "normalize-path@npm:2.1.1" - dependencies: - remove-trailing-separator: "npm:^1.0.1" - checksum: 10c0/db814326ff88057437233361b4c7e9cac7b54815b051b57f2d341ce89b1d8ec8cbd43e7fa95d7652b3b69ea8fcc294b89b8530d556a84d1bdace94229e1e9a8b - languageName: node - linkType: hard - "normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" @@ -20870,15 +17506,6 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^2.0.0": - version: 2.0.2 - resolution: "npm-run-path@npm:2.0.2" - dependencies: - path-key: "npm:^2.0.0" - checksum: 10c0/95549a477886f48346568c97b08c4fda9cdbf7ce8a4fbc2213f36896d0d19249e32d68d7451bdcbca8041b5fba04a6b2c4a618beaf19849505c05b700740f1de - languageName: node - linkType: hard - "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -20904,13 +17531,6 @@ __metadata: languageName: node linkType: hard -"number-is-nan@npm:^1.0.0": - version: 1.0.1 - resolution: "number-is-nan@npm:1.0.1" - checksum: 10c0/cb97149006acc5cd512c13c1838223abdf202e76ddfa059c5e8e7507aff2c3a78cd19057516885a2f6f5b576543dc4f7b6f3c997cc7df53ae26c260855466df5 - languageName: node - linkType: hard - "number-to-bn@npm:1.7.0": version: 1.7.0 resolution: "number-to-bn@npm:1.7.0" @@ -20939,31 +17559,13 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 languageName: node linkType: hard -"object-copy@npm:^0.1.0": - version: 0.1.0 - resolution: "object-copy@npm:0.1.0" - dependencies: - copy-descriptor: "npm:^0.1.0" - define-property: "npm:^0.2.5" - kind-of: "npm:^3.0.3" - checksum: 10c0/79314b05e9d626159a04f1d913f4c4aba9eae8848511cf5f4c8e3b04bb3cc313b65f60357f86462c959a14c2d58380fedf89b6b32ecec237c452a5ef3900a293 - languageName: node - linkType: hard - -"object-hash@npm:^3.0.0": - version: 3.0.0 - resolution: "object-hash@npm:3.0.0" - checksum: 10c0/a06844537107b960c1c8b96cd2ac8592a265186bfa0f6ccafe0d34eabdb526f6fa81da1f37c43df7ed13b12a4ae3457a16071603bcd39d8beddb5f08c37b0f47 - languageName: node - linkType: hard - "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -20978,15 +17580,6 @@ __metadata: languageName: node linkType: hard -"object-visit@npm:^1.0.0": - version: 1.0.1 - resolution: "object-visit@npm:1.0.1" - dependencies: - isobject: "npm:^3.0.0" - checksum: 10c0/086b475bda24abd2318d2b187c3e928959b89f5cb5883d6fe5a42d03719b61fc18e765f658de9ac8730e67ba9ff26d61e73d991215948ff9ecefe771e0071029 - languageName: node - linkType: hard - "object.assign@npm:^4.1.4, object.assign@npm:^4.1.7": version: 4.1.7 resolution: "object.assign@npm:4.1.7" @@ -21040,27 +17633,7 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.3": - version: 1.0.3 - resolution: "object.groupby@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - checksum: 10c0/60d0455c85c736fbfeda0217d1a77525956f76f7b2495edeca9e9bbf8168a45783199e77b894d30638837c654d0cc410e0e02cbfcf445bc8de71c3da1ede6a9c - languageName: node - linkType: hard - -"object.pick@npm:^1.3.0": - version: 1.3.0 - resolution: "object.pick@npm:1.3.0" - dependencies: - isobject: "npm:^3.0.1" - checksum: 10c0/cd316ec986e49895a28f2df9182de9cdeee57cd2a952c122aacc86344c28624fe002d9affc4f48b5014ec7c033da9942b08821ddb44db8c5bac5b3ec54bdc31e - languageName: node - linkType: hard - -"object.values@npm:^1.0.3, object.values@npm:^1.1.6, object.values@npm:^1.2.0, object.values@npm:^1.2.1": +"object.values@npm:^1.0.3, object.values@npm:^1.1.6, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" dependencies: @@ -21079,14 +17652,7 @@ __metadata: languageName: node linkType: hard -"obuf@npm:~1.1.2": - version: 1.1.2 - resolution: "obuf@npm:1.1.2" - checksum: 10c0/520aaac7ea701618eacf000fc96ae458e20e13b0569845800fc582f81b386731ab22d55354b4915d58171db00e79cfcd09c1638c02f89577ef092b38c65b7d81 - languageName: node - linkType: hard - -"on-finished@npm:2.4.1, on-finished@npm:^2.3.0": +"on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -21095,15 +17661,6 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:~2.2.1": - version: 2.2.1 - resolution: "on-finished@npm:2.2.1" - dependencies: - ee-first: "npm:1.1.0" - checksum: 10c0/e7a73549a4c658b62e5cca495385557c7338a5d858cd81981ecb39011a0731497747b846e74f926ae8139bebc955e61c1f4c1ea09a146af9220e41a9ffe6a3d9 - languageName: node - linkType: hard - "on-finished@npm:~2.3.0": version: 2.3.0 resolution: "on-finished@npm:2.3.0" @@ -21129,13 +17686,6 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^1.0.0": - version: 1.1.0 - resolution: "onetime@npm:1.1.0" - checksum: 10c0/612a15af7966d9df486fe7a91da115b383137f3794709785deb13ecbcabbd9ad1fa983f4ba1f6076c143d454a7da5e6590e8da4d411ff7f06c8a180eb45011f5 - languageName: node - linkType: hard - "onetime@npm:^5.1.0, onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" @@ -21175,13 +17725,6 @@ __metadata: languageName: node linkType: hard -"openapi-types@npm:^12.1.3": - version: 12.1.3 - resolution: "openapi-types@npm:12.1.3" - checksum: 10c0/4ad4eb91ea834c237edfa6ab31394e87e00c888fc2918009763389c00d02342345195d6f302d61c3fd807f17723cd48df29b47b538b68375b3827b3758cd520f - languageName: node - linkType: hard - "opencollective-postinstall@npm:^2.0.3": version: 2.0.3 resolution: "opencollective-postinstall@npm:2.0.3" @@ -21270,27 +17813,6 @@ __metadata: languageName: node linkType: hard -"ox@npm:0.7.1": - version: 0.7.1 - resolution: "ox@npm:0.7.1" - dependencies: - "@adraffy/ens-normalize": "npm:^1.10.1" - "@noble/ciphers": "npm:^1.3.0" - "@noble/curves": "npm:^1.6.0" - "@noble/hashes": "npm:^1.5.0" - "@scure/bip32": "npm:^1.5.0" - "@scure/bip39": "npm:^1.4.0" - abitype: "npm:^1.0.6" - eventemitter3: "npm:5.0.1" - peerDependencies: - typescript: ">=5.4.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/15370d76f7e5fe1b06c5b9986bc709a8c433e4242660900b3d1adb2a56c8f762a2010a9166bdb95bdf531806cde7891911456c7ec8ba135fc232a5d5037ac673 - languageName: node - linkType: hard - "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -21298,13 +17820,6 @@ __metadata: languageName: node linkType: hard -"p-finally@npm:^1.0.0": - version: 1.0.0 - resolution: "p-finally@npm:1.0.0" - checksum: 10c0/6b8552339a71fe7bd424d01d8451eea92d379a711fc62f6b2fe64cad8a472c7259a236c9a22b4733abca0b5666ad503cb497792a0478c5af31ded793d00937e7 - languageName: node - linkType: hard - "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -21406,18 +17921,6 @@ __metadata: languageName: node linkType: hard -"package-json@npm:^4.0.0": - version: 4.0.1 - resolution: "package-json@npm:4.0.1" - dependencies: - got: "npm:^6.7.1" - registry-auth-token: "npm:^3.0.1" - registry-url: "npm:^3.0.3" - semver: "npm:^5.1.0" - checksum: 10c0/e3c213b9764547024dd80bb7913dada29f487de1dd3d24ef63c152d661cb75ae28ccd965bac3b9e33d0cdaf7cfe2527995e8d00b9e9e2973b7c53bf19ce522a3 - languageName: node - linkType: hard - "pako@npm:^2.1.0": version: 2.1.0 resolution: "pako@npm:2.1.0" @@ -21451,7 +17954,7 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": +"parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -21463,20 +17966,13 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.0, parseurl@npm:~1.3.3": +"parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 languageName: node linkType: hard -"pascalcase@npm:^0.1.1": - version: 0.1.1 - resolution: "pascalcase@npm:0.1.1" - checksum: 10c0/48dfe90618e33810bf58211d8f39ad2c0262f19ad6354da1ba563935b5f429f36409a1fb9187c220328f7a4dc5969917f8e3e01ee089b5f1627b02aefe39567b - languageName: node - linkType: hard - "patch-package@npm:^8.0.0": version: 8.0.0 resolution: "patch-package@npm:8.0.0" @@ -21502,7 +17998,7 @@ __metadata: languageName: node linkType: hard -"path-dirname@npm:^1.0.0, path-dirname@npm:^1.0.2": +"path-dirname@npm:^1.0.2": version: 1.0.2 resolution: "path-dirname@npm:1.0.2" checksum: 10c0/71e59be2bada7c91f62b976245fd421b7cb01fde3207fe53a82d8880621ad04fd8b434e628c9cf4e796259fc168a107d77cd56837725267c5b2c58cefe2c4e1b @@ -21530,20 +18026,6 @@ __metadata: languageName: node linkType: hard -"path-is-inside@npm:^1.0.1": - version: 1.0.2 - resolution: "path-is-inside@npm:1.0.2" - checksum: 10c0/7fdd4b41672c70461cce734fc222b33e7b447fa489c7c4377c95e7e6852d83d69741f307d88ec0cc3b385b41cb4accc6efac3c7c511cd18512e95424f5fa980c - languageName: node - linkType: hard - -"path-key@npm:^2.0.0": - version: 2.0.1 - resolution: "path-key@npm:2.0.1" - checksum: 10c0/dd2044f029a8e58ac31d2bf34c34b93c3095c1481942960e84dd2faa95bbb71b9b762a106aead0646695330936414b31ca0bd862bf488a937ad17c8c5d73b32b - languageName: node - linkType: hard - "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -21551,16 +18033,6 @@ __metadata: languageName: node linkType: hard -"path-loader@npm:^1.0.2": - version: 1.0.12 - resolution: "path-loader@npm:1.0.12" - dependencies: - native-promise-only: "npm:^0.8.1" - superagent: "npm:^7.1.6" - checksum: 10c0/e559ed3694264e43501a0ed6f905307c282fe65197a918f3963fb81f1c570bd979d157339e86527fad57b220446a84a5ed512b186703f0c6080f2fa858e91ada - languageName: node - linkType: hard - "path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" @@ -21568,7 +18040,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1, path-scurry@npm:^1.11.1": +"path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" dependencies: @@ -21578,15 +18050,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^1.2.0": - version: 1.9.0 - resolution: "path-to-regexp@npm:1.9.0" - dependencies: - isarray: "npm:0.0.1" - checksum: 10c0/de9ddb01b84d9c2c8e2bed18630d8d039e2d6f60a6538595750fa08c7a6482512257464c8da50616f266ab2cdd2428387e85f3b089e4c3f25d0c537e898a0751 - languageName: node - linkType: hard - "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -21604,13 +18067,6 @@ __metadata: languageName: node linkType: hard -"pathe@npm:^1.1.2": - version: 1.1.2 - resolution: "pathe@npm:1.1.2" - checksum: 10c0/64ee0a4e587fb0f208d9777a6c56e4f9050039268faaaaecd50e959ef01bf847b7872785c36483fa5cdcdbdfdb31fef2ff222684d4fc21c330ab60395c681897 - languageName: node - linkType: hard - "pathval@npm:^1.1.1": version: 1.1.1 resolution: "pathval@npm:1.1.1" @@ -21645,109 +18101,6 @@ __metadata: languageName: node linkType: hard -"pg-cloudflare@npm:^1.2.5": - version: 1.2.5 - resolution: "pg-cloudflare@npm:1.2.5" - checksum: 10c0/48b9105ef027c7b3f57ef88ceaec3634cd82120059bd68273cce06989a1ec547e0b0fbb5d1afdd0711824f409c8b410f9bdec2f6c8034728992d3658c0b36f86 - languageName: node - linkType: hard - -"pg-connection-string@npm:^2.9.0": - version: 2.9.0 - resolution: "pg-connection-string@npm:2.9.0" - checksum: 10c0/7145d00688200685a9d9931a7fc8d61c75f348608626aef88080ece956ceb4ff1cbdee29c3284e41b7a3345bab0e4f50f9edc256e270bfa3a563af4ea78bb490 - languageName: node - linkType: hard - -"pg-int8@npm:1.0.1": - version: 1.0.1 - resolution: "pg-int8@npm:1.0.1" - checksum: 10c0/be6a02d851fc2a4ae3e9de81710d861de3ba35ac927268973eb3cb618873a05b9424656df464dd43bd7dc3fc5295c3f5b3c8349494f87c7af50ec59ef14e0b98 - languageName: node - linkType: hard - -"pg-numeric@npm:1.0.2": - version: 1.0.2 - resolution: "pg-numeric@npm:1.0.2" - checksum: 10c0/43dd9884e7b52c79ddc28d2d282d7475fce8bba13452d33c04ceb2e0a65f561edf6699694e8e1c832ff9093770496363183c950dd29608e1bdd98f344b25bca9 - languageName: node - linkType: hard - -"pg-pool@npm:^3.10.0": - version: 3.10.0 - resolution: "pg-pool@npm:3.10.0" - peerDependencies: - pg: ">=8.0" - checksum: 10c0/b36162dc98c0ad88cd26f3d65f3e3932c3f870abe7a88905f16fc98282e8131692903e482720ebc9698cb08851c9b19242ff16a50af7f9434c8bb0b5d33a9a9a - languageName: node - linkType: hard - -"pg-protocol@npm:*, pg-protocol@npm:^1.10.0": - version: 1.10.0 - resolution: "pg-protocol@npm:1.10.0" - checksum: 10c0/7d0d64fe9df50262d907fd476454e1e36f41f5f66044c3ba6aa773fb8add1d350a9c162306e5c33e99bdfbdcc1140dd4ca74f66eda41d0aaceb5853244dcdb65 - languageName: node - linkType: hard - -"pg-types@npm:2.2.0": - version: 2.2.0 - resolution: "pg-types@npm:2.2.0" - dependencies: - pg-int8: "npm:1.0.1" - postgres-array: "npm:~2.0.0" - postgres-bytea: "npm:~1.0.0" - postgres-date: "npm:~1.0.4" - postgres-interval: "npm:^1.1.0" - checksum: 10c0/ab3f8069a323f601cd2d2279ca8c425447dab3f9b61d933b0601d7ffc00d6200df25e26a4290b2b0783b59278198f7dd2ed03e94c4875797919605116a577c65 - languageName: node - linkType: hard - -"pg-types@npm:^4.0.1": - version: 4.0.2 - resolution: "pg-types@npm:4.0.2" - dependencies: - pg-int8: "npm:1.0.1" - pg-numeric: "npm:1.0.2" - postgres-array: "npm:~3.0.1" - postgres-bytea: "npm:~3.0.0" - postgres-date: "npm:~2.1.0" - postgres-interval: "npm:^3.0.0" - postgres-range: "npm:^1.1.1" - checksum: 10c0/780fccda2f3fa2a34e85a72e8e7dadb7d88fbe71ce88f126cb3313f333ad836d02488ec4ff3d94d0c1e5846f735d6e6c6281f8059e6b8919d2180429acaec3e2 - languageName: node - linkType: hard - -"pg@npm:^8.13.1": - version: 8.16.0 - resolution: "pg@npm:8.16.0" - dependencies: - pg-cloudflare: "npm:^1.2.5" - pg-connection-string: "npm:^2.9.0" - pg-pool: "npm:^3.10.0" - pg-protocol: "npm:^1.10.0" - pg-types: "npm:2.2.0" - pgpass: "npm:1.0.5" - peerDependencies: - pg-native: ">=3.0.1" - dependenciesMeta: - pg-cloudflare: - optional: true - peerDependenciesMeta: - pg-native: - optional: true - checksum: 10c0/24542229c7e5cbf69d654de32e8cdc8302c73f1338e56728543cb16364fb319d5689e03fa704b69a208105c7065c867cfccb9dbccccea2020bb5c64ead785713 - languageName: node - linkType: hard - -"pgpass@npm:1.0.5": - version: 1.0.5 - resolution: "pgpass@npm:1.0.5" - dependencies: - split2: "npm:^4.1.0" - checksum: 10c0/5ea6c9b2de04c33abb08d33a2dded303c4a3c7162a9264519cbe85c0a9857d712463140ba42fad0c7cd4b21f644dd870b45bb2e02fcbe505b4de0744fd802c1d - languageName: node - linkType: hard - "picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -21769,20 +18122,6 @@ __metadata: languageName: node linkType: hard -"pify@npm:^2.3.0": - version: 2.3.0 - resolution: "pify@npm:2.3.0" - checksum: 10c0/551ff8ab830b1052633f59cb8adc9ae8407a436e06b4a9718bcb27dc5844b83d535c3a8512b388b6062af65a98c49bdc0dd523d8b2617b188f7c8fee457158dc - languageName: node - linkType: hard - -"pify@npm:^3.0.0": - version: 3.0.0 - resolution: "pify@npm:3.0.0" - checksum: 10c0/fead19ed9d801f1b1fcd0638a1ac53eabbb0945bf615f2f8806a8b646565a04a1b0e7ef115c951d225f042cca388fdc1cd3add46d10d1ed6951c20bd2998af10 - languageName: node - linkType: hard - "pify@npm:^4.0.1": version: 4.0.1 resolution: "pify@npm:4.0.1" @@ -21790,7 +18129,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.6": +"pirates@npm:^4.0.4, pirates@npm:^4.0.6": version: 4.0.7 resolution: "pirates@npm:4.0.7" checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a @@ -21869,13 +18208,6 @@ __metadata: languageName: node linkType: hard -"posix-character-classes@npm:^0.1.0": - version: 0.1.1 - resolution: "posix-character-classes@npm:0.1.1" - checksum: 10c0/cce88011548a973b4af58361cd8f5f7b5a6faff8eef0901565802f067bcabf82597e920d4c97c22068464be3cbc6447af589f6cc8a7d813ea7165be60a0395bc - languageName: node - linkType: hard - "possible-typed-array-names@npm:^1.0.0": version: 1.1.0 resolution: "possible-typed-array-names@npm:1.1.0" @@ -21883,165 +18215,6 @@ __metadata: languageName: node linkType: hard -"postcss-import@npm:^15.1.0": - version: 15.1.0 - resolution: "postcss-import@npm:15.1.0" - dependencies: - postcss-value-parser: "npm:^4.0.0" - read-cache: "npm:^1.0.0" - resolve: "npm:^1.1.7" - peerDependencies: - postcss: ^8.0.0 - checksum: 10c0/518aee5c83ea6940e890b0be675a2588db68b2582319f48c3b4e06535a50ea6ee45f7e63e4309f8754473245c47a0372632378d1d73d901310f295a92f26f17b - languageName: node - linkType: hard - -"postcss-js@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-js@npm:4.0.1" - dependencies: - camelcase-css: "npm:^2.0.1" - peerDependencies: - postcss: ^8.4.21 - checksum: 10c0/af35d55cb873b0797d3b42529514f5318f447b134541844285c9ac31a17497297eb72296902967911bb737a75163441695737300ce2794e3bd8c70c13a3b106e - languageName: node - linkType: hard - -"postcss-load-config@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-load-config@npm:4.0.2" - dependencies: - lilconfig: "npm:^3.0.0" - yaml: "npm:^2.3.4" - peerDependencies: - postcss: ">=8.0.9" - ts-node: ">=9.0.0" - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - checksum: 10c0/3d7939acb3570b0e4b4740e483d6e555a3e2de815219cb8a3c8fc03f575a6bde667443aa93369c0be390af845cb84471bf623e24af833260de3a105b78d42519 - languageName: node - linkType: hard - -"postcss-nested@npm:^6.2.0": - version: 6.2.0 - resolution: "postcss-nested@npm:6.2.0" - dependencies: - postcss-selector-parser: "npm:^6.1.1" - peerDependencies: - postcss: ^8.2.14 - checksum: 10c0/7f9c3f2d764191a39364cbdcec350f26a312431a569c9ef17408021424726b0d67995ff5288405e3724bb7152a4c92f73c027e580ec91e798800ed3c52e2bc6e - languageName: node - linkType: hard - -"postcss-selector-parser@npm:^6.1.1, postcss-selector-parser@npm:^6.1.2": - version: 6.1.2 - resolution: "postcss-selector-parser@npm:6.1.2" - dependencies: - cssesc: "npm:^3.0.0" - util-deprecate: "npm:^1.0.2" - checksum: 10c0/523196a6bd8cf660bdf537ad95abd79e546d54180f9afb165a4ab3e651ac705d0f8b8ce6b3164fb9e3279ce482c5f751a69eb2d3a1e8eb0fd5e82294fb3ef13e - languageName: node - linkType: hard - -"postcss-value-parser@npm:^4.0.0": - version: 4.2.0 - resolution: "postcss-value-parser@npm:4.2.0" - checksum: 10c0/f4142a4f56565f77c1831168e04e3effd9ffcc5aebaf0f538eee4b2d465adfd4b85a44257bb48418202a63806a7da7fe9f56c330aebb3cac898e46b4cbf49161 - languageName: node - linkType: hard - -"postcss@npm:8.4.31": - version: 8.4.31 - resolution: "postcss@npm:8.4.31" - dependencies: - nanoid: "npm:^3.3.6" - picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.0.2" - checksum: 10c0/748b82e6e5fc34034dcf2ae88ea3d11fd09f69b6c50ecdd3b4a875cfc7cdca435c958b211e2cb52355422ab6fccb7d8f2f2923161d7a1b281029e4a913d59acf - languageName: node - linkType: hard - -"postcss@npm:^8, postcss@npm:^8.4.47": - version: 8.5.3 - resolution: "postcss@npm:8.5.3" - dependencies: - nanoid: "npm:^3.3.8" - picocolors: "npm:^1.1.1" - source-map-js: "npm:^1.2.1" - checksum: 10c0/b75510d7b28c3ab728c8733dd01538314a18c52af426f199a3c9177e63eb08602a3938bfb66b62dc01350b9aed62087eabbf229af97a1659eb8d3513cec823b3 - languageName: node - linkType: hard - -"postgres-array@npm:~2.0.0": - version: 2.0.0 - resolution: "postgres-array@npm:2.0.0" - checksum: 10c0/cbd56207e4141d7fbf08c86f2aebf21fa7064943d3f808ec85f442ff94b48d891e7a144cc02665fb2de5dbcb9b8e3183a2ac749959e794b4a4cfd379d7a21d08 - languageName: node - linkType: hard - -"postgres-array@npm:~3.0.1": - version: 3.0.4 - resolution: "postgres-array@npm:3.0.4" - checksum: 10c0/47f3e648da512bacdd6a5ed55cf770605ec271330789faeece0fd13805a49f376d6e5c9e0e353377be11a9545e727dceaa2473566c505432bf06366ccd04c6b2 - languageName: node - linkType: hard - -"postgres-bytea@npm:~1.0.0": - version: 1.0.0 - resolution: "postgres-bytea@npm:1.0.0" - checksum: 10c0/febf2364b8a8953695cac159eeb94542ead5886792a9627b97e33f6b5bb6e263bc0706ab47ec221516e79fbd6b2452d668841830fb3b49ec6c0fc29be61892ce - languageName: node - linkType: hard - -"postgres-bytea@npm:~3.0.0": - version: 3.0.0 - resolution: "postgres-bytea@npm:3.0.0" - dependencies: - obuf: "npm:~1.1.2" - checksum: 10c0/41c79cc48aa730c5ba3eda6ab989a940034f07a1f57b8f2777dce56f1b8cca16c5870582932b5b10cc605048aef9b6157e06253c871b4717cafc6d00f55376aa - languageName: node - linkType: hard - -"postgres-date@npm:~1.0.4": - version: 1.0.7 - resolution: "postgres-date@npm:1.0.7" - checksum: 10c0/0ff91fccc64003e10b767fcfeefb5eaffbc522c93aa65d5051c49b3c4ce6cb93ab091a7d22877a90ad60b8874202c6f1d0f935f38a7235ed3b258efd54b97ca9 - languageName: node - linkType: hard - -"postgres-date@npm:~2.1.0": - version: 2.1.0 - resolution: "postgres-date@npm:2.1.0" - checksum: 10c0/00a7472c10788f6b0d08d24108bf1eb80858de1bd6317740198a564918ea4a69b80c98148167b92ae688abd606483020d0de0dd3a36f3ea9a3e26bbeef3464f4 - languageName: node - linkType: hard - -"postgres-interval@npm:^1.1.0": - version: 1.2.0 - resolution: "postgres-interval@npm:1.2.0" - dependencies: - xtend: "npm:^4.0.0" - checksum: 10c0/c1734c3cb79e7f22579af0b268a463b1fa1d084e742a02a7a290c4f041e349456f3bee3b4ee0bb3f226828597f7b76deb615c1b857db9a742c45520100456272 - languageName: node - linkType: hard - -"postgres-interval@npm:^3.0.0": - version: 3.0.0 - resolution: "postgres-interval@npm:3.0.0" - checksum: 10c0/8b570b30ea37c685e26d136d34460f246f98935a1533defc4b53bb05ee23ae3dc7475b718ec7ea607a57894d8c6b4f1adf67ca9cc83a75bdacffd427d5c68de8 - languageName: node - linkType: hard - -"postgres-range@npm:^1.1.1": - version: 1.1.4 - resolution: "postgres-range@npm:1.1.4" - checksum: 10c0/254494ef81df208e0adeae6b66ce394aba37914ea14c7ece55a45fb6691b7db04bee74c825380a47c887a9f87158fd3d86f758f9cc60b76d3a38ce5aca7912e8 - languageName: node - linkType: hard - "postinstall-postinstall@npm:^2.1.0": version: 2.1.0 resolution: "postinstall-postinstall@npm:2.1.0" @@ -22063,13 +18236,6 @@ __metadata: languageName: node linkType: hard -"prepend-http@npm:^1.0.1": - version: 1.0.4 - resolution: "prepend-http@npm:1.0.4" - checksum: 10c0/c6c173ca439e58163ba7bea7cbba52a1ed11e3e3da1c048da296f37d4b7654f78f7304e03f76d5923f4b83af7e2d55533e0f79064209c75b743ccddee13904f8 - languageName: node - linkType: hard - "prettier-linter-helpers@npm:^1.0.0": version: 1.0.0 resolution: "prettier-linter-helpers@npm:1.0.0" @@ -22190,7 +18356,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -22240,13 +18406,6 @@ __metadata: languageName: node linkType: hard -"pseudomap@npm:^1.0.2": - version: 1.0.2 - resolution: "pseudomap@npm:1.0.2" - checksum: 10c0/5a91ce114c64ed3a6a553aa7d2943868811377388bb31447f9d8028271bae9b05b340fe0b6961a64e45b9c72946aeb0a4ab635e8f7cb3715ffd0ff2beeb6a679 - languageName: node - linkType: hard - "psl@npm:^1.9.0": version: 1.15.0 resolution: "psl@npm:1.15.0" @@ -22256,13 +18415,6 @@ __metadata: languageName: node linkType: hard -"pstree.remy@npm:^1.1.7": - version: 1.1.8 - resolution: "pstree.remy@npm:1.1.8" - checksum: 10c0/30f78c88ce6393cb3f7834216cb6e282eb83c92ccb227430d4590298ab2811bc4a4745f850a27c5178e79a8f3e316591de0fec87abc19da648c2b3c6eb766d14 - languageName: node - linkType: hard - "pump@npm:^3.0.0": version: 3.0.2 resolution: "pump@npm:3.0.2" @@ -22325,28 +18477,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:2.3.3": - version: 2.3.3 - resolution: "qs@npm:2.3.3" - checksum: 10c0/4c02f03f77e50219799f52608dd72f57389ea364be499f5e8b02d505377cb93f6414239e00b3a7342b0d05a730ad85b3ffb5e7f0a5ba2f3d8ef7303283c01e17 - languageName: node - linkType: hard - -"qs@npm:2.4.2": - version: 2.4.2 - resolution: "qs@npm:2.4.2" - checksum: 10c0/50228c5c2129766e04f8aec41c70e3e1d235484ac8e83352d6ac723d58e91642082abc0172122dc27e13e8c6a28a8d3b9fc499fe120c48dc764ddf27f498fb51 - languageName: node - linkType: hard - -"qs@npm:^4.0.0": - version: 4.0.0 - resolution: "qs@npm:4.0.0" - checksum: 10c0/23a656b2193ded17fbc2fbb08e5294f1657fc4b4cc62de4d8808b330854022a34b8394d2507bcf9998982d26ce5e3822b039ee3523fe8590223d4a156e08e998 - languageName: node - linkType: hard - -"qs@npm:^6.10.3, qs@npm:^6.11.0, qs@npm:^6.4.0": +"qs@npm:^6.4.0": version: 6.14.0 resolution: "qs@npm:6.14.0" dependencies: @@ -22466,30 +18597,6 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:~2.0.1": - version: 2.0.2 - resolution: "raw-body@npm:2.0.2" - dependencies: - bytes: "npm:2.1.0" - iconv-lite: "npm:0.4.8" - checksum: 10c0/a2c15f2862b278b1550d45624cce27838fa1ffe19429fa8c4ae977c66e36642827a74a7ef049a415ccba4b1595c2fb55d595d55ec1c1ae65f8cd2582203ccae6 - languageName: node - linkType: hard - -"rc@npm:^1.0.1, rc@npm:^1.1.6": - version: 1.2.8 - resolution: "rc@npm:1.2.8" - dependencies: - deep-extend: "npm:^0.6.0" - ini: "npm:~1.3.0" - minimist: "npm:^1.2.0" - strip-json-comments: "npm:~2.0.1" - bin: - rc: ./cli.js - checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 - languageName: node - linkType: hard - "react-devtools-core@npm:^5.3.1": version: 5.3.2 resolution: "react-devtools-core@npm:5.3.2" @@ -22510,7 +18617,7 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18, react-dom@npm:^18.0.0": +"react-dom@npm:^18.0.0": version: 18.3.1 resolution: "react-dom@npm:18.3.1" dependencies: @@ -22563,7 +18670,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^19.0.0, react-is@npm:^19.1.0": +"react-is@npm:^19.1.0": version: 19.1.0 resolution: "react-is@npm:19.1.0" checksum: 10c0/b6c6cadd172d5d39f66d493700d137a5545c294a62ce0f8ec793d59794c97d2bed6bad227626f16bd0e90004ed7fdc8ed662a004e6edcf5d2b7ecb6e3040ea6b @@ -22997,22 +19104,7 @@ __metadata: languageName: node linkType: hard -"react-transition-group@npm:^4.4.5": - version: 4.4.5 - resolution: "react-transition-group@npm:4.4.5" - dependencies: - "@babel/runtime": "npm:^7.5.5" - dom-helpers: "npm:^5.0.1" - loose-envify: "npm:^1.4.0" - prop-types: "npm:^15.6.2" - peerDependencies: - react: ">=16.6.0" - react-dom: ">=16.6.0" - checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82 - languageName: node - linkType: hard - -"react@npm:^18, react@npm:^18.0.0, react@npm:^18.3.1": +"react@npm:^18.0.0, react@npm:^18.3.1": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: @@ -23021,39 +19113,6 @@ __metadata: languageName: node linkType: hard -"read-cache@npm:^1.0.0": - version: 1.0.0 - resolution: "read-cache@npm:1.0.0" - dependencies: - pify: "npm:^2.3.0" - checksum: 10c0/90cb2750213c7dd7c80cb420654344a311fdec12944e81eb912cd82f1bc92aea21885fa6ce442e3336d9fccd663b8a7a19c46d9698e6ca55620848ab932da814 - languageName: node - linkType: hard - -"readable-stream@npm:1.0.27-1": - version: 1.0.27-1 - resolution: "readable-stream@npm:1.0.27-1" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.1" - isarray: "npm:0.0.1" - string_decoder: "npm:~0.10.x" - checksum: 10c0/b887546e0a2c9e3204141be697d96f7966c4f25110925d9cd6714cf451d750b77ad873fd176ed03e40e4cb5da52f35a382ddd50e306e3f5fd37e238044897cd3 - languageName: node - linkType: hard - -"readable-stream@npm:1.1.x": - version: 1.1.14 - resolution: "readable-stream@npm:1.1.14" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.1" - isarray: "npm:0.0.1" - string_decoder: "npm:~0.10.x" - checksum: 10c0/b7f41b16b305103d598e3c8964fa30d52d6e0b5d9fdad567588964521691c24b279c7a8bb71f11927c3613acf355bac72d8396885a43d50425b2caafd49bc83d - languageName: node - linkType: hard - "readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" @@ -23065,7 +19124,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.2, readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -23087,20 +19146,9 @@ __metadata: abort-controller: "npm:^3.0.0" buffer: "npm:^6.0.3" events: "npm:^3.3.0" - process: "npm:^0.11.10" - string_decoder: "npm:^1.3.0" - checksum: 10c0/fd86d068da21cfdb10f7a4479f2e47d9c0a9b0c862fc0c840a7e5360201580a55ac399c764b12a4f6fa291f8cee74d9c4b7562e0d53b3c4b2769f2c98155d957 - languageName: node - linkType: hard - -"readdirp@npm:^2.2.1": - version: 2.2.1 - resolution: "readdirp@npm:2.2.1" - dependencies: - graceful-fs: "npm:^4.1.11" - micromatch: "npm:^3.1.10" - readable-stream: "npm:^2.0.2" - checksum: 10c0/770d177372ff2212d382d425d55ca48301fcbf3231ab3827257bbcca7ff44fb51fe4af6acc2dda8512dc7f29da390e9fbea5b2b3fc724b86e85cc828395b7797 + process: "npm:^0.11.10" + string_decoder: "npm:^1.3.0" + checksum: 10c0/fd86d068da21cfdb10f7a4479f2e47d9c0a9b0c862fc0c840a7e5360201580a55ac399c764b12a4f6fa291f8cee74d9c4b7562e0d53b3c4b2769f2c98155d957 languageName: node linkType: hard @@ -23120,17 +19168,6 @@ __metadata: languageName: node linkType: hard -"readline2@npm:^1.0.1": - version: 1.0.1 - resolution: "readline2@npm:1.0.1" - dependencies: - code-point-at: "npm:^1.0.0" - is-fullwidth-code-point: "npm:^1.0.0" - mute-stream: "npm:0.0.5" - checksum: 10c0/8b245192a925d5829d0b243c89dfc70646f4842f9ee968528f8b2f60b1c3277446cc007a4a2a1c91360dc1a7a8025d9b30567b6684bee4962179428e1ac02d86 - languageName: node - linkType: hard - "readline@npm:^1.3.0": version: 1.3.0 resolution: "readline@npm:1.3.0" @@ -23178,13 +19215,6 @@ __metadata: languageName: node linkType: hard -"reduce-component@npm:1.0.1": - version: 1.0.1 - resolution: "reduce-component@npm:1.0.1" - checksum: 10c0/a06392549d3783c626daff88e49ca29d02390b27028a37a75116c3f36b544ad1772d32332b0f374990545287edf4403159de990d0678fb799b254ebbe113fa71 - languageName: node - linkType: hard - "reduce-flatten@npm:^2.0.0": version: 2.0.0 resolution: "reduce-flatten@npm:2.0.0" @@ -23245,16 +19275,6 @@ __metadata: languageName: node linkType: hard -"regex-not@npm:^1.0.0, regex-not@npm:^1.0.2": - version: 1.0.2 - resolution: "regex-not@npm:1.0.2" - dependencies: - extend-shallow: "npm:^3.0.2" - safe-regex: "npm:^1.1.0" - checksum: 10c0/a0f8d6045f63b22e9759db10e248369c443b41cedd7dba0922d002b66c2734bc2aef0d98c4d45772d1f756245f4c5203856b88b9624bba2a58708858a8d485d6 - languageName: node - linkType: hard - "regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" @@ -23283,25 +19303,6 @@ __metadata: languageName: node linkType: hard -"registry-auth-token@npm:^3.0.1": - version: 3.4.0 - resolution: "registry-auth-token@npm:3.4.0" - dependencies: - rc: "npm:^1.1.6" - safe-buffer: "npm:^5.0.1" - checksum: 10c0/44c0cbf380bcf0af02996b7d0215e2f789c97d2c762bb420fd844b34588bf77ab0cf94fbe33eeaf945456ff022dbfebec4309cf5ef110a653aa3696134efd081 - languageName: node - linkType: hard - -"registry-url@npm:^3.0.3": - version: 3.1.0 - resolution: "registry-url@npm:3.1.0" - dependencies: - rc: "npm:^1.0.1" - checksum: 10c0/345cf9638f99d95863d92800b3f595ac312c19d6865595e499fbeb33fcda04021a0dbdafbb5e61a838a89a558bc239d78752a1f90eb68cf53fdf0d91da816a7c - languageName: node - linkType: hard - "regjsgen@npm:^0.8.0": version: 0.8.0 resolution: "regjsgen@npm:0.8.0" @@ -23320,20 +19321,6 @@ __metadata: languageName: node linkType: hard -"remove-trailing-separator@npm:^1.0.1": - version: 1.1.0 - resolution: "remove-trailing-separator@npm:1.1.0" - checksum: 10c0/3568f9f8f5af3737b4aee9e6e1e8ec4be65a92da9cb27f989e0893714d50aa95ed2ff02d40d1fa35e1b1a234dc9c2437050ef356704a3999feaca6667d9e9bfc - languageName: node - linkType: hard - -"repeat-element@npm:^1.1.2": - version: 1.1.4 - resolution: "repeat-element@npm:1.1.4" - checksum: 10c0/81aa8d82bc845780803ef52df3533fa399974b99df571d0bb86e91f0ffca9ee4b9c4e8e5e72af087938cc28d2aef93d106a6d01da685d72ce96455b90a9f9f69 - languageName: node - linkType: hard - "repeat-string@npm:^1.6.1": version: 1.6.1 resolution: "repeat-string@npm:1.6.1" @@ -23424,13 +19411,6 @@ __metadata: languageName: node linkType: hard -"resolve-url@npm:^0.2.1": - version: 0.2.1 - resolution: "resolve-url@npm:0.2.1" - checksum: 10c0/c285182cfcddea13a12af92129ce0569be27fb0074ffaefbd3ba3da2eac2acecdfc996d435c4982a9fa2b4708640e52837c9153a5ab9255886a00b0b9e8d2a54 - languageName: node - linkType: hard - "resolve.exports@npm:^2.0.0": version: 2.0.3 resolution: "resolve.exports@npm:2.0.3" @@ -23454,7 +19434,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4, resolve@npm:^1.22.8": +"resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.14.2, resolve@npm:^1.20.0": version: 1.22.10 resolution: "resolve@npm:1.22.10" dependencies: @@ -23496,7 +19476,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin": version: 1.22.10 resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" dependencies: @@ -23531,16 +19511,6 @@ __metadata: languageName: node linkType: hard -"restore-cursor@npm:^1.0.1": - version: 1.0.1 - resolution: "restore-cursor@npm:1.0.1" - dependencies: - exit-hook: "npm:^1.0.0" - onetime: "npm:^1.0.0" - checksum: 10c0/5bab0d0131b91d5f4445cccf8e43dfde39c4de007c4792be5d03ea245439a96162a307285dd6684e81cc43ff205ec85ba21daa07ceae827b18a4f32ddaf7b7b1 - languageName: node - linkType: hard - "restore-cursor@npm:^3.1.0": version: 3.1.0 resolution: "restore-cursor@npm:3.1.0" @@ -23551,13 +19521,6 @@ __metadata: languageName: node linkType: hard -"ret@npm:~0.1.10": - version: 0.1.15 - resolution: "ret@npm:0.1.15" - checksum: 10c0/01f77cad0f7ea4f955852c03d66982609893edc1240c0c964b4c9251d0f9fb6705150634060d169939b096d3b77f4c84d6b6098a5b5d340160898c8581f1f63f - languageName: node - linkType: hard - "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -23572,7 +19535,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^2.2.8, rimraf@npm:^2.6.3": +"rimraf@npm:^2.6.3": version: 2.7.1 resolution: "rimraf@npm:2.7.1" dependencies: @@ -23626,15 +19589,6 @@ __metadata: languageName: node linkType: hard -"run-async@npm:^0.1.0": - version: 0.1.0 - resolution: "run-async@npm:0.1.0" - dependencies: - once: "npm:^1.3.0" - checksum: 10c0/059e76d49f56d30e71e6baab6844bb8729889d0e28b4a2e586e8bb18163cc71c7aba16172ab77ae40f3f0a63bb502babdb71907277e9b8aac3ecd7498f5a0c41 - languageName: node - linkType: hard - "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -23644,13 +19598,6 @@ __metadata: languageName: node linkType: hard -"rx-lite@npm:^3.1.2": - version: 3.1.2 - resolution: "rx-lite@npm:3.1.2" - checksum: 10c0/be2ce693f96cfe0b6dc2a5bb1fe28613edd0226238043f783facf97c76e91cde46c2f25a1b18337c97f27bba610d696d96b55040ba7a10088480902ba179fa03 - languageName: node - linkType: hard - "safe-array-concat@npm:^1.1.2, safe-array-concat@npm:^1.1.3": version: 1.1.3 resolution: "safe-array-concat@npm:1.1.3" @@ -23688,7 +19635,7 @@ __metadata: languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3, safe-regex-test@npm:^1.1.0": +"safe-regex-test@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex-test@npm:1.1.0" dependencies: @@ -23699,15 +19646,6 @@ __metadata: languageName: node linkType: hard -"safe-regex@npm:^1.1.0": - version: 1.1.0 - resolution: "safe-regex@npm:1.1.0" - dependencies: - ret: "npm:~0.1.10" - checksum: 10c0/547d58aa5184cbef368fd5ed5f28d20f911614748c5da6b35f53fd6626396707587251e6e3d1e3010fd3ff1212e413841b8825eaa5f317017ca62a30899af31a - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -23715,15 +19653,6 @@ __metadata: languageName: node linkType: hard -"sanitize-filename@npm:^1.3.0": - version: 1.6.3 - resolution: "sanitize-filename@npm:1.6.3" - dependencies: - truncate-utf8-bytes: "npm:^1.0.0" - checksum: 10c0/16ff47556a6e54e228c28db096bedd303da67b030d4bea4925fd71324932d6b02c7b0446f00ad33987b25b6414f24ae968e01a1a1679ce599542e82c4b07eb1f - languageName: node - linkType: hard - "sc-istanbul@npm:^0.4.5": version: 0.4.6 resolution: "sc-istanbul@npm:0.4.6" @@ -23823,15 +19752,6 @@ __metadata: languageName: node linkType: hard -"semver-diff@npm:^2.0.0": - version: 2.1.0 - resolution: "semver-diff@npm:2.1.0" - dependencies: - semver: "npm:^5.0.3" - checksum: 10c0/5825827a82e848908c6b6f9248aad4a15fe5baeed74ae41d67cf6d96107425028a5a5432e17abf10f0696719b0efcbbc34b47d071a70fb85e11cb451feb637e6 - languageName: node - linkType: hard - "semver@npm:7.6.0": version: 7.6.0 resolution: "semver@npm:7.6.0" @@ -23843,7 +19763,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^5.0.3, semver@npm:^5.1.0, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1": +"semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -23907,7 +19827,7 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:^1.10.0, serve-static@npm:^1.13.1, serve-static@npm:^1.16.2, serve-static@npm:^1.9.2": +"serve-static@npm:^1.13.1, serve-static@npm:^1.16.2": version: 1.16.2 resolution: "serve-static@npm:1.16.2" dependencies: @@ -23963,18 +19883,6 @@ __metadata: languageName: node linkType: hard -"set-value@npm:^2.0.0, set-value@npm:^2.0.1": - version: 2.0.1 - resolution: "set-value@npm:2.0.1" - dependencies: - extend-shallow: "npm:^2.0.1" - is-extendable: "npm:^0.1.1" - is-plain-object: "npm:^2.0.3" - split-string: "npm:^3.0.1" - checksum: 10c0/4c40573c4f6540456e4b38b95f570272c4cfbe1d12890ad4057886da8535047cd772dfadf5b58e2e87aa244dfb4c57e3586f6716b976fc47c5144b6b09e1811b - languageName: node - linkType: hard - "setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -24031,15 +19939,6 @@ __metadata: languageName: node linkType: hard -"shebang-command@npm:^1.2.0": - version: 1.2.0 - resolution: "shebang-command@npm:1.2.0" - dependencies: - shebang-regex: "npm:^1.0.0" - checksum: 10c0/7b20dbf04112c456b7fc258622dafd566553184ac9b6938dd30b943b065b21dabd3776460df534cc02480db5e1b6aec44700d985153a3da46e7db7f9bd21326d - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -24049,13 +19948,6 @@ __metadata: languageName: node linkType: hard -"shebang-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "shebang-regex@npm:1.0.0" - checksum: 10c0/9abc45dee35f554ae9453098a13fdc2f1730e525a5eb33c51f096cc31f6f10a4b38074c1ebf354ae7bffa7229506083844008dfc3bb7818228568c0b2dc1fff2 - languageName: node - linkType: hard - "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" @@ -24138,14 +20030,7 @@ __metadata: languageName: node linkType: hard -"sigmund@npm:~1.0.0": - version: 1.0.1 - resolution: "sigmund@npm:1.0.1" - checksum: 10c0/0cc9cf0acf4ee1e29bc324ec60b81865c30c4cf6738c6677646b101df1b1b1663759106d96de4199648e5fff3d1d2468ba06ec437cfcef16ee8ff19133fcbb9d - languageName: node - linkType: hard - -"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 @@ -24192,13 +20077,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^1.0.0": - version: 1.0.0 - resolution: "slash@npm:1.0.0" - checksum: 10c0/3944659885d905480f98810542fd314f3e1006eaad25ec78227a7835a469d9ed66fc3dd90abc7377dd2e71f4b5473e8f766bd08198fdd25152a80792e9ed464c - languageName: node - linkType: hard - "slash@npm:^2.0.0": version: 2.0.0 resolution: "slash@npm:2.0.0" @@ -24252,42 +20130,6 @@ __metadata: languageName: node linkType: hard -"snapdragon-node@npm:^2.0.1": - version: 2.1.1 - resolution: "snapdragon-node@npm:2.1.1" - dependencies: - define-property: "npm:^1.0.0" - isobject: "npm:^3.0.0" - snapdragon-util: "npm:^3.0.1" - checksum: 10c0/7616e6a1ca054afe3ad8defda17ebe4c73b0800d2e0efd635c44ee1b286f8ac7900517314b5330862ce99b28cd2782348ee78bae573ff0f55832ad81d9657f3f - languageName: node - linkType: hard - -"snapdragon-util@npm:^3.0.1": - version: 3.0.1 - resolution: "snapdragon-util@npm:3.0.1" - dependencies: - kind-of: "npm:^3.2.0" - checksum: 10c0/4441856d343399ba7f37f79681949d51b922e290fcc07e7bc94655a50f584befa4fb08f40c3471cd160e004660161964d8ff140cba49baa59aa6caba774240e3 - languageName: node - linkType: hard - -"snapdragon@npm:^0.8.1": - version: 0.8.2 - resolution: "snapdragon@npm:0.8.2" - dependencies: - base: "npm:^0.11.1" - debug: "npm:^2.2.0" - define-property: "npm:^0.2.5" - extend-shallow: "npm:^2.0.1" - map-cache: "npm:^0.2.2" - source-map: "npm:^0.5.6" - source-map-resolve: "npm:^0.5.0" - use: "npm:^3.1.0" - checksum: 10c0/dfdac1f73d47152d72fc07f4322da09bbddfa31c1c9c3ae7346f252f778c45afa5b03e90813332f02f04f6de8003b34a168c456f8bb719024d092f932520ffca - languageName: node - linkType: hard - "snarkjs@https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e": version: 0.5.0 resolution: "snarkjs@https://github.com/sampritipanda/snarkjs.git#commit=fef81fc51d17a734637555c6edbd585ecda02d9e" @@ -24463,26 +20305,13 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.1": +"source-map-js@npm:^1.0.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0": - version: 0.5.3 - resolution: "source-map-resolve@npm:0.5.3" - dependencies: - atob: "npm:^2.1.2" - decode-uri-component: "npm:^0.2.0" - resolve-url: "npm:^0.2.1" - source-map-url: "npm:^0.4.0" - urix: "npm:^0.1.0" - checksum: 10c0/410acbe93882e058858d4c1297be61da3e1533f95f25b95903edddc1fb719654e705663644677542d1fb78a66390238fad1a57115fc958a0724cf9bb509caf57 - languageName: node - linkType: hard - "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -24503,14 +20332,7 @@ __metadata: languageName: node linkType: hard -"source-map-url@npm:^0.4.0": - version: 0.4.1 - resolution: "source-map-url@npm:0.4.1" - checksum: 10c0/f8af0678500d536c7f643e32094d6718a4070ab4ca2d2326532512cfbe2d5d25a45849b4b385879326f2d7523bb3b686d0360dd347a3cda09fd89a5c28d4bc58 - languageName: node - linkType: hard - -"source-map@npm:^0.5.6, source-map@npm:^0.5.7": +"source-map@npm:^0.5.6": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 @@ -24540,13 +20362,6 @@ __metadata: languageName: node linkType: hard -"spark-md5@npm:^1.0.0": - version: 1.0.1 - resolution: "spark-md5@npm:1.0.1" - checksum: 10c0/af4c247c8f1f101344b82aa9403c45ff451ade53ad859dc77f360db6d1dbad25d5495c8bebc17a18aac084af70d928ef7fb041ec4dfd59bbe0c00cceae8e2b52 - languageName: node - linkType: hard - "split-on-first@npm:^1.0.0": version: 1.1.0 resolution: "split-on-first@npm:1.1.0" @@ -24554,15 +20369,6 @@ __metadata: languageName: node linkType: hard -"split-string@npm:^3.0.1, split-string@npm:^3.0.2": - version: 3.1.0 - resolution: "split-string@npm:3.1.0" - dependencies: - extend-shallow: "npm:^3.0.0" - checksum: 10c0/72d7cd625445c7af215130e1e2bc183013bb9dd48a074eda1d35741e2b0dcb355e6df5b5558a62543a24dcec37dd1d6eb7a6228ff510d3c9de0f3dc1d1da8a70 - languageName: node - linkType: hard - "split2@npm:^3.0.0": version: 3.2.2 resolution: "split2@npm:3.2.2" @@ -24572,13 +20378,6 @@ __metadata: languageName: node linkType: hard -"split2@npm:^4.1.0": - version: 4.2.0 - resolution: "split2@npm:4.2.0" - checksum: 10c0/b292beb8ce9215f8c642bb68be6249c5a4c7f332fc8ecadae7be5cbdf1ea95addc95f0459ef2e7ad9d45fd1064698a097e4eb211c83e772b49bc0ee423e91534 - languageName: node - linkType: hard - "sprintf-js@npm:^1.1.3": version: 1.1.3 resolution: "sprintf-js@npm:1.1.3" @@ -24602,13 +20401,6 @@ __metadata: languageName: node linkType: hard -"stable-hash@npm:^0.0.5": - version: 0.0.5 - resolution: "stable-hash@npm:0.0.5" - checksum: 10c0/ca670cb6d172f1c834950e4ec661e2055885df32fee3ebf3647c5df94993b7c2666a5dbc1c9a62ee11fc5c24928579ec5e81bb5ad31971d355d5a341aab493b3 - languageName: node - linkType: hard - "stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -24643,16 +20435,6 @@ __metadata: languageName: node linkType: hard -"static-extend@npm:^0.1.1": - version: 0.1.2 - resolution: "static-extend@npm:0.1.2" - dependencies: - define-property: "npm:^0.2.5" - object-copy: "npm:^0.1.0" - checksum: 10c0/284f5865a9e19d079f1badbcd70d5f9f82e7a08393f818a220839cd5f71729e89105e1c95322bd28e833161d484cee671380ca443869ae89578eef2bf55c0653 - languageName: node - linkType: hard - "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -24677,20 +20459,6 @@ __metadata: languageName: node linkType: hard -"streamsearch@npm:0.1.2": - version: 0.1.2 - resolution: "streamsearch@npm:0.1.2" - checksum: 10c0/408a3db5b5643c1d6eb65c9d8ccc011b4857bfca41946d808b7f165b5b85f47755b2ff56ec1c4bbbeb5a496afcde9adfea12f9f67bd09ff3f04ae3f1f58d37c6 - languageName: node - linkType: hard - -"streamsearch@npm:^1.1.0": - version: 1.1.0 - resolution: "streamsearch@npm:1.1.0" - checksum: 10c0/fbd9aecc2621364384d157f7e59426f4bfd385e8b424b5aaa79c83a6f5a1c8fd2e4e3289e95de1eb3511cb96bb333d6281a9919fafce760e4edb35b2cd2facab - languageName: node - linkType: hard - "streamx@npm:^2.15.0, streamx@npm:^2.21.0": version: 2.22.0 resolution: "streamx@npm:2.22.0" @@ -24757,7 +20525,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^2.0.0, string-width@npm:^2.1.1": +"string-width@npm:^2.1.1": version: 2.1.1 resolution: "string-width@npm:2.1.1" dependencies: @@ -24778,17 +20546,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.includes@npm:^2.0.1": - version: 2.0.1 - resolution: "string.prototype.includes@npm:2.0.1" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.3" - checksum: 10c0/25ce9c9b49128352a2618fbe8758b46f945817a58a4420f4799419e40a8d28f116e176c7590d767d5327a61e75c8f32c86171063f48e389b9fdd325f1bd04ee5 - languageName: node - linkType: hard - "string.prototype.matchall@npm:^4.0.12": version: 4.0.12 resolution: "string.prototype.matchall@npm:4.0.12" @@ -24860,7 +20617,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.3, string.prototype.trimend@npm:^1.0.8, string.prototype.trimend@npm:^1.0.9": +"string.prototype.trimend@npm:^1.0.3, string.prototype.trimend@npm:^1.0.9": version: 1.0.9 resolution: "string.prototype.trimend@npm:1.0.9" dependencies: @@ -24905,13 +20662,6 @@ __metadata: languageName: node linkType: hard -"string@npm:^3.3.0": - version: 3.3.3 - resolution: "string@npm:3.3.3" - checksum: 10c0/6991ab28add3276ca5334739054dcd4a03f35c0c0e7220f4be19d3cf70b7aa339633a03063f77b3d9ab1e0f7b6b0844c6248dff19f810de015fd45fdd38ff3e0 - languageName: node - linkType: hard - "string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" @@ -24921,13 +20671,6 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:~0.10.x": - version: 0.10.31 - resolution: "string_decoder@npm:0.10.31" - checksum: 10c0/1c628d78f974aa7539c496029f48e7019acc32487fc695464f9d6bdfec98edd7d933a06b3216bc2016918f6e75074c611d84430a53cb0e43071597d6c1ac5e25 - languageName: node - linkType: hard - "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -24946,15 +20689,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^3.0.0": - version: 3.0.1 - resolution: "strip-ansi@npm:3.0.1" - dependencies: - ansi-regex: "npm:^2.0.0" - checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f - languageName: node - linkType: hard - "strip-ansi@npm:^4.0.0": version: 4.0.0 resolution: "strip-ansi@npm:4.0.0" @@ -24996,13 +20730,6 @@ __metadata: languageName: node linkType: hard -"strip-eof@npm:^1.0.0": - version: 1.0.0 - resolution: "strip-eof@npm:1.0.0" - checksum: 10c0/f336beed8622f7c1dd02f2cbd8422da9208fae81daf184f73656332899978919d5c0ca84dc6cfc49ad1fc4dd7badcde5412a063cf4e0d7f8ed95a13a63f68f45 - languageName: node - linkType: hard - "strip-final-newline@npm:^2.0.0": version: 2.0.0 resolution: "strip-final-newline@npm:2.0.0" @@ -25035,13 +20762,6 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:~2.0.1": - version: 2.0.1 - resolution: "strip-json-comments@npm:2.0.1" - checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 - languageName: node - linkType: hard - "strnum@npm:^1.1.1": version: 1.1.2 resolution: "strnum@npm:1.1.2" @@ -25059,47 +20779,6 @@ __metadata: languageName: node linkType: hard -"styled-jsx@npm:5.1.1": - version: 5.1.1 - resolution: "styled-jsx@npm:5.1.1" - dependencies: - client-only: "npm:0.0.1" - peerDependencies: - react: ">= 16.8.0 || 17.x.x || ^18.0.0-0" - peerDependenciesMeta: - "@babel/core": - optional: true - babel-plugin-macros: - optional: true - checksum: 10c0/42655cdadfa5388f8a48bb282d6b450df7d7b8cf066ac37038bd0499d3c9f084815ebd9ff9dfa12a218fd4441338851db79603498d7557207009c1cf4d609835 - languageName: node - linkType: hard - -"stylis@npm:4.2.0": - version: 4.2.0 - resolution: "stylis@npm:4.2.0" - checksum: 10c0/a7128ad5a8ed72652c6eba46bed4f416521bc9745a460ef5741edc725252cebf36ee45e33a8615a7057403c93df0866ab9ee955960792db210bb80abd5ac6543 - languageName: node - linkType: hard - -"sucrase@npm:^3.35.0": - version: 3.35.0 - resolution: "sucrase@npm:3.35.0" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.2" - commander: "npm:^4.0.0" - glob: "npm:^10.3.10" - lines-and-columns: "npm:^1.1.6" - mz: "npm:^2.7.0" - pirates: "npm:^4.0.1" - ts-interface-checker: "npm:^0.1.9" - bin: - sucrase: bin/sucrase - sucrase-node: bin/sucrase-node - checksum: 10c0/ac85f3359d2c2ecbf5febca6a24ae9bf96c931f05fde533c22a94f59c6a74895e5d5f0e871878dfd59c2697a75ebb04e4b2224ef0bfc24ca1210735c2ec191ef - languageName: node - linkType: hard - "sudo-prompt@npm:^9.0.0": version: 9.2.1 resolution: "sudo-prompt@npm:9.2.1" @@ -25107,44 +20786,6 @@ __metadata: languageName: node linkType: hard -"superagent@npm:^1.2.0": - version: 1.8.5 - resolution: "superagent@npm:1.8.5" - dependencies: - component-emitter: "npm:~1.2.0" - cookiejar: "npm:2.0.6" - debug: "npm:2" - extend: "npm:3.0.0" - form-data: "npm:1.0.0-rc3" - formidable: "npm:~1.0.14" - methods: "npm:~1.1.1" - mime: "npm:1.3.4" - qs: "npm:2.3.3" - readable-stream: "npm:1.0.27-1" - reduce-component: "npm:1.0.1" - checksum: 10c0/636198862a8bad386adc9fbe5f129a2617893fb79dbc007b6c7e92be9a114a7b3aed32c08adf00d286fa8726e6b5d51b8d46345a037a0066d7764b0c41bde4f9 - languageName: node - linkType: hard - -"superagent@npm:^7.1.6": - version: 7.1.6 - resolution: "superagent@npm:7.1.6" - dependencies: - component-emitter: "npm:^1.3.0" - cookiejar: "npm:^2.1.3" - debug: "npm:^4.3.4" - fast-safe-stringify: "npm:^2.1.1" - form-data: "npm:^4.0.0" - formidable: "npm:^2.0.1" - methods: "npm:^1.1.2" - mime: "npm:2.6.0" - qs: "npm:^6.10.3" - readable-stream: "npm:^3.6.0" - semver: "npm:^7.3.7" - checksum: 10c0/af956af1524dda3878df6f694d62bddb63daa747c2a429984b7304e4a5d355b81caaeb5d2049cdbeba207abba06b0d215008755a4f1b4d2c823e0eeaf6a4fad4 - languageName: node - linkType: hard - "superstruct@npm:^0.6.2": version: 0.6.2 resolution: "superstruct@npm:0.6.2" @@ -25155,22 +20796,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:1.2.0": - version: 1.2.0 - resolution: "supports-color@npm:1.2.0" - bin: - supports-color: cli.js - checksum: 10c0/7a3df5814fe5b3676b2f11f7de4bbeb64be182335ae9dd7738101fc8c78df87e0100b2a0104ec29658009195abd4f50f04574e93e6adc7c7e84c288e9731a8ca - languageName: node - linkType: hard - -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 10c0/570e0b63be36cccdd25186350a6cb2eaad332a95ff162fa06d9499982315f2fe4217e69dd98e862fbcd9c81eaff300a825a1fe7bf5cc752e5b84dfed042b0dda - languageName: node - linkType: hard - "supports-color@npm:^3.1.0": version: 3.2.3 resolution: "supports-color@npm:3.2.3" @@ -25180,7 +20805,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": +"supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" dependencies: @@ -25214,120 +20839,27 @@ __metadata: languageName: node linkType: hard -"svg-parser@npm:^2.0.4": - version: 2.0.4 - resolution: "svg-parser@npm:2.0.4" - checksum: 10c0/02f6cb155dd7b63ebc2f44f36365bc294543bebb81b614b7628f1af3c54ab64f7e1cec20f06e252bf95bdde78441ae295a412c68ad1678f16a6907d924512b7a - languageName: node - linkType: hard - -"svgo@npm:^3.0.2": - version: 3.3.2 - resolution: "svgo@npm:3.3.2" - dependencies: - "@trysound/sax": "npm:0.2.0" - commander: "npm:^7.2.0" - css-select: "npm:^5.1.0" - css-tree: "npm:^2.3.1" - css-what: "npm:^6.1.0" - csso: "npm:^5.0.5" - picocolors: "npm:^1.0.0" - bin: - svgo: ./bin/svgo - checksum: 10c0/a6badbd3d1d6dbb177f872787699ab34320b990d12e20798ecae915f0008796a0f3c69164f1485c9def399e0ce0a5683eb4a8045e51a5e1c364bb13a0d9f79e1 - languageName: node - linkType: hard - -"swagger-converter@npm:^0.1.7": - version: 0.1.7 - resolution: "swagger-converter@npm:0.1.7" - dependencies: - lodash.clonedeep: "npm:^2.4.1" - checksum: 10c0/c8255154600b4775570a5cf291aa3bde868b8fbf475564fdaa1b3f454ded67c01b6a8bee8fe9494701678883ef9061d793b8fb7ee271c08cbe134e0e940379fb - languageName: node - linkType: hard - -"swagger-converter@npm:^0.2.0": - version: 0.2.0 - resolution: "swagger-converter@npm:0.2.0" - dependencies: - URIjs: "npm:^1.16.0" - checksum: 10c0/0b2295e2548abdeeffff95af006e4a6bd578a24ec6a231bcedfb4d99617c707fd7bb4c3474b66852caedde89394b0b7c124a735146f43bf8662f4323a0f6ccd0 - languageName: node - linkType: hard - -"swagger-editor@npm:^2.9.2": - version: 2.10.5 - resolution: "swagger-editor@npm:2.10.5" - checksum: 10c0/f172ed637222581db374bbbfdd29778de2ac8904fd88fdecb2575f3446b42073940f26246d3ccd31bcb2cd9906fa0edddae18a095eb6914cf41ff1b314f9271f - languageName: node - linkType: hard - -"swagger-test-templates@npm:^1.2.0": - version: 1.6.0 - resolution: "swagger-test-templates@npm:1.6.0" - dependencies: - handlebars: "npm:^4.0.5" - js-string-escape: "npm:^1.0.1" - json-schema-deref-sync: "npm:^0.6.0" - lodash: "npm:^4.17.12" - sanitize-filename: "npm:^1.3.0" - string: "npm:^3.3.0" - checksum: 10c0/33dce75f56bfc4d720c964b48806339a95f251af5d5fbb15c587ac6669af7bd5c64823f802b868fb0dde60df4157365b7bfca9904faa411018e29182a041a141 +"svg-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "svg-parser@npm:2.0.4" + checksum: 10c0/02f6cb155dd7b63ebc2f44f36365bc294543bebb81b614b7628f1af3c54ab64f7e1cec20f06e252bf95bdde78441ae295a412c68ad1678f16a6907d924512b7a languageName: node linkType: hard -"swagger-tools@npm:^0.9.0": - version: 0.9.16 - resolution: "swagger-tools@npm:0.9.16" +"svgo@npm:^3.0.2": + version: 3.3.2 + resolution: "svgo@npm:3.3.2" dependencies: - async: "npm:^1.3.0" - body-parser: "npm:1.12.4" - commander: "npm:^2.8.1" - debug: "npm:^2.2.0" - js-yaml: "npm:^3.3.1" - json-refs: "npm:^2.1.5" - lodash-compat: "npm:^3.10.0" - multer: "npm:^1.1.0" - parseurl: "npm:^1.3.0" - path-to-regexp: "npm:^1.2.0" - qs: "npm:^4.0.0" - serve-static: "npm:^1.10.0" - spark-md5: "npm:^1.0.0" - string: "npm:^3.3.0" - superagent: "npm:^1.2.0" - swagger-converter: "npm:^0.1.7" - traverse: "npm:^0.6.6" - z-schema: "npm:^3.15.4" - bin: - swagger-tools: ./bin/swagger-tools - checksum: 10c0/3810d37eaf3295d8949ff2574b491b83bceb9222cdcb8124d280509a4521128364ecc0a0b09756e2e1bf65737e3ade6f72d530015ebed4c4159edc06828cc413 - languageName: node - linkType: hard - -"swagger@npm:^0.7.5": - version: 0.7.5 - resolution: "swagger@npm:0.7.5" - dependencies: - async: "npm:^1.2.1" - commander: "npm:^2.7.1" - connect: "npm:^3.3.5" - debug: "npm:^2.1.3" - fs-extra: "npm:^0.24.0" - inquirer: "npm:^0.10.0" - js-yaml: "npm:^3.3.0" - lodash: "npm:^3.10.0" - mocha: "npm:^2.2.1" - nodemon: "npm:^1.3.7" - serve-static: "npm:^1.9.2" - swagger-converter: "npm:^0.2.0" - swagger-editor: "npm:^2.9.2" - swagger-test-templates: "npm:^1.2.0" - swagger-tools: "npm:^0.9.0" + "@trysound/sax": "npm:0.2.0" + commander: "npm:^7.2.0" + css-select: "npm:^5.1.0" + css-tree: "npm:^2.3.1" + css-what: "npm:^6.1.0" + csso: "npm:^5.0.5" + picocolors: "npm:^1.0.0" bin: - swagger: bin/swagger.js - swagger-project: bin/swagger-project.js - checksum: 10c0/c8532853520c6066a4cc6840011604f59b5dec2c3f15c65cb643a3b744f23819e6aa05e198be6fde30500e126816c6420b60ad715121d17c52be1906898a6fd9 + svgo: ./bin/svgo + checksum: 10c0/a6badbd3d1d6dbb177f872787699ab34320b990d12e20798ecae915f0008796a0f3c69164f1485c9def399e0ce0a5683eb4a8045e51a5e1c364bb13a0d9f79e1 languageName: node linkType: hard @@ -25393,39 +20925,6 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:^3.4.1": - version: 3.4.17 - resolution: "tailwindcss@npm:3.4.17" - dependencies: - "@alloc/quick-lru": "npm:^5.2.0" - arg: "npm:^5.0.2" - chokidar: "npm:^3.6.0" - didyoumean: "npm:^1.2.2" - dlv: "npm:^1.1.3" - fast-glob: "npm:^3.3.2" - glob-parent: "npm:^6.0.2" - is-glob: "npm:^4.0.3" - jiti: "npm:^1.21.6" - lilconfig: "npm:^3.1.3" - micromatch: "npm:^4.0.8" - normalize-path: "npm:^3.0.0" - object-hash: "npm:^3.0.0" - picocolors: "npm:^1.1.1" - postcss: "npm:^8.4.47" - postcss-import: "npm:^15.1.0" - postcss-js: "npm:^4.0.1" - postcss-load-config: "npm:^4.0.2" - postcss-nested: "npm:^6.2.0" - postcss-selector-parser: "npm:^6.1.2" - resolve: "npm:^1.22.8" - sucrase: "npm:^3.35.0" - bin: - tailwind: lib/cli.js - tailwindcss: lib/cli.js - checksum: 10c0/cc42c6e7fdf88a5507a0d7fea37f1b4122bec158977f8c017b2ae6828741f9e6f8cb90282c6bf2bd5951fd1220a53e0a50ca58f5c1c00eb7f5d9f8b80dc4523c - languageName: node - linkType: hard - "tamagui@npm:1.126.14": version: 1.126.14 resolution: "tamagui@npm:1.126.14" @@ -25604,15 +21103,6 @@ __metadata: languageName: node linkType: hard -"term-size@npm:^1.2.0": - version: 1.2.0 - resolution: "term-size@npm:1.2.0" - dependencies: - execa: "npm:^0.7.0" - checksum: 10c0/2fbb2668cdd3b5e63038c28355145e98789d16143fc6754462cd4a194706c7153f15c2a6f05f579ffed27bcf2f35bdf752007927457128cc9a9ce3ec20075649 - languageName: node - linkType: hard - "terser-webpack-plugin@npm:^5.3.11": version: 5.3.14 resolution: "terser-webpack-plugin@npm:5.3.14" @@ -25660,31 +21150,6 @@ __metadata: languageName: node linkType: hard -"test-web-app@workspace:sdk/tests/web-app": - version: 0.0.0-use.local - resolution: "test-web-app@workspace:sdk/tests/web-app" - dependencies: - "@emotion/react": "npm:^11.13.3" - "@emotion/styled": "npm:^11.13.0" - "@mui/material": "npm:^6.0.2" - "@selfxyz/common": "workspace:^" - "@selfxyz/qrcode": "workspace:^" - "@types/node": "npm:^20" - "@types/react": "npm:^18" - "@types/react-dom": "npm:^18" - axios: "npm:^1.7.7" - eslint: "npm:^8" - eslint-config-next: "npm:14.2.8" - next: "npm:14.2.8" - postcss: "npm:^8" - react: "npm:^18" - react-dom: "npm:^18" - tailwindcss: "npm:^3.4.1" - typescript: "npm:^5" - uuid: "npm:^11.1.0" - languageName: unknown - linkType: soft - "text-decoder@npm:^1.1.0": version: 1.2.3 resolution: "text-decoder@npm:1.2.3" @@ -25720,24 +21185,6 @@ __metadata: languageName: node linkType: hard -"thenify-all@npm:^1.0.0": - version: 1.6.0 - resolution: "thenify-all@npm:1.6.0" - dependencies: - thenify: "npm:>= 3.1.0 < 4" - checksum: 10c0/9b896a22735e8122754fe70f1d65f7ee691c1d70b1f116fda04fea103d0f9b356e3676cb789506e3909ae0486a79a476e4914b0f92472c2e093d206aed4b7d6b - languageName: node - linkType: hard - -"thenify@npm:>= 3.1.0 < 4": - version: 3.3.1 - resolution: "thenify@npm:3.3.1" - dependencies: - any-promise: "npm:^1.0.0" - checksum: 10c0/f375aeb2b05c100a456a30bc3ed07ef03a39cbdefe02e0403fb714b8c7e57eeaad1a2f5c4ecfb9ce554ce3db9c2b024eba144843cd9e344566d9fcee73b04767 - languageName: node - linkType: hard - "throat@npm:^5.0.0": version: 5.0.0 resolution: "throat@npm:5.0.0" @@ -25764,20 +21211,13 @@ __metadata: languageName: node linkType: hard -"through@npm:^2.3.6, through@npm:^2.3.8": +"through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc languageName: node linkType: hard -"timed-out@npm:^4.0.0": - version: 4.0.1 - resolution: "timed-out@npm:4.0.1" - checksum: 10c0/86f03ffce5b80c5a066e02e59e411d3fbbfcf242b19290ba76817b4180abd1b85558489586b6022b798fb1cf26fc644c0ce0efb9c271d67ec83fada4b9542a56 - languageName: node - linkType: hard - "tiny-hashes@npm:^1.0.1": version: 1.0.1 resolution: "tiny-hashes@npm:1.0.1" @@ -25785,7 +21225,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.11, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.6": +"tinyglobby@npm:^0.2.11, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.6": version: 0.2.14 resolution: "tinyglobby@npm:0.2.14" dependencies: @@ -25834,32 +21274,6 @@ __metadata: languageName: node linkType: hard -"to-iso-string@npm:0.0.2": - version: 0.0.2 - resolution: "to-iso-string@npm:0.0.2" - checksum: 10c0/bffeac1e4de0f4cbc14aed39f5dec7fbc32f5b43fb768b5e818e2675dda719dcd5744857874cd02b01c6bef9481bd2518867dc43eb23dd8822ef6c089a4fe293 - languageName: node - linkType: hard - -"to-object-path@npm:^0.3.0": - version: 0.3.0 - resolution: "to-object-path@npm:0.3.0" - dependencies: - kind-of: "npm:^3.0.2" - checksum: 10c0/731832a977614c03a770363ad2bd9e9c82f233261861724a8e612bb90c705b94b1a290a19f52958e8e179180bb9b71121ed65e245691a421467726f06d1d7fc3 - languageName: node - linkType: hard - -"to-regex-range@npm:^2.1.0": - version: 2.1.1 - resolution: "to-regex-range@npm:2.1.1" - dependencies: - is-number: "npm:^3.0.0" - repeat-string: "npm:^1.6.1" - checksum: 10c0/440d82dbfe0b2e24f36dd8a9467240406ad1499fc8b2b0f547372c22ed1d092ace2a3eb522bb09bfd9c2f39bf1ca42eb78035cf6d2b8c9f5c78da3abc96cd949 - languageName: node - linkType: hard - "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -25869,18 +21283,6 @@ __metadata: languageName: node linkType: hard -"to-regex@npm:^3.0.1, to-regex@npm:^3.0.2": - version: 3.0.2 - resolution: "to-regex@npm:3.0.2" - dependencies: - define-property: "npm:^2.0.2" - extend-shallow: "npm:^3.0.2" - regex-not: "npm:^1.0.2" - safe-regex: "npm:^1.1.0" - checksum: 10c0/99d0b8ef397b3f7abed4bac757b0f0bb9f52bfd39167eb7105b144becfaa9a03756892352d01ac6a911f0c1ceef9f81db68c46899521a3eed054082042796120 - languageName: node - linkType: hard - "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -25888,15 +21290,6 @@ __metadata: languageName: node linkType: hard -"touch@npm:^3.1.0": - version: 3.1.1 - resolution: "touch@npm:3.1.1" - bin: - nodetouch: bin/nodetouch.js - checksum: 10c0/d2e4d269a42c846a22a29065b9af0b263de58effc85a1764bb7a2e8fc4b47700e9e2fcbd7eb1f5bffbb7c73d860f93600cef282b93ddac8f0b62321cb498b36e - languageName: node - linkType: hard - "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -25904,17 +21297,6 @@ __metadata: languageName: node linkType: hard -"traverse@npm:^0.6.6, traverse@npm:~0.6.6": - version: 0.6.11 - resolution: "traverse@npm:0.6.11" - dependencies: - gopd: "npm:^1.2.0" - typedarray.prototype.slice: "npm:^1.0.5" - which-typed-array: "npm:^1.1.18" - checksum: 10c0/2b57662da3061ed2aa9977a6a3e315fc19f2cfdeb691700a88c12f4d460146abdb4d726740f47a9ca5fa84d3c50096b76ee50047d1a71c2afb168852ad264e36 - languageName: node - linkType: hard - "treeify@npm:^1.1.0": version: 1.1.0 resolution: "treeify@npm:1.1.0" @@ -25922,15 +21304,6 @@ __metadata: languageName: node linkType: hard -"truncate-utf8-bytes@npm:^1.0.0": - version: 1.0.2 - resolution: "truncate-utf8-bytes@npm:1.0.2" - dependencies: - utf8-byte-length: "npm:^1.0.1" - checksum: 10c0/af2b431fc4314f119b551e5fccfad49d4c0ef82e13ba9ca61be6567801195b08e732ce9643542e8ad1b3df44f3df2d7345b3dd34f723954b6bb43a14584d6b3c - languageName: node - linkType: hard - "tryer@npm:^1.0.1": version: 1.0.1 resolution: "tryer@npm:1.0.1" @@ -25938,7 +21311,7 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": +"ts-api-utils@npm:^1.3.0": version: 1.4.3 resolution: "ts-api-utils@npm:1.4.3" peerDependencies: @@ -25979,13 +21352,6 @@ __metadata: languageName: node linkType: hard -"ts-interface-checker@npm:^0.1.9": - version: 0.1.13 - resolution: "ts-interface-checker@npm:0.1.13" - checksum: 10c0/232509f1b84192d07b81d1e9b9677088e590ac1303436da1e92b296e9be8e31ea042e3e1fd3d29b1742ad2c959e95afe30f63117b8f1bc3a3850070a5142fea7 - languageName: node - linkType: hard - "ts-loader@npm:^9.5.1": version: 9.5.2 resolution: "ts-loader@npm:9.5.2" @@ -26075,7 +21441,7 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^3.15.0, tsconfig-paths@npm:^3.5.0": +"tsconfig-paths@npm:^3.5.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0" dependencies: @@ -26229,23 +21595,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^4.20.0": - version: 4.41.0 - resolution: "type-fest@npm:4.41.0" - checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4 - languageName: node - linkType: hard - -"type-is@npm:^1.6.4, type-is@npm:~1.6.2": - version: 1.6.18 - resolution: "type-is@npm:1.6.18" - dependencies: - media-typer: "npm:0.3.0" - mime-types: "npm:~2.1.24" - checksum: 10c0/a23daeb538591b7efbd61ecf06b6feb2501b683ffdc9a19c74ef5baba362b4347e42f1b4ed81f5882a8c96a3bfff7f93ce3ffaf0cbbc879b532b04c97a55db9d - languageName: node - linkType: hard - "typechain@npm:^8.3.2": version: 8.3.2 resolution: "typechain@npm:8.3.2" @@ -26321,22 +21670,6 @@ __metadata: languageName: node linkType: hard -"typedarray.prototype.slice@npm:^1.0.5": - version: 1.0.5 - resolution: "typedarray.prototype.slice@npm:1.0.5" - dependencies: - call-bind: "npm:^1.0.8" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.9" - es-errors: "npm:^1.3.0" - get-proto: "npm:^1.0.1" - math-intrinsics: "npm:^1.1.0" - typed-array-buffer: "npm:^1.0.3" - typed-array-byte-offset: "npm:^1.0.4" - checksum: 10c0/4995828640f8079cfbc9e3b4b8fc2e0eeb109edd1a2596806325ae07306dba1cd947e6ed6f63391aa7d5af0ea4f40fddf1b6eb863f8a59869a9dfc5dcfd8eac2 - languageName: node - linkType: hard - "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -26366,7 +21699,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5, typescript@npm:^5.1.6, typescript@npm:^5.3.3, typescript@npm:^5.4.5, typescript@npm:^5.8.3": +"typescript@npm:^5.1.6, typescript@npm:^5.3.3, typescript@npm:^5.4.5, typescript@npm:^5.8.3": version: 5.8.3 resolution: "typescript@npm:5.8.3" bin: @@ -26386,7 +21719,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5#optional!builtin, typescript@patch:typescript@npm%3A^5.1.6#optional!builtin, typescript@patch:typescript@npm%3A^5.3.3#optional!builtin, typescript@patch:typescript@npm%3A^5.4.5#optional!builtin, typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": +"typescript@patch:typescript@npm%3A^5.1.6#optional!builtin, typescript@patch:typescript@npm%3A^5.3.3#optional!builtin, typescript@patch:typescript@npm%3A^5.4.5#optional!builtin, typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": version: 5.8.3 resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" bin: @@ -26441,13 +21774,6 @@ __metadata: languageName: node linkType: hard -"undefsafe@npm:^2.0.2": - version: 2.0.5 - resolution: "undefsafe@npm:2.0.5" - checksum: 10c0/96c0466a5fbf395917974a921d5d4eee67bca4b30d3a31ce7e621e0228c479cf893e783a109af6e14329b52fe2f0cb4108665fad2b87b0018c0df6ac771261d5 - languageName: node - linkType: hard - "underscore@npm:1.12.1": version: 1.12.1 resolution: "underscore@npm:1.12.1" @@ -26509,18 +21835,6 @@ __metadata: languageName: node linkType: hard -"union-value@npm:^1.0.0": - version: 1.0.1 - resolution: "union-value@npm:1.0.1" - dependencies: - arr-union: "npm:^3.1.0" - get-value: "npm:^2.0.6" - is-extendable: "npm:^0.1.1" - set-value: "npm:^2.0.1" - checksum: 10c0/8758d880cb9545f62ce9cfb9b791b2b7a206e0ff5cc4b9d7cd6581da2c6839837fbb45e639cf1fd8eef3cae08c0201b614b7c06dd9f5f70d9dbe7c5fe2fbf592 - languageName: node - linkType: hard - "unique-filename@npm:^4.0.0": version: 4.0.0 resolution: "unique-filename@npm:4.0.0" @@ -26539,15 +21853,6 @@ __metadata: languageName: node linkType: hard -"unique-string@npm:^1.0.0": - version: 1.0.0 - resolution: "unique-string@npm:1.0.0" - dependencies: - crypto-random-string: "npm:^1.0.0" - checksum: 10c0/79cc2a6515a51e6350c74f65c92246511966c47528f1119318cbe8d68a508842f4e5a2a81857a65f3919629397a525f820505116dd89cac425294598e35ca12c - languageName: node - linkType: hard - "universalify@npm:^0.1.0": version: 0.1.2 resolution: "universalify@npm:0.1.2" @@ -26569,91 +21874,6 @@ __metadata: languageName: node linkType: hard -"unrs-resolver@npm:^1.6.2": - version: 1.7.5 - resolution: "unrs-resolver@npm:1.7.5" - dependencies: - "@unrs/resolver-binding-darwin-arm64": "npm:1.7.5" - "@unrs/resolver-binding-darwin-x64": "npm:1.7.5" - "@unrs/resolver-binding-freebsd-x64": "npm:1.7.5" - "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.7.5" - "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.7.5" - "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.7.5" - "@unrs/resolver-binding-linux-arm64-musl": "npm:1.7.5" - "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.7.5" - "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.7.5" - "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.7.5" - "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.7.5" - "@unrs/resolver-binding-linux-x64-gnu": "npm:1.7.5" - "@unrs/resolver-binding-linux-x64-musl": "npm:1.7.5" - "@unrs/resolver-binding-wasm32-wasi": "npm:1.7.5" - "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.7.5" - "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.7.5" - "@unrs/resolver-binding-win32-x64-msvc": "npm:1.7.5" - napi-postinstall: "npm:^0.2.2" - dependenciesMeta: - "@unrs/resolver-binding-darwin-arm64": - optional: true - "@unrs/resolver-binding-darwin-x64": - optional: true - "@unrs/resolver-binding-freebsd-x64": - optional: true - "@unrs/resolver-binding-linux-arm-gnueabihf": - optional: true - "@unrs/resolver-binding-linux-arm-musleabihf": - optional: true - "@unrs/resolver-binding-linux-arm64-gnu": - optional: true - "@unrs/resolver-binding-linux-arm64-musl": - optional: true - "@unrs/resolver-binding-linux-ppc64-gnu": - optional: true - "@unrs/resolver-binding-linux-riscv64-gnu": - optional: true - "@unrs/resolver-binding-linux-riscv64-musl": - optional: true - "@unrs/resolver-binding-linux-s390x-gnu": - optional: true - "@unrs/resolver-binding-linux-x64-gnu": - optional: true - "@unrs/resolver-binding-linux-x64-musl": - optional: true - "@unrs/resolver-binding-wasm32-wasi": - optional: true - "@unrs/resolver-binding-win32-arm64-msvc": - optional: true - "@unrs/resolver-binding-win32-ia32-msvc": - optional: true - "@unrs/resolver-binding-win32-x64-msvc": - optional: true - checksum: 10c0/b71bc6fadb0f513b8db6e7166a6d0dd3e133b5091a1ef71eaf36878e116b0a7710de16a4e4c17a0f7a93395909177af445fddab711f5d26230acec76d1055677 - languageName: node - linkType: hard - -"unset-value@npm:^1.0.0": - version: 1.0.0 - resolution: "unset-value@npm:1.0.0" - dependencies: - has-value: "npm:^0.3.1" - isobject: "npm:^3.0.0" - checksum: 10c0/68a796dde4a373afdbf017de64f08490a3573ebee549136da0b3a2245299e7f65f647ef70dc13c4ac7f47b12fba4de1646fa0967a365638578fedce02b9c0b1f - languageName: node - linkType: hard - -"unzip-response@npm:^2.0.1": - version: 2.0.1 - resolution: "unzip-response@npm:2.0.1" - checksum: 10c0/8df383f28e87bcc1e0810343c435a524d62063841ace6cb507edeade4d74e78be76d32a84e35e7fa270a1b697ba86fd3e3c153224228a6db88e728576fa7e4f3 - languageName: node - linkType: hard - -"upath@npm:^1.1.1": - version: 1.2.0 - resolution: "upath@npm:1.2.0" - checksum: 10c0/3746f24099bf69dbf8234cecb671e1016e1f6b26bd306de4ff8966fb0bc463fa1014ffc48646b375de1ab573660e3a0256f6f2a87218b2dfa1779a84ef6992fa - languageName: node - linkType: hard - "update-browserslist-db@npm:^1.1.3": version: 1.1.3 resolution: "update-browserslist-db@npm:1.1.3" @@ -26668,33 +21888,6 @@ __metadata: languageName: node linkType: hard -"update-notifier@npm:^2.5.0": - version: 2.5.0 - resolution: "update-notifier@npm:2.5.0" - dependencies: - boxen: "npm:^1.2.1" - chalk: "npm:^2.0.1" - configstore: "npm:^3.0.0" - import-lazy: "npm:^2.1.0" - is-ci: "npm:^1.0.10" - is-installed-globally: "npm:^0.1.0" - is-npm: "npm:^1.0.0" - latest-version: "npm:^3.0.0" - semver-diff: "npm:^2.0.0" - xdg-basedir: "npm:^3.0.0" - checksum: 10c0/f6b82e655f115b67e829a9f10fe75d2c3afae84a51941478791bfa49023e2c35386790deb8f53d7149fa7e323d6cec1ab9580d92c84e99c7aca3f00e1cfe5efe - languageName: node - linkType: hard - -"uri-js@npm:^3.0.2": - version: 3.0.2 - resolution: "uri-js@npm:3.0.2" - dependencies: - punycode: "npm:^2.1.0" - checksum: 10c0/8c24d7f2b1821f76f9f4f838f6afa406eef277ef86b93a4e20b8570cd5685f16862fa9c4b2f7db0e787fb172b90c1c1da313da8064ac3e93167b0ff81f91ac80 - languageName: node - linkType: hard - "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -26704,22 +21897,6 @@ __metadata: languageName: node linkType: hard -"urix@npm:^0.1.0": - version: 0.1.0 - resolution: "urix@npm:0.1.0" - checksum: 10c0/264f1b29360c33c0aec5fb9819d7e28f15d1a3b83175d2bcc9131efe8583f459f07364957ae3527f1478659ec5b2d0f1ad401dfb625f73e4d424b3ae35fc5fc0 - languageName: node - linkType: hard - -"url-parse-lax@npm:^1.0.0": - version: 1.0.0 - resolution: "url-parse-lax@npm:1.0.0" - dependencies: - prepend-http: "npm:^1.0.1" - checksum: 10c0/7578d90d18297c0896ab3c98350b61b59be56211baad543ea55eb570dfbd403b0987e499a817abb55d755df6f47ec2e748a49bd09f8d39766066a6871853cea1 - languageName: node - linkType: hard - "urlpattern-polyfill@npm:10.0.0": version: 10.0.0 resolution: "urlpattern-polyfill@npm:10.0.0" @@ -26788,20 +21965,6 @@ __metadata: languageName: node linkType: hard -"use@npm:^3.1.0": - version: 3.1.1 - resolution: "use@npm:3.1.1" - checksum: 10c0/75b48673ab80d5139c76922630d5a8a44e72ed58dbaf54dee1b88352d10e1c1c1fc332066c782d8ae9a56503b85d3dc67ff6d2ffbd9821120466d1280ebb6d6e - languageName: node - linkType: hard - -"utf8-byte-length@npm:^1.0.1": - version: 1.0.5 - resolution: "utf8-byte-length@npm:1.0.5" - checksum: 10c0/e69bda3299608f4cc75976da9fb74ac94801a58b9ca29fdad03a20ec952e7477d7f226c12716b5f36bd4cff8151d1d152d02ee1df3752f017d4b2c725ce3e47a - languageName: node - linkType: hard - "utf8@npm:3.0.0": version: 3.0.0 resolution: "utf8@npm:3.0.0" @@ -26809,7 +21972,7 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": +"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 @@ -26899,20 +22062,6 @@ __metadata: languageName: node linkType: hard -"valid-url@npm:~1.0.9": - version: 1.0.9 - resolution: "valid-url@npm:1.0.9" - checksum: 10c0/3995e65f9942dbcb1621754c0f9790335cec61e9e9310c0a809e9ae0e2ae91bb7fc6a471fba788e979db0418d9806639f681ecebacc869bc8c3de88efa562ee6 - languageName: node - linkType: hard - -"validator@npm:^10.0.0": - version: 10.11.0 - resolution: "validator@npm:10.11.0" - checksum: 10c0/3e32a0a00b28012369c44aef1437b21a095640e0576580f97310d214f7eb0fb8c465099a1d8493d2d4117d9d342a43ae176cf184917f83e95a8eb4449652b4e1 - languageName: node - linkType: hard - "validator@npm:^13.6.0": version: 13.15.15 resolution: "validator@npm:13.15.15" @@ -26927,27 +22076,6 @@ __metadata: languageName: node linkType: hard -"viem@npm:^2.22.23": - version: 2.30.4 - resolution: "viem@npm:2.30.4" - dependencies: - "@noble/curves": "npm:1.9.1" - "@noble/hashes": "npm:1.8.0" - "@scure/bip32": "npm:1.7.0" - "@scure/bip39": "npm:1.6.0" - abitype: "npm:1.0.8" - isows: "npm:1.0.7" - ox: "npm:0.7.1" - ws: "npm:8.18.2" - peerDependencies: - typescript: ">=5.0.4" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/fae6b5106ede843f6d2227e6135746379059c2b90b92a286e732555b4670f3c10caa82f4cb527184f15b7499547891cd45ac17aac2761a9158f9df0c3b9b1f27 - languageName: node - linkType: hard - "vlq@npm:^1.0.0": version: 1.0.1 resolution: "vlq@npm:1.0.1" @@ -27185,7 +22313,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: @@ -27200,7 +22328,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^1.1.1, which@npm:^1.2.9, which@npm:^1.3.1": +"which@npm:^1.1.1, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -27233,15 +22361,6 @@ __metadata: languageName: node linkType: hard -"widest-line@npm:^2.0.0": - version: 2.0.1 - resolution: "widest-line@npm:2.0.1" - dependencies: - string-width: "npm:^2.1.1" - checksum: 10c0/c8c908c737b522a8cf46254bc85b3b0c9e6934a054840d9b01ea7f36442aa11c8393579fa57bc9ef9a5c5ea69f49e78783ce27b8a8ebab4f855ca044efa584fa - languageName: node - linkType: hard - "widest-line@npm:^3.1.0": version: 3.1.0 resolution: "widest-line@npm:3.1.0" @@ -27322,7 +22441,7 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^2.0.0, write-file-atomic@npm:^2.3.0": +"write-file-atomic@npm:^2.3.0": version: 2.4.3 resolution: "write-file-atomic@npm:2.4.3" dependencies: @@ -27388,21 +22507,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.2": - version: 8.18.2 - resolution: "ws@npm:8.18.2" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10c0/4b50f67931b8c6943c893f59c524f0e4905bbd183016cfb0f2b8653aa7f28dad4e456b9d99d285bbb67cca4fedd9ce90dfdfaa82b898a11414ebd66ee99141e4 - languageName: node - linkType: hard - "ws@npm:^6.2.2, ws@npm:^6.2.3": version: 6.2.3 resolution: "ws@npm:6.2.3" @@ -27427,13 +22531,6 @@ __metadata: languageName: node linkType: hard -"xdg-basedir@npm:^3.0.0": - version: 3.0.0 - resolution: "xdg-basedir@npm:3.0.0" - checksum: 10c0/c3be36400d8a69c9154ce6ccff98832dae0d04f8bacda806f609d3955beb23dc7c9dde724438b81e6128bf253d440a2bfe0239dd37d70333ab625c4e170b77b2 - languageName: node - linkType: hard - "xmlhttprequest-ssl@npm:~2.1.1": version: 2.1.2 resolution: "xmlhttprequest-ssl@npm:2.1.2" @@ -27448,7 +22545,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0, xtend@npm:~4.0.1": +"xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e @@ -27469,13 +22566,6 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^2.1.2": - version: 2.1.2 - resolution: "yallist@npm:2.1.2" - checksum: 10c0/0b9e25aa00adf19e01d2bcd4b208aee2b0db643d9927131797b7af5ff69480fc80f1c3db738cbf3946f0bddf39d8f2d0a5709c644fd42d4aa3a4e6e786c087b5 - languageName: node - linkType: hard - "yallist@npm:^3.0.2": version: 3.1.1 resolution: "yallist@npm:3.1.1" @@ -27497,14 +22587,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.10.0": - version: 1.10.2 - resolution: "yaml@npm:1.10.2" - checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f - languageName: node - linkType: hard - -"yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.4": +"yaml@npm:^2.2.1, yaml@npm:^2.2.2": version: 2.8.0 resolution: "yaml@npm:2.8.0" bin: @@ -27629,31 +22712,6 @@ __metadata: languageName: node linkType: hard -"z-schema@npm:^3.15.4": - version: 3.25.1 - resolution: "z-schema@npm:3.25.1" - dependencies: - commander: "npm:^2.7.1" - core-js: "npm:^2.5.7" - lodash.get: "npm:^4.0.0" - lodash.isequal: "npm:^4.0.0" - validator: "npm:^10.0.0" - dependenciesMeta: - commander: - optional: true - bin: - z-schema: ./bin/z-schema - checksum: 10c0/df6c0f211a4a85d0ce35b717e05bc636ad6368ed492a7567efabaa47b1d25d967cb19cf55e88ae6af3787517aafe6a8da85d076419680b530f5aa9b58c7a1a62 - languageName: node - linkType: hard - -"zhead@npm:^2.2.4": - version: 2.2.4 - resolution: "zhead@npm:2.2.4" - checksum: 10c0/3d166fb661f1b7fdf8a0ef2222d9e574ab241e72141f2f1fda62a9250ca73aabf2eaf0d66046a3984cd24d1dd9bac231338c6271684d6b8caa6b66af7c45f275 - languageName: node - linkType: hard - "zod@npm:3.22.4": version: 3.22.4 resolution: "zod@npm:3.22.4" @@ -27661,13 +22719,6 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.23.8": - version: 3.25.32 - resolution: "zod@npm:3.25.32" - checksum: 10c0/de0bc052a7666578b3d5dd42bc522f02f27e1c798236439c0f6b6bc1b311a221706aebdafb1f58399d5f558b1fab7860c6970e096fe8d6947743bc791d567c4b - languageName: node - linkType: hard - "zustand@npm:^4.5.2": version: 4.5.7 resolution: "zustand@npm:4.5.7"